packages feed

freetype2 (empty) → 0.0.1

raw patch · 378 files changed

+153254/−0 lines, 378 filesdep +arraydep +basedep +freetype2setup-changed

Dependencies added: array, base, freetype2, missing-foreign

Files

+ Graphics/Rendering/FreeType/Internal.hsc view
@@ -0,0 +1,60 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module Graphics.Rendering.FreeType.Internal where++import Foreign+import Foreign.C.String++import Graphics.Rendering.FreeType.Internal.PrimitiveTypes+import Graphics.Rendering.FreeType.Internal.Library+import Graphics.Rendering.FreeType.Internal.Face+import Graphics.Rendering.FreeType.Internal.Matrix+import Graphics.Rendering.FreeType.Internal.Vector+import Graphics.Rendering.FreeType.Internal.Glyph+import Graphics.Rendering.FreeType.Internal.GlyphSlot++#include "ft2build.h"+#include FT_FREETYPE_H++foreign import ccall "FT_Init_FreeType"+  ft_Init_FreeType :: Ptr FT_Library -> IO FT_Error++foreign import ccall "FT_New_Face"+  ft_New_Face :: FT_Library  -> CString -> FT_Long+              -> Ptr FT_Face -> IO FT_Error++foreign import ccall "FT_Set_Char_Size"+  ft_Set_Char_Size :: FT_Face -> FT_F26Dot6 -> FT_F26Dot6+                   -> FT_UInt -> FT_UInt    -> IO FT_Error++foreign import ccall "FT_Set_Pixel_Sizes"+  ft_Set_Pixel_Sizes :: FT_Face -> FT_UInt -> FT_UInt+                     -> IO FT_Error++foreign import ccall "FT_Get_Char_Index"+  ft_Get_Char_Index :: FT_Face -> FT_ULong -> IO FT_UInt++foreign import ccall "FT_Set_Transform"+  ft_Set_Transform :: FT_Face -> Ptr FT_Matrix+                   -> Ptr FT_Vector -> IO ()++foreign import ccall "FT_Load_Char"+  ft_Load_Char :: FT_Face -> FT_ULong -> FT_Int32 -> IO FT_Error++foreign import ccall "FT_Done_Face"+  ft_Done_Face :: FT_Face -> IO FT_Error++foreign import ccall "FT_Done_FreeType"+  ft_Done_FreeType :: FT_Library -> IO FT_Error++foreign import ccall "FT_Load_Glyph"+  ft_Load_Glyph :: FT_Face -> FT_UInt -> FT_Int32 -> IO FT_Error++foreign import ccall "FT_Get_Glyph"+  ft_Get_Glyph :: FT_GlyphSlot -> Ptr FT_Glyph -> IO FT_Error++foreign import ccall "FT_Done_Glyph"+  ft_Done_Glyph :: FT_Glyph -> IO ()++foreign import ccall "FT_Glyph_To_Bitmap"+  ft_Glyph_To_Bitmap :: Ptr FT_Glyph  -> FT_Render_Mode+                     -> Ptr FT_Vector -> FT_Bool -> IO FT_Error
+ Graphics/Rendering/FreeType/Internal/Bitmap.hsc view
@@ -0,0 +1,56 @@+{-# LANGUAGE ForeignFunctionInterface #-}
+module Graphics.Rendering.FreeType.Internal.Bitmap
+( FT_Bitmap(..)
+) where
+
+import Foreign
+import Foreign.C.Types
+import Foreign.Storable
+
+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+data FT_Bitmap = FT_Bitmap
+  { rows         :: CInt
+  , width        :: CInt
+  , pitch        :: CInt
+  , buffer       :: Ptr CChar
+  , num_grays    :: CShort
+  , pixel_mode   :: CChar
+  , palette_mode :: CChar
+  , palette      :: Ptr ()
+  }
+
+instance Storable FT_Bitmap where
+  sizeOf _    = #size FT_Bitmap
+  alignment _ = #alignment FT_Bitmap
+  peek ptr = do
+    rows'         <- (#peek FT_Bitmap, rows) ptr
+    width'        <- (#peek FT_Bitmap, width) ptr
+    pitch'        <- (#peek FT_Bitmap, pitch) ptr
+    buffer'       <- (#peek FT_Bitmap, buffer) ptr
+    num_grays'    <- (#peek FT_Bitmap, num_grays) ptr
+    pixel_mode'   <- (#peek FT_Bitmap, pixel_mode) ptr
+    palette_mode' <- (#peek FT_Bitmap, palette_mode) ptr
+    palette'      <- (#peek FT_Bitmap, palette) ptr
+    return $ FT_Bitmap
+      { rows = rows'
+      , width = width'
+      , pitch = pitch'
+      , buffer = buffer'
+      , num_grays = num_grays'
+      , pixel_mode = pixel_mode'
+      , palette_mode = palette_mode'
+      , palette = palette'
+      }
+  poke ptr val = do
+    (#poke FT_Bitmap, rows) ptr (rows val)
+    (#poke FT_Bitmap, width) ptr (width val)
+    (#poke FT_Bitmap, pitch) ptr (pitch val)
+    (#poke FT_Bitmap, buffer) ptr (buffer val)
+    (#poke FT_Bitmap, num_grays) ptr (num_grays val)
+    (#poke FT_Bitmap, pixel_mode) ptr (pixel_mode val)
+    (#poke FT_Bitmap, palette_mode) ptr (palette_mode val)
+    (#poke FT_Bitmap, palette) ptr (palette val)
+ Graphics/Rendering/FreeType/Internal/Face.hsc view
@@ -0,0 +1,45 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+module Graphics.Rendering.FreeType.Internal.Face+( FT_FaceRec_+, FT_Face+, num_faces+, num_glyphs+, glyph+, underline_thickness+) where++import Foreign+import Foreign.Storable++import Graphics.Rendering.FreeType.Internal.PrimitiveTypes+import qualified Graphics.Rendering.FreeType.Internal.GlyphSlot as GS++#include <stddef.h>+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)++#include "ft2build.h"+#include FT_FREETYPE_H++#include "internal/ftobjs.h"++data FT_FaceRec_+type FT_Face = Ptr FT_FaceRec_++instance Storable FT_FaceRec_ where+  sizeOf _    = #size struct FT_FaceRec_+  alignment _ = #alignment struct FT_FaceRec_+  peek = error "peek not implemented for FT_FaceRec_"+  poke = error "poke not implemented for FT_FaceRec_"++num_faces :: FT_Face -> Ptr FT_Long+num_faces = #ptr struct FT_FaceRec_, num_faces++num_glyphs :: FT_Face -> Ptr FT_Long+num_glyphs = #ptr struct FT_FaceRec_, num_glyphs++glyph :: FT_Face -> Ptr GS.FT_GlyphSlot+glyph = #ptr struct FT_FaceRec_, glyph++underline_thickness :: FT_Face -> Ptr FT_Short+underline_thickness = #ptr struct FT_FaceRec_, underline_thickness+
+ Graphics/Rendering/FreeType/Internal/Glyph.hsc view
@@ -0,0 +1,44 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+module Graphics.Rendering.FreeType.Internal.Glyph
+( FT_GlyphRec_
+, FT_Glyph
+, library
+, advance
+) where
+
+import Foreign
+import Foreign.Storable
+
+-- import Graphics.Rendering.FreeType.Internal.PrimitiveTypes
+import qualified Graphics.Rendering.FreeType.Internal.Library as Lib
+import qualified Graphics.Rendering.FreeType.Internal.Vector  as V
+
+#include <stddef.h>
+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+#include "freetype/ftglyph.h"
+
+data FT_GlyphRec_
+type FT_Glyph = Ptr FT_GlyphRec_
+
+instance Storable FT_GlyphRec_ where
+  sizeOf    _  = #size struct FT_GlyphRec_
+  alignment _  = #alignment struct FT_GlyphRec_
+  peek = error "peek not implemented for FT_GlyphRec_"
+  poke = error "peek not implemented for FT_GlyphRec_"
+
+library :: FT_Glyph -> Ptr Lib.FT_Library
+library = #ptr struct FT_GlyphRec_, library
+
+{- TODO: implement FT_Glyph_Format
+format :: FT_Glyph -> Ptr FT_Glyph_Format
+format = #ptr struct FT_GlyphRec_, format
+-}
+
+advance :: FT_Glyph -> Ptr V.FT_Vector
+advance = #ptr struct FT_GlyphRec_, advance
+
+
+ Graphics/Rendering/FreeType/Internal/GlyphSlot.hsc view
@@ -0,0 +1,50 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+module Graphics.Rendering.FreeType.Internal.GlyphSlot
+( FT_GlyphSlotRec_
+, FT_GlyphSlot
+, library
+, advance
+, bitmap
+, bitmap_top
+, bitmap_left
+) where
+
+import Foreign
+import Foreign.Storable
+
+import Graphics.Rendering.FreeType.Internal.PrimitiveTypes
+import qualified Graphics.Rendering.FreeType.Internal.Library as Lib
+import qualified Graphics.Rendering.FreeType.Internal.Vector  as V
+import qualified Graphics.Rendering.FreeType.Internal.Bitmap as B
+
+#include <stddef.h>
+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+#include "internal/ftobjs.h"
+
+data FT_GlyphSlotRec_
+type FT_GlyphSlot = Ptr FT_GlyphSlotRec_
+
+instance Storable FT_GlyphSlotRec_ where
+  sizeOf _    = #size struct FT_GlyphSlotRec_
+  alignment _ = #alignment struct FT_GlyphSlotRec_
+  peek = error "peek not implemented for FT_GlyphSlotRec_"
+  poke = error "poke not implemented for FT_GlyphSlotRec_"
+
+library :: FT_GlyphSlot -> Lib.FT_Library
+library = (#ptr struct FT_GlyphSlotRec_, library)
+
+advance :: FT_GlyphSlot -> Ptr V.FT_Vector
+advance = (#ptr struct FT_GlyphSlotRec_, advance)
+
+bitmap :: FT_GlyphSlot -> Ptr B.FT_Bitmap
+bitmap = (#ptr struct FT_GlyphSlotRec_, bitmap)
+
+bitmap_left :: FT_GlyphSlot -> Ptr FT_Int
+bitmap_left = (#ptr struct FT_GlyphSlotRec_, bitmap_left)
+
+bitmap_top :: FT_GlyphSlot -> Ptr FT_Int
+bitmap_top = (#ptr struct FT_GlyphSlotRec_, bitmap_top)
+ Graphics/Rendering/FreeType/Internal/Library.hsc view
@@ -0,0 +1,26 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+module Graphics.Rendering.FreeType.Internal.Library
+( FT_LibraryRec_
+, FT_Library
+) where
+
+import Foreign
+import Foreign.Storable
+
+#include <stddef.h>
+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+#include "internal/ftobjs.h"
+
+data FT_LibraryRec_
+type FT_Library = Ptr FT_LibraryRec_
+
+instance Storable FT_LibraryRec_ where
+  sizeOf _    = #size struct FT_LibraryRec_
+  alignment _ = #alignment struct FT_LibraryRec_
+  peek = error "peek not implemented for FT_LibraryRec_"
+  poke = error "poke not implemented for FT_LibraryRec_"
+
+ Graphics/Rendering/FreeType/Internal/Matrix.hsc view
@@ -0,0 +1,35 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+module Graphics.Rendering.FreeType.Internal.Matrix
+( FT_Matrix(..)
+) where
+
+import Foreign
+import Foreign.Storable
+
+import Graphics.Rendering.FreeType.Internal.PrimitiveTypes
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+#include "internal/ftobjs.h"
+
+data FT_Matrix = FT_Matrix
+  { xx, xy :: FT_Fixed
+  , yx, yy :: FT_Fixed
+  }
+  deriving (Read, Show, Eq)
+
+instance Storable FT_Matrix where
+  sizeOf _    = #size FT_Matrix
+  alignment _ = alignment (undefined :: FT_Fixed)
+  peek ptr = do
+    xx' <- (#peek FT_Matrix, xx) ptr
+    xy' <- (#peek FT_Matrix, xy) ptr
+    yx' <- (#peek FT_Matrix, yx) ptr
+    yy' <- (#peek FT_Matrix, yy) ptr
+    return $! FT_Matrix xx' xy' yx' yy'
+  poke ptr val = do
+    (#poke FT_Matrix, xx) ptr (xx val)
+    (#poke FT_Matrix, xy) ptr (xy val)
+    (#poke FT_Matrix, yx) ptr (yx val)
+    (#poke FT_Matrix, yy) ptr (yy val)
+ Graphics/Rendering/FreeType/Internal/PrimitiveTypes.hsc view
@@ -0,0 +1,72 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}+module Graphics.Rendering.FreeType.Internal.PrimitiveTypes where++import Foreign+import Foreign.C.Types++#include <stddef.h>++#include "ft2build.h"+#include FT_FREETYPE_H++ft_LOAD_DEFAULT :: FT_Int32+ft_LOAD_DEFAULT = #const FT_LOAD_DEFAULT+ft_LOAD_NO_SCALE :: FT_Int32+ft_LOAD_NO_SCALE = #const FT_LOAD_NO_SCALE+ft_LOAD_NO_HINTING :: FT_Int32+ft_LOAD_NO_HINTING = #const FT_LOAD_NO_HINTING+ft_LOAD_RENDER :: FT_Int32+ft_LOAD_RENDER = #const FT_LOAD_RENDER+ft_LOAD_NO_BITMAP :: FT_Int32+ft_LOAD_NO_BITMAP = #const FT_LOAD_NO_BITMAP+ft_LOAD_VERTICAL_LAYOUT :: FT_Int32+ft_LOAD_VERTICAL_LAYOUT = #const FT_LOAD_VERTICAL_LAYOUT+ft_LOAD_FORCE_AUTOHINT :: FT_Int32+ft_LOAD_FORCE_AUTOHINT = #const FT_LOAD_FORCE_AUTOHINT+ft_LOAD_CROP_BITMAP :: FT_Int32+ft_LOAD_CROP_BITMAP = #const FT_LOAD_CROP_BITMAP+ft_LOAD_PEDANTIC :: FT_Int32+ft_LOAD_PEDANTIC = #const FT_LOAD_PEDANTIC+ft_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: FT_Int32+ft_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH+  = #const FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH+ft_LOAD_NO_RECURSE :: FT_Int32+ft_LOAD_NO_RECURSE = #const FT_LOAD_NO_RECURSE+ft_LOAD_IGNORE_TRANSFORM :: FT_Int32+ft_LOAD_IGNORE_TRANSFORM = #const FT_LOAD_IGNORE_TRANSFORM+ft_LOAD_MONOCHROME :: FT_Int32+ft_LOAD_MONOCHROME = #const FT_LOAD_MONOCHROME+ft_LOAD_LINEAR_DESIGN :: FT_Int32+ft_LOAD_LINEAR_DESIGN = #const FT_LOAD_LINEAR_DESIGN+ft_LOAD_NO_AUTOHINT :: FT_Int32+ft_LOAD_NO_AUTOHINT = #const FT_LOAD_NO_AUTOHINT++type FT_Byte    = CUChar+type FT_Bytes   = Ptr FT_Byte+type FT_Char    = CChar+type FT_Int     = CInt+type FT_UInt    = CUInt+type FT_Int16   = CShort+type FT_UInt16  = CUShort+type FT_Int32   = Int32+type FT_UInt32  = Word32+type FT_Short   = CShort+type FT_UShort  = CUShort+type FT_Long    = CLong+type FT_ULong   = CULong+type FT_Bool    = CUChar+type FT_Offset  = #type size_t+type FT_Error   = CInt+type FT_F26Dot6 = CLong+type FT_Fixed   = CLong+type FT_Pos     = CLong++newtype FT_Render_Mode = FT_Render_Mode CUInt++#{enum FT_Render_Mode, FT_Render_Mode,+  ft_RENDER_MODE_NORMAL = FT_RENDER_MODE_NORMAL,+  ft_RENDER_MODE_LIGHT  = FT_RENDER_MODE_LIGHT,+  ft_RENDER_MODE_MONO   = FT_RENDER_MODE_MONO,+  ft_RENDER_MODE_LCD    = FT_RENDER_MODE_LCD,+  ft_RENDER_MODE_LCD_V  = FT_RENDER_MODE_LCD_V+}
+ Graphics/Rendering/FreeType/Internal/Vector.hsc view
@@ -0,0 +1,28 @@+{-# LANGUAGE ForeignFunctionInterface #-}
+module Graphics.Rendering.FreeType.Internal.Vector
+( FT_Vector(..)
+) where
+
+import Foreign.Storable
+
+import Graphics.Rendering.FreeType.Internal.PrimitiveTypes
+
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+data FT_Vector = FT_Vector
+  { x :: FT_Pos
+  , y :: FT_Pos
+  }
+  deriving (Read, Show, Eq)
+
+instance Storable FT_Vector where
+  sizeOf _    = #size FT_Vector
+  alignment _ = alignment (undefined :: FT_Pos)
+  peek ptr = do
+    x' <- (#peek FT_Vector, x) ptr
+    y' <- (#peek FT_Vector, y) ptr
+    return $! FT_Vector x' y'
+  poke ptr val = do
+    (#poke FT_Vector, x) ptr (x val)
+    (#poke FT_Vector, y) ptr (y val)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Jason Dagit <dagitj@gmail.com>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Jason Dagit <dagitj@gmail.com> nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Main.hs view
@@ -0,0 +1,115 @@+module Main where
+
+import Control.Monad
+import System.Environment
+import Graphics.Rendering.FreeType.Internal as FT
+import Graphics.Rendering.FreeType.Internal.Matrix as M
+import Graphics.Rendering.FreeType.Internal.Vector as V
+import Graphics.Rendering.FreeType.Internal.GlyphSlot as GS
+import Graphics.Rendering.FreeType.Internal.PrimitiveTypes as PT
+import Graphics.Rendering.FreeType.Internal.Face as F
+import Graphics.Rendering.FreeType.Internal.Library as L
+import Graphics.Rendering.FreeType.Internal.Bitmap as B
+
+import Foreign
+import Foreign.Marshal
+import Foreign.Marshal.MissingAlloc
+import Foreign.C.String
+
+import System.Exit
+
+import Data.Array.IO as A
+
+main :: IO ()
+main = do
+  let width  = 640
+      height = 480
+      angle  = (25 / 360) * pi * 2
+  matrix <- mallocForeignPtr
+  pen    <- mallocForeignPtr
+  withForeignPtr matrix $ \p-> poke p (FT_Matrix
+        { xx = round $   cos angle * 0x10000
+        , xy = round $ -(sin angle * 0x10000)
+        , yx = round $   sin angle * 0x10000
+        , yy = round $   cos angle * 0x10000
+        })
+  withForeignPtr pen $ \p -> poke p (FT_Vector
+        { x = 300 * 64
+        , y = (height - 200) * 64
+        })
+  (filename:text:_) <- getArgs
+
+  libraryptr <- calloc
+  library <- do
+    print $ libraryptr == nullPtr
+    ft_Init_FreeType libraryptr >>= print
+    peek libraryptr
+
+  faceptr <- calloc
+  print $ faceptr == nullPtr
+  face <- withCString filename $ \str -> do
+    print =<< ft_New_Face library str 0 faceptr
+    peek faceptr
+
+  image <- A.newArray
+    ((0,0), (fromIntegral height - 1, fromIntegral width - 1)) 0
+    :: IO (IOUArray (Int, Int) Int)
+
+  print =<< ft_Set_Char_Size face (50*64) 0 100 0
+  forM_ text $ \c -> do
+    withForeignPtr matrix $ \mp ->
+      withForeignPtr pen $ \pp -> do
+        ft_Set_Transform face mp pp
+        slot <- peek $ glyph face
+        print =<< ft_Load_Char face
+                               (fromIntegral . fromEnum $ c)
+                               ft_LOAD_RENDER
+        numFaces <- peek $ num_faces face
+        putStrLn $ "face->num_faces = " ++ show numFaces
+        v <- peek $ advance slot
+        putStrLn "advance: "
+        print v
+        numGlyphs <- peek $ num_glyphs face
+        putStrLn $ "numGlyphs = " ++ show numGlyphs
+        pen' <- peek pp
+        poke pp $ FT_Vector { x = x v + x pen'
+                            , y = y v + y pen' }
+        b <- peek $ bitmap slot
+        left <- peek $ bitmap_left slot
+        top  <- peek $ bitmap_top slot
+        drawBitmap b
+                   image
+                   left
+                   (fromIntegral height - top)
+  showImage image
+  print =<< ft_Done_Face face
+  print =<< ft_Done_FreeType library
+
+
+drawBitmap :: FT_Bitmap -> IOUArray (Int, Int) Int
+           -> FT_Int -> FT_Int -> IO ()
+drawBitmap bitmap image x y = do
+  let xMax = x + width bitmap
+      yMax = y + rows bitmap
+  forM_ (zip [ x .. xMax - 1] [0 .. ]) $ \(i,p) ->
+    forM_ (zip [ y .. yMax - 1] [0 .. ]) $ \(j,q) -> do
+      let index = q * width bitmap + p
+      v <- readArray image (fromIntegral j, fromIntegral i) :: IO Int
+      b <- peek $ (buffer bitmap) `plusPtr` fromIntegral index
+      writeArray image (fromIntegral j, fromIntegral i) $ v .|. b
+
+showImage :: IOUArray (Int, Int) Int -> IO ()
+showImage image = do
+  ((hmin,wmin), (hmax,wmax)) <- getBounds image
+  forM_ [ hmin .. hmax ] $ \i -> do
+    forM_ [ wmin .. wmax ] $ \j -> do
+      v <- readArray image (i,j)
+      putc v
+    putChar '\n'
+  where
+  putc :: Int -> IO ()
+  putc c
+    | c == 0    = putChar '0'
+    | c < 128   = putChar '+'
+    | otherwise = putChar '*'
+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ freetype2.cabal view
@@ -0,0 +1,251 @@+Name:                freetype2+Version:             0.0.1+Synopsis:            Haskell binding for FreeType 2 library+Description:         Wrapper around FreeType 2 library.  Relevant+                     exerpts from the FreeType 2 website:+                     .+                     What is FreeType 2?+                     .+                     FreeType 2 is a software font engine that is+                     designed to be small, efficient, highly+                     customizable, and portable while capable of+                     producing high-quality output (glyph images). It+                     can be used in graphics libraries, display+                     servers, font conversion tools, text image+                     generation tools, and many other products as+                     well.+                     .+                     The following is a non-exhaustive list of+                     features provided by FreeType 2.+                     .+                     * FreeType 2 provides a simple and easy-to-use+                     API to access font content in a uniform way,+                     independently of the file format. Additionally,+                     some format-specific APIs can be used to access+                     special data in the font file.+                     .+                     * Unlike most comparable libraries, FreeType 2+                     supports scalable font formats like TrueType or+                     Type 1 natively and can return the outline data+                     (and control instructions/hints) to client+                     applications.+                     .+                     By default, FreeType 2 supports the following+                     font formats.+                     .+                     * TrueType fonts (and collections)+                     .+                     * Type 1 fonts+                     .+                     * CID-keyed Type 1 fonts+                     .+                     * CFF fonts+                     .+                     * OpenType fonts (both TrueType and CFF variants)+                     .+                     * SFNT-based bitmap fonts+                     .+                     * X11 PCF fonts+                     .+                     * Windows FNT fonts+                     .+                     * BDF fonts (including anti-aliased ones)+                     .+                     * PFR fonts+                     .+                     * Type 42 fonts (limited support)+                     .+                     From a given glyph outline, FreeType 2 is capable+                     of producing a high-quality monochrome bitmap, or+                     anti-aliased pixmap, using 256 levels of+                     'gray'. This is much better than the 5 levels+                     used by Windows 9x\/98\/NT\/2000 or FreeType 1.+                     .+                     FreeType 2 supports all the character mappings+                     defined by the TrueType and OpenType+                     specification. It is also capable of+                     automatically synthetizing a Unicode charmap from+                     Type 1 fonts, which puts an end to the painful+                     'encoding translation' headache common with this+                     format (of course, original encodings are also+                     available in the case where you need them).+                     .+                     The FreeType 2 core API provides simple functions+                     to access advanced information like glyph names+                     or kerning data.+                     .+                     FreeType 2 provides information that is often not+                     available from other similar font engines, like+                     kerning distances, glyph names, vertical metrics,+                     etc.+                     .+                     FreeType 2 provides its own caching subsystem+                     since release 2.0.1. It can be used to cache+                     either face instances or glyph images+                     efficiently.+License:             BSD3+License-file:        LICENSE+Author:              Jason Dagit <dagitj@gmail.com>+Maintainer:          Jason Dagit <dagitj@gmail.com>+Copyright:           Copyright Jason Dagit 2011+Category:            Graphics+Build-type:          Simple+Extra-source-files:  objs/ftmodule.h+                     include/*.h+                     include/freetype/*.h+                     include/freetype/config/*.h+                     include/freetype/internal/*.h+                     include/freetype/internal/services/*.h+                     src/base/*.h+                     src/base/*.c+                     src/truetype/*.h+                     src/truetype/*.c+                     src/type1/*.h+                     src/type1/*.c+                     src/cff/*.h+                     src/cff/*.c+                     src/cid/*.h+                     src/cid/*.c+                     src/pfr/*.h+                     src/pfr/*.c+                     src/type42/*.h+                     src/type42/*.c+                     src/winfonts/*.h+                     src/winfonts/*.c+                     src/pcf/*.h+                     src/pcf/*.c+                     src/bdf/*.h+                     src/bdf/*.c+                     src/sfnt/*.h+                     src/sfnt/*.c+                     src/autofit/*.h+                     src/autofit/*.c+                     src/pshinter/*.h+                     src/pshinter/*.c+                     src/raster/*.h+                     src/raster/*.c+                     src/smooth/*.h+                     src/smooth/*.c+                     src/cache/*.h+                     src/cache/*.c+                     src/gzip/*.h+                     src/gzip/*.c+                     src/lzw/*.h+                     src/lzw/*.c+                     src/psaux/*.h+                     src/psaux/*.c+                     src/psnames/*.h+                     src/psnames/*.c++Cabal-version:       >=1.8++Flag examples+  Description: Build example programs+  Default: False++Executable freetype-example1++  if flag(examples)+    Buildable: True+    Build-depends: base > 3 && < 5, freetype2, array,+                   missing-foreign >= 0.1.1 && < 0.2.0+  else+    Buildable: False+  Main-is:       Main.hs++Library+  -- Modules exported by the library.+  Exposed-modules: Graphics.Rendering.FreeType.Internal+                   Graphics.Rendering.FreeType.Internal.Bitmap+                   Graphics.Rendering.FreeType.Internal.Face+                   Graphics.Rendering.FreeType.Internal.GlyphSlot+                   Graphics.Rendering.FreeType.Internal.Library+                   Graphics.Rendering.FreeType.Internal.Matrix+                   Graphics.Rendering.FreeType.Internal.PrimitiveTypes+                   Graphics.Rendering.FreeType.Internal.Vector+                   Graphics.Rendering.FreeType.Internal.Glyph++  -- Packages needed in order to build this package.+  Build-depends: base > 3 && < 5++  -- Modules not exported by this package.+  -- Other-modules:       ++  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.+  Build-tools: hsc2hs+  ghc-options: -Wall+  include-dirs: objs include include/freetype/config+                include/freetype+                src/base+                src/truetype+                src/type1+                src/cff+                src/cid+                src/pfr+                src/type42+                src/winfonts+                src/pcf+                src/bdf+                src/sfnt+                src/autofit+                src/pshinter+                src/raster+                src/smooth+                src/cache+                src/gzip+                src/lzw+                src/psaux+                src/psnames++  cc-options: -DFT_CONFIG_CONFIG_H=<ftconfig.h>+              -DFT2_BUILD_LIBRARY+              -DFT_CONFIG_MODULES_H=<ftmodule.h>+              -DDARWIN_NO_CARBON++  c-sources:+             src/base/ftsystem.c+             src/base/ftdebug.c+             src/base/ftinit.c+             src/base/ftbase.c+             src/base/ftbbox.c+             src/base/ftbdf.c+             src/base/ftbitmap.c+             src/base/ftcid.c+             src/base/ftfstype.c+             src/base/ftgasp.c+             src/base/ftglyph.c+             src/base/ftgxval.c+             src/base/ftlcdfil.c+             src/base/ftmm.c+             src/base/ftotval.c+             src/base/ftpatent.c+             src/base/ftpfr.c+             src/base/ftstroke.c+             src/base/ftsynth.c+             src/base/fttype1.c+             src/base/ftwinfnt.c+             src/base/ftxf86.c+             src/truetype/truetype.c+             src/type1/type1.c+             src/cff/cff.c+             src/cid/type1cid.c+             src/pfr/pfr.c+             src/type42/type42.c+             src/winfonts/winfnt.c+             src/pcf/pcf.c+             src/bdf/bdf.c+             src/sfnt/sfnt.c+             src/autofit/autofit.c+             src/pshinter/pshinter.c+             src/raster/raster.c+             src/smooth/smooth.c+             src/cache/ftcache.c+             src/gzip/ftgzip.c+             src/lzw/ftlzw.c+             src/psaux/psaux.c+             src/psnames/psmodule.c++source-repository head+  type: git+  location: git://github.com/dagit/freetype2.git+
+ include/freetype/config/ftconfig.h view
@@ -0,0 +1,528 @@+/***************************************************************************/+/*                                                                         */+/*  ftconfig.h                                                             */+/*                                                                         */+/*    ANSI-specific configuration file (specification only).               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This header file contains a number of macro definitions that are used */+  /* by the rest of the engine.  Most of the macros here are automatically */+  /* determined at compile time, and you should not need to change it to   */+  /* port FreeType, except to compile the library with a non-ANSI          */+  /* compiler.                                                             */+  /*                                                                       */+  /* Note however that if some specific modifications are needed, we       */+  /* advise you to place a modified copy in your build directory.          */+  /*                                                                       */+  /* The build directory is usually `freetype/builds/<system>', and        */+  /* contains system-specific files that are always included first when    */+  /* building the library.                                                 */+  /*                                                                       */+  /* This ANSI version should stay in `include/freetype/config'.           */+  /*                                                                       */+  /*************************************************************************/++#ifndef __FTCONFIG_H__+#define __FTCONFIG_H__++#include <ft2build.h>+#include FT_CONFIG_OPTIONS_H+#include FT_CONFIG_STANDARD_LIBRARY_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */+  /*                                                                       */+  /* These macros can be toggled to suit a specific system.  The current   */+  /* ones are defaults used to compile FreeType in an ANSI C environment   */+  /* (16bit compilers are also supported).  Copy this file to your own     */+  /* `freetype/builds/<system>' directory, and edit it to port the engine. */+  /*                                                                       */+  /*************************************************************************/+++  /* There are systems (like the Texas Instruments 'C54x) where a `char' */+  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */+  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */+  /* is probably unexpected.                                             */+  /*                                                                     */+  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */+  /* `char' type.                                                        */++#ifndef FT_CHAR_BIT+#define FT_CHAR_BIT  CHAR_BIT+#endif+++  /* The size of an `int' type.  */+#if                                 FT_UINT_MAX == 0xFFFFUL+#define FT_SIZEOF_INT  (16 / FT_CHAR_BIT)+#elif                               FT_UINT_MAX == 0xFFFFFFFFUL+#define FT_SIZEOF_INT  (32 / FT_CHAR_BIT)+#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL+#define FT_SIZEOF_INT  (64 / FT_CHAR_BIT)+#else+#error "Unsupported size of `int' type!"+#endif++  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */+  /* DM642) is recognized but avoided.                                   */+#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL+#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL+#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL+#define FT_SIZEOF_LONG  (64 / FT_CHAR_BIT)+#else+#error "Unsupported size of `long' type!"+#endif+++  /* Preferred alignment of data */+#define FT_ALIGNMENT  8+++  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */+  /* used -- this is only used to get rid of unpleasant compiler warnings */+#ifndef FT_UNUSED+#define FT_UNUSED( arg )  ( (arg) = (arg) )+#endif+++  /*************************************************************************/+  /*                                                                       */+  /*                     AUTOMATIC CONFIGURATION MACROS                    */+  /*                                                                       */+  /* These macros are computed from the ones defined above.  Don't touch   */+  /* their definition, unless you know precisely what you are doing.  No   */+  /* porter should need to mess with them.                                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Mac support                                                           */+  /*                                                                       */+  /*   This is the only necessary change, so it is defined here instead    */+  /*   providing a new configuration file.                                 */+  /*                                                                       */+#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \+    ( defined( __MWERKS__ ) && defined( macintosh )        )+  /* no Carbon frameworks for 64bit 10.4.x */+#include "AvailabilityMacros.h"+#if defined( __LP64__ ) && \+    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )+#define DARWIN_NO_CARBON 1+#else+#define FT_MACINTOSH 1+#endif++#elif defined( __SC__ ) || defined( __MRC__ )+  /* Classic MacOS compilers */+#include "ConditionalMacros.h"+#if TARGET_OS_MAC+#define FT_MACINTOSH 1+#endif++#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    basic_types                                                        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Int16                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for a 16bit signed integer type.                         */+  /*                                                                       */+  typedef signed short  FT_Int16;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_UInt16                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for a 16bit unsigned integer type.                       */+  /*                                                                       */+  typedef unsigned short  FT_UInt16;++  /* */+++  /* this #if 0 ... #endif clause is for documentation purposes */+#if 0++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Int32                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for a 32bit signed integer type.  The size depends on    */+  /*    the configuration.                                                 */+  /*                                                                       */+  typedef signed XXX  FT_Int32;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_UInt32                                                          */+  /*                                                                       */+  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */+  /*    the configuration.                                                 */+  /*                                                                       */+  typedef unsigned XXX  FT_UInt32;++  /* */++#endif++#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT)++  typedef signed int      FT_Int32;+  typedef unsigned int    FT_UInt32;++#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT)++  typedef signed long     FT_Int32;+  typedef unsigned long   FT_UInt32;++#else+#error "no 32bit type found -- please check your configuration files"+#endif+++  /* look up an integer type that is at least 32 bits */+#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT)++  typedef int            FT_Fast;+  typedef unsigned int   FT_UFast;++#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT)++  typedef long           FT_Fast;+  typedef unsigned long  FT_UFast;++#endif+++  /* determine whether we have a 64-bit int type for platforms without */+  /* Autoconf                                                          */+#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT)++  /* FT_LONG64 must be defined if a 64-bit type is available */+#define FT_LONG64+#define FT_INT64  long++#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */++  /* this compiler provides the __int64 type */+#define FT_LONG64+#define FT_INT64  __int64++#elif defined( __BORLANDC__ )  /* Borland C++ */++  /* XXXX: We should probably check the value of __BORLANDC__ in order */+  /*       to test the compiler version.                               */++  /* this compiler provides the __int64 type */+#define FT_LONG64+#define FT_INT64  __int64++#elif defined( __WATCOMC__ )   /* Watcom C++ */++  /* Watcom doesn't provide 64-bit data types */++#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */++#define FT_LONG64+#define FT_INT64  long long int++#elif defined( __GNUC__ )++  /* GCC provides the `long long' type */+#define FT_LONG64+#define FT_INT64  long long int++#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */+++  /*************************************************************************/+  /*                                                                       */+  /* A 64-bit data type will create compilation problems if you compile    */+  /* in strict ANSI mode.  To avoid them, we disable its use if __STDC__   */+  /* is defined.  You can however ignore this rule by defining the         */+  /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro.                     */+  /*                                                                       */+#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )++#ifdef __STDC__++  /* undefine the 64-bit macros in strict ANSI compilation mode */+#undef FT_LONG64+#undef FT_INT64++#endif /* __STDC__ */++#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */+++#define FT_BEGIN_STMNT  do {+#define FT_END_STMNT    } while ( 0 )+#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT+++#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER+  /* Provide assembler fragments for performance-critical functions. */+  /* These must be defined `static __inline__' with GCC.             */++#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm++  /* documentation is in freetype.h */++  static __inline FT_Int32+  FT_MulFix_arm( FT_Int32  a,+                 FT_Int32  b )+  {+    register FT_Int32  t, t2;+++    __asm+    {+      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */+      mov   a,  t,  asr #31         /* a   = (hi >> 31) */+      add   a,  a,  #0x8000         /* a  += 0x8000 */+      adds  t2, t2, a               /* t2 += a */+      adc   t,  t,  #0              /* t  += carry */+      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */+      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */+    }+    return a;+  }++#endif /* __CC_ARM || __ARMCC__ */+++#ifdef __GNUC__++#if defined( __arm__ ) && !defined( __thumb__ )    && \+    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm++  /* documentation is in freetype.h */++  static __inline__ FT_Int32+  FT_MulFix_arm( FT_Int32  a,+                 FT_Int32  b )+  {+    register FT_Int32  t, t2;+++    asm __volatile__ (+      "smull  %1, %2, %4, %3\n\t"   /* (lo=%1,hi=%2) = a*b */+      "mov    %0, %2, asr #31\n\t"  /* %0  = (hi >> 31) */+      "add    %0, %0, #0x8000\n\t"  /* %0 += 0x8000 */+      "adds   %1, %1, %0\n\t"       /* %1 += %0 */+      "adc    %2, %2, #0\n\t"       /* %2 += carry */+      "mov    %0, %1, lsr #16\n\t"  /* %0  = %1 >> 16 */+      "orr    %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */+      : "=r"(a), "=&r"(t2), "=&r"(t)+      : "r"(a), "r"(b) );+    return a;+  }++#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */++#if defined( __i386__ )+#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386++  /* documentation is in freetype.h */++  static __inline__ FT_Int32+  FT_MulFix_i386( FT_Int32  a,+                  FT_Int32  b )+  {+    register FT_Int32  result;+++    __asm__ __volatile__ (+      "imul  %%edx\n"+      "movl  %%edx, %%ecx\n"+      "sarl  $31, %%ecx\n"+      "addl  $0x8000, %%ecx\n"+      "addl  %%ecx, %%eax\n"+      "adcl  $0, %%edx\n"+      "shrl  $16, %%eax\n"+      "shll  $16, %%edx\n"+      "addl  %%edx, %%eax\n"+      : "=a"(result), "=d"(b)+      : "a"(a), "d"(b)+      : "%ecx", "cc" );+    return result;+  }++#endif /* i386 */++#endif /* __GNUC__ */++#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */+++#ifdef FT_CONFIG_OPTION_INLINE_MULFIX+#ifdef FT_MULFIX_ASSEMBLER+#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER+#endif+#endif+++#ifdef FT_MAKE_OPTION_SINGLE_OBJECT++#define FT_LOCAL( x )      static  x+#define FT_LOCAL_DEF( x )  static  x++#else++#ifdef __cplusplus+#define FT_LOCAL( x )      extern "C"  x+#define FT_LOCAL_DEF( x )  extern "C"  x+#else+#define FT_LOCAL( x )      extern  x+#define FT_LOCAL_DEF( x )  x+#endif++#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */+++#ifndef FT_BASE++#ifdef __cplusplus+#define FT_BASE( x )  extern "C"  x+#else+#define FT_BASE( x )  extern  x+#endif++#endif /* !FT_BASE */+++#ifndef FT_BASE_DEF++#ifdef __cplusplus+#define FT_BASE_DEF( x )  x+#else+#define FT_BASE_DEF( x )  x+#endif++#endif /* !FT_BASE_DEF */+++#ifndef FT_EXPORT++#ifdef __cplusplus+#define FT_EXPORT( x )  extern "C"  x+#else+#define FT_EXPORT( x )  extern  x+#endif++#endif /* !FT_EXPORT */+++#ifndef FT_EXPORT_DEF++#ifdef __cplusplus+#define FT_EXPORT_DEF( x )  extern "C"  x+#else+#define FT_EXPORT_DEF( x )  extern  x+#endif++#endif /* !FT_EXPORT_DEF */+++#ifndef FT_EXPORT_VAR++#ifdef __cplusplus+#define FT_EXPORT_VAR( x )  extern "C"  x+#else+#define FT_EXPORT_VAR( x )  extern  x+#endif++#endif /* !FT_EXPORT_VAR */++  /* The following macros are needed to compile the library with a   */+  /* C++ compiler and with 16bit compilers.                          */+  /*                                                                 */++  /* This is special.  Within C++, you must specify `extern "C"' for */+  /* functions which are used via function pointers, and you also    */+  /* must do that for structures which contain function pointers to  */+  /* assure C linkage -- it's not possible to have (local) anonymous */+  /* functions which are accessed by (global) function pointers.     */+  /*                                                                 */+  /*                                                                 */+  /* FT_CALLBACK_DEF is used to _define_ a callback function.        */+  /*                                                                 */+  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */+  /* contains pointers to callback functions.                        */+  /*                                                                 */+  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */+  /* that contains pointers to callback functions.                   */+  /*                                                                 */+  /*                                                                 */+  /* Some 16bit compilers have to redefine these macros to insert    */+  /* the infamous `_cdecl' or `__fastcall' declarations.             */+  /*                                                                 */+#ifndef FT_CALLBACK_DEF+#ifdef __cplusplus+#define FT_CALLBACK_DEF( x )  extern "C"  x+#else+#define FT_CALLBACK_DEF( x )  static  x+#endif+#endif /* FT_CALLBACK_DEF */++#ifndef FT_CALLBACK_TABLE+#ifdef __cplusplus+#define FT_CALLBACK_TABLE      extern "C"+#define FT_CALLBACK_TABLE_DEF  extern "C"+#else+#define FT_CALLBACK_TABLE      extern+#define FT_CALLBACK_TABLE_DEF  /* nothing */+#endif+#endif /* FT_CALLBACK_TABLE */+++FT_END_HEADER+++#endif /* __FTCONFIG_H__ */+++/* END */
+ include/freetype/config/ftheader.h view
@@ -0,0 +1,780 @@+/***************************************************************************/+/*                                                                         */+/*  ftheader.h                                                             */+/*                                                                         */+/*    Build macros of the FreeType 2 library.                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#ifndef __FT_HEADER_H__+#define __FT_HEADER_H__+++  /*@***********************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_BEGIN_HEADER                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro is used in association with @FT_END_HEADER in header    */+  /*    files to ensure that the declarations within are properly          */+  /*    encapsulated in an `extern "C" { .. }' block when included from a  */+  /*    C++ compiler.                                                      */+  /*                                                                       */+#ifdef __cplusplus+#define FT_BEGIN_HEADER  extern "C" {+#else+#define FT_BEGIN_HEADER  /* nothing */+#endif+++  /*@***********************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_END_HEADER                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro is used in association with @FT_BEGIN_HEADER in header  */+  /*    files to ensure that the declarations within are properly          */+  /*    encapsulated in an `extern "C" { .. }' block when included from a  */+  /*    C++ compiler.                                                      */+  /*                                                                       */+#ifdef __cplusplus+#define FT_END_HEADER  }+#else+#define FT_END_HEADER  /* nothing */+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* Aliases for the FreeType 2 public and configuration files.            */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    header_file_macros                                                 */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Header File Macros                                                 */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Macro definitions used to #include specific header files.          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The following macros are defined to the name of specific           */+  /*    FreeType~2 header files.  They can be used directly in #include    */+  /*    statements as in:                                                  */+  /*                                                                       */+  /*    {                                                                  */+  /*      #include FT_FREETYPE_H                                           */+  /*      #include FT_MULTIPLE_MASTERS_H                                   */+  /*      #include FT_GLYPH_H                                              */+  /*    }                                                                  */+  /*                                                                       */+  /*    There are several reasons why we are now using macros to name      */+  /*    public header files.  The first one is that such macros are not    */+  /*    limited to the infamous 8.3~naming rule required by DOS (and       */+  /*    `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h').   */+  /*                                                                       */+  /*    The second reason is that it allows for more flexibility in the    */+  /*    way FreeType~2 is installed on a given system.                     */+  /*                                                                       */+  /*************************************************************************/+++  /* configuration files */++  /*************************************************************************+   *+   * @macro:+   *   FT_CONFIG_CONFIG_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing+   *   FreeType~2 configuration data.+   *+   */+#ifndef FT_CONFIG_CONFIG_H+#define FT_CONFIG_CONFIG_H  <freetype/config/ftconfig.h>+#endif+++  /*************************************************************************+   *+   * @macro:+   *   FT_CONFIG_STANDARD_LIBRARY_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing+   *   FreeType~2 interface to the standard C library functions.+   *+   */+#ifndef FT_CONFIG_STANDARD_LIBRARY_H+#define FT_CONFIG_STANDARD_LIBRARY_H  <freetype/config/ftstdlib.h>+#endif+++  /*************************************************************************+   *+   * @macro:+   *   FT_CONFIG_OPTIONS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing+   *   FreeType~2 project-specific configuration options.+   *+   */+#ifndef FT_CONFIG_OPTIONS_H+#define FT_CONFIG_OPTIONS_H  <freetype/config/ftoption.h>+#endif+++  /*************************************************************************+   *+   * @macro:+   *   FT_CONFIG_MODULES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   list of FreeType~2 modules that are statically linked to new library+   *   instances in @FT_Init_FreeType.+   *+   */+#ifndef FT_CONFIG_MODULES_H+#define FT_CONFIG_MODULES_H  <freetype/config/ftmodule.h>+#endif++  /* */++  /* public headers */++  /*************************************************************************+   *+   * @macro:+   *   FT_FREETYPE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   base FreeType~2 API.+   *+   */+#define FT_FREETYPE_H  <freetype/freetype.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_ERRORS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   list of FreeType~2 error codes (and messages).+   *+   *   It is included by @FT_FREETYPE_H.+   *+   */+#define FT_ERRORS_H  <freetype/fterrors.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_MODULE_ERRORS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   list of FreeType~2 module error offsets (and messages).+   *+   */+#define FT_MODULE_ERRORS_H  <freetype/ftmoderr.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_SYSTEM_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 interface to low-level operations (i.e., memory management+   *   and stream i/o).+   *+   *   It is included by @FT_FREETYPE_H.+   *+   */+#define FT_SYSTEM_H  <freetype/ftsystem.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_IMAGE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing type+   *   definitions related to glyph images (i.e., bitmaps, outlines,+   *   scan-converter parameters).+   *+   *   It is included by @FT_FREETYPE_H.+   *+   */+#define FT_IMAGE_H  <freetype/ftimage.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TYPES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   basic data types defined by FreeType~2.+   *+   *   It is included by @FT_FREETYPE_H.+   *+   */+#define FT_TYPES_H  <freetype/fttypes.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_LIST_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   list management API of FreeType~2.+   *+   *   (Most applications will never need to include this file.)+   *+   */+#define FT_LIST_H  <freetype/ftlist.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_OUTLINE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   scalable outline management API of FreeType~2.+   *+   */+#define FT_OUTLINE_H  <freetype/ftoutln.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_SIZES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   API which manages multiple @FT_Size objects per face.+   *+   */+#define FT_SIZES_H  <freetype/ftsizes.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_MODULE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   module management API of FreeType~2.+   *+   */+#define FT_MODULE_H  <freetype/ftmodapi.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_RENDER_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   renderer module management API of FreeType~2.+   *+   */+#define FT_RENDER_H  <freetype/ftrender.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TYPE1_TABLES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   types and API specific to the Type~1 format.+   *+   */+#define FT_TYPE1_TABLES_H  <freetype/t1tables.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TRUETYPE_IDS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   enumeration values which identify name strings, languages, encodings,+   *   etc.  This file really contains a _large_ set of constant macro+   *   definitions, taken from the TrueType and OpenType specifications.+   *+   */+#define FT_TRUETYPE_IDS_H  <freetype/ttnameid.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TRUETYPE_TABLES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   types and API specific to the TrueType (as well as OpenType) format.+   *+   */+#define FT_TRUETYPE_TABLES_H  <freetype/tttables.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TRUETYPE_TAGS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of TrueType four-byte `tags' which identify blocks in+   *   SFNT-based font formats (i.e., TrueType and OpenType).+   *+   */+#define FT_TRUETYPE_TAGS_H  <freetype/tttags.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_BDF_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of an API which accesses BDF-specific strings from a+   *   face.+   *+   */+#define FT_BDF_H  <freetype/ftbdf.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_CID_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of an API which access CID font information from a+   *   face.+   *+   */+#define FT_CID_H  <freetype/ftcid.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_GZIP_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of an API which supports gzip-compressed files.+   *+   */+#define FT_GZIP_H  <freetype/ftgzip.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_LZW_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of an API which supports LZW-compressed files.+   *+   */+#define FT_LZW_H  <freetype/ftlzw.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_WINFONTS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   definitions of an API which supports Windows FNT files.+   *+   */+#define FT_WINFONTS_H   <freetype/ftwinfnt.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_GLYPH_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   API of the optional glyph management component.+   *+   */+#define FT_GLYPH_H  <freetype/ftglyph.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_BITMAP_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   API of the optional bitmap conversion component.+   *+   */+#define FT_BITMAP_H  <freetype/ftbitmap.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_BBOX_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   API of the optional exact bounding box computation routines.+   *+   */+#define FT_BBOX_H  <freetype/ftbbox.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_CACHE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   API of the optional FreeType~2 cache sub-system.+   *+   */+#define FT_CACHE_H  <freetype/ftcache.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_CACHE_IMAGE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   `glyph image' API of the FreeType~2 cache sub-system.+   *+   *   It is used to define a cache for @FT_Glyph elements.  You can also+   *   use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to+   *   store small glyph bitmaps, as it will use less memory.+   *+   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all+   *   glyph image-related cache declarations.+   *+   */+#define FT_CACHE_IMAGE_H  FT_CACHE_H+++  /*************************************************************************+   *+   * @macro:+   *   FT_CACHE_SMALL_BITMAPS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   `small bitmaps' API of the FreeType~2 cache sub-system.+   *+   *   It is used to define a cache for small glyph bitmaps in a relatively+   *   memory-efficient way.  You can also use the API defined in+   *   @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images,+   *   including scalable outlines.+   *+   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all+   *   small bitmaps-related cache declarations.+   *+   */+#define FT_CACHE_SMALL_BITMAPS_H  FT_CACHE_H+++  /*************************************************************************+   *+   * @macro:+   *   FT_CACHE_CHARMAP_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   `charmap' API of the FreeType~2 cache sub-system.+   *+   *   This macro is deprecated.  Simply include @FT_CACHE_H to have all+   *   charmap-based cache declarations.+   *+   */+#define FT_CACHE_CHARMAP_H  FT_CACHE_H+++  /*************************************************************************+   *+   * @macro:+   *   FT_MAC_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   Macintosh-specific FreeType~2 API.  The latter is used to access+   *   fonts embedded in resource forks.+   *+   *   This header file must be explicitly included by client applications+   *   compiled on the Mac (note that the base API still works though).+   *+   */+#define FT_MAC_H  <freetype/ftmac.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_MULTIPLE_MASTERS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   optional multiple-masters management API of FreeType~2.+   *+   */+#define FT_MULTIPLE_MASTERS_H  <freetype/ftmm.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_SFNT_NAMES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   optional FreeType~2 API which accesses embedded `name' strings in+   *   SFNT-based font formats (i.e., TrueType and OpenType).+   *+   */+#define FT_SFNT_NAMES_H  <freetype/ftsnames.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_OPENTYPE_VALIDATE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   optional FreeType~2 API which validates OpenType tables (BASE, GDEF,+   *   GPOS, GSUB, JSTF).+   *+   */+#define FT_OPENTYPE_VALIDATE_H  <freetype/ftotval.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_GX_VALIDATE_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat,+   *   mort, morx, bsln, just, kern, opbd, trak, prop).+   *+   */+#define FT_GX_VALIDATE_H  <freetype/ftgxval.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_PFR_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which accesses PFR-specific data.+   *+   */+#define FT_PFR_H  <freetype/ftpfr.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_STROKER_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which provides functions to stroke outline paths.+   */+#define FT_STROKER_H  <freetype/ftstroke.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_SYNTHESIS_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which performs artificial obliquing and emboldening.+   */+#define FT_SYNTHESIS_H  <freetype/ftsynth.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_XFREE86_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which provides functions specific to the XFree86 and+   *   X.Org X11 servers.+   */+#define FT_XFREE86_H  <freetype/ftxf86.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_TRIGONOMETRY_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which performs trigonometric computations (e.g.,+   *   cosines and arc tangents).+   */+#define FT_TRIGONOMETRY_H  <freetype/fttrigon.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_LCD_FILTER_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which performs color filtering for subpixel rendering.+   */+#define FT_LCD_FILTER_H  <freetype/ftlcdfil.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_UNPATENTED_HINTING_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which performs color filtering for subpixel rendering.+   */+#define FT_UNPATENTED_HINTING_H  <freetype/ttunpat.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_INCREMENTAL_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which performs color filtering for subpixel rendering.+   */+#define FT_INCREMENTAL_H  <freetype/ftincrem.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_GASP_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which returns entries from the TrueType GASP table.+   */+#define FT_GASP_H  <freetype/ftgasp.h>+++  /*************************************************************************+   *+   * @macro:+   *   FT_ADVANCES_H+   *+   * @description:+   *   A macro used in #include statements to name the file containing the+   *   FreeType~2 API which returns individual and ranged glyph advances.+   */+#define FT_ADVANCES_H  <freetype/ftadvanc.h>+++  /* */++#define FT_ERROR_DEFINITIONS_H  <freetype/fterrdef.h>+++  /* The internals of the cache sub-system are no longer exposed.  We */+  /* default to FT_CACHE_H at the moment just in case, but we know of */+  /* no rogue client that uses them.                                  */+  /*                                                                  */+#define FT_CACHE_MANAGER_H           <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_MRU_H      <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_MANAGER_H  <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_CACHE_H    <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_GLYPH_H    <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_IMAGE_H    <freetype/ftcache.h>+#define FT_CACHE_INTERNAL_SBITS_H    <freetype/ftcache.h>+++#define FT_INCREMENTAL_H          <freetype/ftincrem.h>++#define FT_TRUETYPE_UNPATENTED_H  <freetype/ttunpat.h>+++  /*+   * Include internal headers definitions from <freetype/internal/...>+   * only when building the library.+   */+#ifdef FT2_BUILD_LIBRARY+#define  FT_INTERNAL_INTERNAL_H  <freetype/internal/internal.h>+#include FT_INTERNAL_INTERNAL_H+#endif /* FT2_BUILD_LIBRARY */+++#endif /* __FT2_BUILD_H__ */+++/* END */
+ include/freetype/config/ftmodule.h view
@@ -0,0 +1,32 @@+/*+ *  This file registers the FreeType modules compiled into the library.+ *+ *  If you use GNU make, this file IS NOT USED!  Instead, it is created in+ *  the objects directory (normally `<topdir>/objs/') based on information+ *  from `<topdir>/modules.cfg'.+ *+ *  Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile+ *  FreeType without GNU make.+ *+ */++FT_USE_MODULE( FT_Module_Class, autofit_module_class )+FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )+FT_USE_MODULE( FT_Module_Class, psaux_module_class )+FT_USE_MODULE( FT_Module_Class, psnames_module_class )+FT_USE_MODULE( FT_Module_Class, pshinter_module_class )+FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )+FT_USE_MODULE( FT_Module_Class, sfnt_module_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )+FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )++/* EOF */
+ include/freetype/config/ftoption.h view
@@ -0,0 +1,733 @@+/***************************************************************************/+/*                                                                         */+/*  ftoption.h                                                             */+/*                                                                         */+/*    User-selectable configuration macros (specification only).           */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTOPTION_H__+#define __FTOPTION_H__+++#include <ft2build.h>+++FT_BEGIN_HEADER++  /*************************************************************************/+  /*                                                                       */+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */+  /*                                                                       */+  /* This file contains the default configuration macro definitions for    */+  /* a standard build of the FreeType library.  There are three ways to    */+  /* use this file to build project-specific versions of the library:      */+  /*                                                                       */+  /*  - You can modify this file by hand, but this is not recommended in   */+  /*    cases where you would like to build several versions of the        */+  /*    library from a single source directory.                            */+  /*                                                                       */+  /*  - You can put a copy of this file in your build directory, more      */+  /*    precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'   */+  /*    is the name of a directory that is included _before_ the FreeType  */+  /*    include path during compilation.                                   */+  /*                                                                       */+  /*    The default FreeType Makefiles and Jamfiles use the build          */+  /*    directory `builds/<system>' by default, but you can easily change  */+  /*    that for your own projects.                                        */+  /*                                                                       */+  /*  - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it    */+  /*    slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to       */+  /*    locate this file during the build.  For example,                   */+  /*                                                                       */+  /*      #define FT_CONFIG_OPTIONS_H  <myftoptions.h>                     */+  /*      #include <freetype/config/ftheader.h>                            */+  /*                                                                       */+  /*    will use `$BUILD/myftoptions.h' instead of this file for macro     */+  /*    definitions.                                                       */+  /*                                                                       */+  /*    Note also that you can similarly pre-define the macro              */+  /*    FT_CONFIG_MODULES_H used to locate the file listing of the modules */+  /*    that are statically linked to the library at compile time.  By     */+  /*    default, this file is <freetype/config/ftmodule.h>.                */+  /*                                                                       */+  /*  We highly recommend using the third method whenever possible.        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /**** G E N E R A L   F R E E T Y P E   2   C O N F I G U R A T I O N ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Uncomment the line below if you want to activate sub-pixel rendering  */+  /* (a.k.a. LCD rendering, or ClearType) in this build of the library.    */+  /*                                                                       */+  /* Note that this feature is covered by several Microsoft patents        */+  /* and should not be activated in any default build of the library.      */+  /*                                                                       */+  /* This macro has no impact on the FreeType API, only on its             */+  /* _implementation_.  For example, using FT_RENDER_MODE_LCD when calling */+  /* FT_Render_Glyph still generates a bitmap that is 3 times wider than   */+  /* the original size in case this macro isn't defined; however, each     */+  /* triplet of subpixels has R=G=B.                                       */+  /*                                                                       */+  /* This is done to allow FreeType clients to run unmodified, forcing     */+  /* them to display normal gray-level anti-aliased glyphs.                */+  /*                                                                       */+/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */+++  /*************************************************************************/+  /*                                                                       */+  /* Many compilers provide a non-ANSI 64-bit data type that can be used   */+  /* by FreeType to speed up some computations.  However, this will create */+  /* some problems when compiling the library in strict ANSI mode.         */+  /*                                                                       */+  /* For this reason, the use of 64-bit integers is normally disabled when */+  /* the __STDC__ macro is defined.  You can however disable this by       */+  /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.                 */+  /*                                                                       */+  /* For most compilers, this will only create compilation warnings when   */+  /* building the library.                                                 */+  /*                                                                       */+  /* ObNote: The compiler-specific 64-bit integers are detected in the     */+  /*         file `ftconfig.h' either statically or through the            */+  /*         `configure' script on supported platforms.                    */+  /*                                                                       */+#undef FT_CONFIG_OPTION_FORCE_INT64+++  /*************************************************************************/+  /*                                                                       */+  /* If this macro is defined, do not try to use an assembler version of   */+  /* performance-critical functions (e.g. FT_MulFix).  You should only do  */+  /* that to verify that the assembler function works properly, or to      */+  /* execute benchmark tests of the various implementations.               */+/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */+++  /*************************************************************************/+  /*                                                                       */+  /* If this macro is defined, try to use an inlined assembler version of  */+  /* the `FT_MulFix' function, which is a `hotspot' when loading and       */+  /* hinting glyphs, and which should be executed as fast as possible.     */+  /*                                                                       */+  /* Note that if your compiler or CPU is not supported, this will default */+  /* to the standard and portable implementation found in `ftcalc.c'.      */+  /*                                                                       */+#define FT_CONFIG_OPTION_INLINE_MULFIX+++  /*************************************************************************/+  /*                                                                       */+  /* LZW-compressed file support.                                          */+  /*                                                                       */+  /*   FreeType now handles font files that have been compressed with the  */+  /*   `compress' program.  This is mostly used to parse many of the PCF   */+  /*   files that come with various X11 distributions.  The implementation */+  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */+  /*   (see src/lzw/ftgzip.c).                                             */+  /*                                                                       */+  /*   Define this macro if you want to enable this `feature'.             */+  /*                                                                       */+#define FT_CONFIG_OPTION_USE_LZW+++  /*************************************************************************/+  /*                                                                       */+  /* Gzip-compressed file support.                                         */+  /*                                                                       */+  /*   FreeType now handles font files that have been compressed with the  */+  /*   `gzip' program.  This is mostly used to parse many of the PCF files */+  /*   that come with XFree86.  The implementation uses `zlib' to          */+  /*   partially uncompress the file on the fly (see src/gzip/ftgzip.c).   */+  /*                                                                       */+  /*   Define this macro if you want to enable this `feature'.  See also   */+  /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */+  /*                                                                       */+#define FT_CONFIG_OPTION_USE_ZLIB+++  /*************************************************************************/+  /*                                                                       */+  /* ZLib library selection                                                */+  /*                                                                       */+  /*   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.  */+  /*   It allows FreeType's `ftgzip' component to link to the system's     */+  /*   installation of the ZLib library.  This is useful on systems like   */+  /*   Unix or VMS where it generally is already available.                */+  /*                                                                       */+  /*   If you let it undefined, the component will use its own copy        */+  /*   of the zlib sources instead.  These have been modified to be        */+  /*   included directly within the component and *not* export external    */+  /*   function names.  This allows you to link any program with FreeType  */+  /*   _and_ ZLib without linking conflicts.                               */+  /*                                                                       */+  /*   Do not #undef this macro here since the build system might define   */+  /*   it for certain configurations only.                                 */+  /*                                                                       */+/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */+++  /*************************************************************************/+  /*                                                                       */+  /* DLL export compilation                                                */+  /*                                                                       */+  /*   When compiling FreeType as a DLL, some systems/compilers need a     */+  /*   special keyword in front OR after the return type of function       */+  /*   declarations.                                                       */+  /*                                                                       */+  /*   Two macros are used within the FreeType source code to define       */+  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */+  /*                                                                       */+  /*     FT_EXPORT( return_type )                                          */+  /*                                                                       */+  /*       is used in a function declaration, as in                        */+  /*                                                                       */+  /*         FT_EXPORT( FT_Error )                                         */+  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */+  /*                                                                       */+  /*                                                                       */+  /*     FT_EXPORT_DEF( return_type )                                      */+  /*                                                                       */+  /*       is used in a function definition, as in                         */+  /*                                                                       */+  /*         FT_EXPORT_DEF( FT_Error )                                     */+  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */+  /*         {                                                             */+  /*           ... some code ...                                           */+  /*           return FT_Err_Ok;                                           */+  /*         }                                                             */+  /*                                                                       */+  /*   You can provide your own implementation of FT_EXPORT and            */+  /*   FT_EXPORT_DEF here if you want.  If you leave them undefined, they  */+  /*   will be later automatically defined as `extern return_type' to      */+  /*   allow normal compilation.                                           */+  /*                                                                       */+  /*   Do not #undef these macros here since the build system might define */+  /*   them for certain configurations only.                               */+  /*                                                                       */+/* #define FT_EXPORT(x)      extern x */+/* #define FT_EXPORT_DEF(x)  x */+++  /*************************************************************************/+  /*                                                                       */+  /* Glyph Postscript Names handling                                       */+  /*                                                                       */+  /*   By default, FreeType 2 is compiled with the `psnames' module.  This */+  /*   module is in charge of converting a glyph name string into a        */+  /*   Unicode value, or return a Macintosh standard glyph name for the    */+  /*   use with the TrueType `post' table.                                 */+  /*                                                                       */+  /*   Undefine this macro if you do not want `psnames' compiled in your   */+  /*   build of FreeType.  This has the following effects:                 */+  /*                                                                       */+  /*   - The TrueType driver will provide its own set of glyph names,      */+  /*     if you build it to support postscript names in the TrueType       */+  /*     `post' table.                                                     */+  /*                                                                       */+  /*   - The Type 1 driver will not be able to synthesize a Unicode        */+  /*     charmap out of the glyphs found in the fonts.                     */+  /*                                                                       */+  /*   You would normally undefine this configuration macro when building  */+  /*   a version of FreeType that doesn't contain a Type 1 or CFF driver.  */+  /*                                                                       */+#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES+++  /*************************************************************************/+  /*                                                                       */+  /* Postscript Names to Unicode Values support                            */+  /*                                                                       */+  /*   By default, FreeType 2 is built with the `PSNames' module compiled  */+  /*   in.  Among other things, the module is used to convert a glyph name */+  /*   into a Unicode value.  This is especially useful in order to        */+  /*   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver  */+  /*   through a big table named the `Adobe Glyph List' (AGL).             */+  /*                                                                       */+  /*   Undefine this macro if you do not want the Adobe Glyph List         */+  /*   compiled in your `PSNames' module.  The Type 1 driver will not be   */+  /*   able to synthesize a Unicode charmap out of the glyphs found in the */+  /*   fonts.                                                              */+  /*                                                                       */+#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST+++  /*************************************************************************/+  /*                                                                       */+  /* Support for Mac fonts                                                 */+  /*                                                                       */+  /*   Define this macro if you want support for outline fonts in Mac      */+  /*   format (mac dfont, mac resource, macbinary containing a mac         */+  /*   resource) on non-Mac platforms.                                     */+  /*                                                                       */+  /*   Note that the `FOND' resource isn't checked.                        */+  /*                                                                       */+#define FT_CONFIG_OPTION_MAC_FONTS+++  /*************************************************************************/+  /*                                                                       */+  /* Guessing methods to access embedded resource forks                    */+  /*                                                                       */+  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */+  /*   GNU/Linux).                                                         */+  /*                                                                       */+  /*   Resource forks which include fonts data are stored sometimes in     */+  /*   locations which users or developers don't expected.  In some cases, */+  /*   resource forks start with some offset from the head of a file.  In  */+  /*   other cases, the actual resource fork is stored in file different   */+  /*   from what the user specifies.  If this option is activated,         */+  /*   FreeType tries to guess whether such offsets or different file      */+  /*   names must be used.                                                 */+  /*                                                                       */+  /*   Note that normal, direct access of resource forks is controlled via */+  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */+  /*                                                                       */+#ifdef FT_CONFIG_OPTION_MAC_FONTS+#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* Allow the use of FT_Incremental_Interface to load typefaces that      */+  /* contain no glyph data, but supply it via a callback function.         */+  /* This is required by clients supporting document formats which         */+  /* supply font data incrementally as the document is parsed, such        */+  /* as the Ghostscript interpreter for the PostScript language.           */+  /*                                                                       */+#define FT_CONFIG_OPTION_INCREMENTAL+++  /*************************************************************************/+  /*                                                                       */+  /* The size in bytes of the render pool used by the scan-line converter  */+  /* to do all of its work.                                                */+  /*                                                                       */+  /* This must be greater than 4KByte if you use FreeType to rasterize     */+  /* glyphs; otherwise, you may set it to zero to avoid unnecessary        */+  /* allocation of the render pool.                                        */+  /*                                                                       */+#define FT_RENDER_POOL_SIZE  16384L+++  /*************************************************************************/+  /*                                                                       */+  /* FT_MAX_MODULES                                                        */+  /*                                                                       */+  /*   The maximum number of modules that can be registered in a single    */+  /*   FreeType library object.  32 is the default.                        */+  /*                                                                       */+#define FT_MAX_MODULES  32+++  /*************************************************************************/+  /*                                                                       */+  /* Debug level                                                           */+  /*                                                                       */+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */+  /*   errors are reported through the `ftdebug' component.  In trace      */+  /*   mode, additional messages are sent to the standard output during    */+  /*   execution.                                                          */+  /*                                                                       */+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */+  /*                                                                       */+  /*   Don't define any of these macros to compile in `release' mode!      */+  /*                                                                       */+  /*   Do not #undef these macros here since the build system might define */+  /*   them for certain configurations only.                               */+  /*                                                                       */+/* #define FT_DEBUG_LEVEL_ERROR */+/* #define FT_DEBUG_LEVEL_TRACE */+++  /*************************************************************************/+  /*                                                                       */+  /* Memory Debugging                                                      */+  /*                                                                       */+  /*   FreeType now comes with an integrated memory debugger that is       */+  /*   capable of detecting simple errors like memory leaks or double      */+  /*   deletes.  To compile it within your build of the library, you       */+  /*   should define FT_DEBUG_MEMORY here.                                 */+  /*                                                                       */+  /*   Note that the memory debugger is only activated at runtime when     */+  /*   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */+  /*                                                                       */+  /*   Do not #undef this macro here since the build system might define   */+  /*   it for certain configurations only.                                 */+  /*                                                                       */+/* #define FT_DEBUG_MEMORY */+++  /*************************************************************************/+  /*                                                                       */+  /* Module errors                                                         */+  /*                                                                       */+  /*   If this macro is set (which is _not_ the default), the higher byte  */+  /*   of an error code gives the module in which the error has occurred,  */+  /*   while the lower byte is the real error code.                        */+  /*                                                                       */+  /*   Setting this macro makes sense for debugging purposes only, since   */+  /*   it would break source compatibility of certain programs that use    */+  /*   FreeType 2.                                                         */+  /*                                                                       */+  /*   More details can be found in the files ftmoderr.h and fterrors.h.   */+  /*                                                                       */+#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS+++  /*************************************************************************/+  /*                                                                       */+  /* Position Independent Code                                             */+  /*                                                                       */+  /*   If this macro is set (which is _not_ the default), FreeType2 will   */+  /*   avoid creating constants that require address fixups.  Instead the  */+  /*   constants will be moved into a struct and additional intialization  */+  /*   code will be used.                                                  */+  /*                                                                       */+  /*   Setting this macro is needed for systems that prohibit address      */+  /*   fixups, such as BREW.                                               */+  /*                                                                       */+/* #define FT_CONFIG_OPTION_PIC */+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****        S F N T   D R I V E R    C O N F I G U R A T I O N       ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */+  /* embedded bitmaps in all formats using the SFNT module (namely         */+  /* TrueType & OpenType).                                                 */+  /*                                                                       */+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */+  /* load and enumerate the glyph Postscript names in a TrueType or        */+  /* OpenType file.                                                        */+  /*                                                                       */+  /* Note that when you do not compile the `PSNames' module by undefining  */+  /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will   */+  /* contain additional code used to read the PS Names table from a font.  */+  /*                                                                       */+  /* (By default, the module uses `PSNames' to extract glyph names.)       */+  /*                                                                       */+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to       */+  /* access the internal name table in a SFNT-based format like TrueType   */+  /* or OpenType.  The name table contains various strings used to         */+  /* describe the font, like family name, copyright, version, etc.  It     */+  /* does not contain any glyph name though.                               */+  /*                                                                       */+  /* Accessing SFNT names is done through the functions declared in        */+  /* `freetype/ftsnames.h'.                                                */+  /*                                                                       */+#define TT_CONFIG_OPTION_SFNT_NAMES+++  /*************************************************************************/+  /*                                                                       */+  /* TrueType CMap support                                                 */+  /*                                                                       */+  /*   Here you can fine-tune which TrueType CMap table format shall be    */+  /*   supported.                                                          */+#define TT_CONFIG_CMAP_FORMAT_0+#define TT_CONFIG_CMAP_FORMAT_2+#define TT_CONFIG_CMAP_FORMAT_4+#define TT_CONFIG_CMAP_FORMAT_6+#define TT_CONFIG_CMAP_FORMAT_8+#define TT_CONFIG_CMAP_FORMAT_10+#define TT_CONFIG_CMAP_FORMAT_12+#define TT_CONFIG_CMAP_FORMAT_13+#define TT_CONFIG_CMAP_FORMAT_14+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****    T R U E T Y P E   D R I V E R    C O N F I G U R A T I O N   ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */+  /* a bytecode interpreter in the TrueType driver.                        */+  /*                                                                       */+  /* By undefining this, you will only compile the code necessary to load  */+  /* TrueType glyphs without hinting.                                      */+  /*                                                                       */+  /*   Do not #undef this macro here, since the build system might         */+  /*   define it for certain configurations only.                          */+  /*                                                                       */+#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER+++  /*************************************************************************/+  /*                                                                       */+  /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version  */+  /* of the TrueType bytecode interpreter is used that doesn't implement   */+  /* any of the patented opcodes and algorithms.  The patents related to   */+  /* TrueType hinting have expired worldwide since May 2010; this option   */+  /* is now deprecated.                                                    */+  /*                                                                       */+  /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored*  */+  /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words,  */+  /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or                */+  /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time.    */+  /*                                                                       */+  /* This macro is only useful for a small number of font files (mostly    */+  /* for Asian scripts) that require bytecode interpretation to properly   */+  /* load glyphs.  For all other fonts, this produces unpleasant results,  */+  /* thus the unpatented interpreter is never used to load glyphs from     */+  /* TrueType fonts unless one of the following two options is used.       */+  /*                                                                       */+  /*   - The unpatented interpreter is explicitly activated by the user    */+  /*     through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag         */+  /*     when opening the FT_Face.                                         */+  /*                                                                       */+  /*   - FreeType detects that the FT_Face corresponds to one of the       */+  /*     `trick' fonts (e.g., `Mingliu') it knows about.  The font engine  */+  /*     contains a hard-coded list of font names and other matching       */+  /*     parameters (see function `tt_face_init' in file                   */+  /*     `src/truetype/ttobjs.c').                                         */+  /*                                                                       */+  /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */+  /*                                                                       */+  /*   {                                                                   */+  /*     FT_Parameter  parameter;                                          */+  /*     FT_Open_Args  open_args;                                          */+  /*                                                                       */+  /*                                                                       */+  /*     parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING;                  */+  /*                                                                       */+  /*     open_args.flags      = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;         */+  /*     open_args.pathname   = my_font_pathname;                          */+  /*     open_args.num_params = 1;                                         */+  /*     open_args.params     = &parameter;                                */+  /*                                                                       */+  /*     error = FT_Open_Face( library, &open_args, index, &face );        */+  /*     ...                                                               */+  /*   }                                                                   */+  /*                                                                       */+/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType    */+  /* bytecode interpreter with a huge switch statement, rather than a call */+  /* table.  This results in smaller and faster code for a number of       */+  /* architectures.                                                        */+  /*                                                                       */+  /* Note however that on some compiler/processor combinations, undefining */+  /* this macro will generate faster, though larger, code.                 */+  /*                                                                       */+#define TT_CONFIG_OPTION_INTERPRETER_SWITCH+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the        */+  /* TrueType glyph loader to use Apple's definition of how to handle      */+  /* component offsets in composite glyphs.                                */+  /*                                                                       */+  /* Apple and MS disagree on the default behavior of component offsets    */+  /* in composites.  Apple says that they should be scaled by the scaling  */+  /* factors in the transformation matrix (roughly, it's more complex)     */+  /* while MS says they should not.  OpenType defines two bits in the      */+  /* composite flags array which can be used to disambiguate, but old      */+  /* fonts will not have them.                                             */+  /*                                                                       */+  /*   http://partners.adobe.com/asn/developer/opentype/glyf.html          */+  /*   http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html                 */+  /*                                                                       */+#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include         */+  /* support for Apple's distortable font technology (fvar, gvar, cvar,    */+  /* and avar tables).  This has many similarities to Type 1 Multiple      */+  /* Masters support.                                                      */+  /*                                                                       */+#define TT_CONFIG_OPTION_GX_VAR_SUPPORT+++  /*************************************************************************/+  /*                                                                       */+  /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */+  /* an embedded `BDF ' table within SFNT-based bitmap formats.            */+  /*                                                                       */+#define TT_CONFIG_OPTION_BDF+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and       */+  /* arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is        */+  /* required.                                                             */+  /*                                                                       */+#define T1_MAX_DICT_DEPTH  5+++  /*************************************************************************/+  /*                                                                       */+  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */+  /* calls during glyph loading.                                           */+  /*                                                                       */+#define T1_MAX_SUBRS_CALLS  16+++  /*************************************************************************/+  /*                                                                       */+  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */+  /* minimum of 16 is required.                                            */+  /*                                                                       */+  /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */+  /*                                                                       */+#define T1_MAX_CHARSTRINGS_OPERANDS  256+++  /*************************************************************************/+  /*                                                                       */+  /* Define this configuration macro if you want to prevent the            */+  /* compilation of `t1afm', which is in charge of reading Type 1 AFM      */+  /* files into an existing face.  Note that if set, the T1 driver will be */+  /* unable to produce kerning distances.                                  */+  /*                                                                       */+#undef T1_CONFIG_OPTION_NO_AFM+++  /*************************************************************************/+  /*                                                                       */+  /* Define this configuration macro if you want to prevent the            */+  /* compilation of the Multiple Masters font support in the Type 1        */+  /* driver.                                                               */+  /*                                                                       */+#undef T1_CONFIG_OPTION_NO_MM_SUPPORT+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Compile autofit module with CJK (Chinese, Japanese, Korean) script    */+  /* support.                                                              */+  /*                                                                       */+#define AF_CONFIG_OPTION_CJK++  /*************************************************************************/+  /*                                                                       */+  /* Compile autofit module with Indic script support.                     */+  /*                                                                       */+#define AF_CONFIG_OPTION_INDIC++  /* */+++  /*+   * Define this variable if you want to keep the layout of internal+   * structures that was used prior to FreeType 2.2.  This also compiles in+   * a few obsolete functions to avoid linking problems on typical Unix+   * distributions.+   *+   * For embedded systems or building a new distribution from scratch, it+   * is recommended to disable the macro since it reduces the library's code+   * size and activates a few memory-saving optimizations as well.+   */+#define FT_CONFIG_OPTION_OLD_INTERNALS+++  /*+   *  To detect legacy cache-lookup call from a rogue client (<= 2.1.7),+   *  we restrict the number of charmaps in a font.  The current API of+   *  FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API+   *  takes charcode only.  To determine the passed value is for cmap_index+   *  or charcode, the possible cmap_index is restricted not to exceed+   *  the minimum possible charcode by a rogue client.  It is also very+   *  unlikely that a rogue client is interested in Unicode values 0 to 15.+   *+   *  NOTE: The original threshold was 4 deduced from popular number of+   *        cmap subtables in UCS-4 TrueType fonts, but now it is not+   *        irregular for OpenType fonts to have more than 4 subtables,+   *        because variation selector subtables are available for Apple+   *        and Microsoft platforms.+   */++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+#define FT_MAX_CHARMAP_CACHEABLE 15+#endif+++  /*+   * This macro is defined if either unpatented or native TrueType+   * hinting is requested by the definitions above.+   */+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER+#define  TT_USE_BYTECODE_INTERPRETER+#undef   TT_CONFIG_OPTION_UNPATENTED_HINTING+#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING+#define  TT_USE_BYTECODE_INTERPRETER+#endif++FT_END_HEADER+++#endif /* __FTOPTION_H__ */+++/* END */
+ include/freetype/config/ftstdlib.h view
@@ -0,0 +1,173 @@+/***************************************************************************/+/*                                                                         */+/*  ftstdlib.h                                                             */+/*                                                                         */+/*    ANSI-specific library and header configuration file (specification   */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to group all #includes to the ANSI C library that   */+  /* FreeType normally requires.  It also defines macros to rename the     */+  /* standard functions within the FreeType source code.                   */+  /*                                                                       */+  /* Load a file which defines __FTSTDLIB_H__ before this one to override  */+  /* it.                                                                   */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTSTDLIB_H__+#define __FTSTDLIB_H__+++#include <stddef.h>++#define ft_ptrdiff_t  ptrdiff_t+++  /**********************************************************************/+  /*                                                                    */+  /*                           integer limits                           */+  /*                                                                    */+  /* UINT_MAX and ULONG_MAX are used to automatically compute the size  */+  /* of `int' and `long' in bytes at compile-time.  So far, this works  */+  /* for all platforms the library has been tested on.                  */+  /*                                                                    */+  /* Note that on the extremely rare platforms that do not provide      */+  /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some    */+  /* old Crays where `int' is 36 bits), we do not make any guarantee    */+  /* about the correct behaviour of FT2 with all fonts.                 */+  /*                                                                    */+  /* In these case, `ftconfig.h' will refuse to compile anyway with a   */+  /* message like `couldn't find 32-bit type' or something similar.     */+  /*                                                                    */+  /**********************************************************************/+++#include <limits.h>++#define FT_CHAR_BIT   CHAR_BIT+#define FT_INT_MAX    INT_MAX+#define FT_INT_MIN    INT_MIN+#define FT_UINT_MAX   UINT_MAX+#define FT_ULONG_MAX  ULONG_MAX+++  /**********************************************************************/+  /*                                                                    */+  /*                 character and string processing                    */+  /*                                                                    */+  /**********************************************************************/+++#include <string.h>++#define ft_memchr   memchr+#define ft_memcmp   memcmp+#define ft_memcpy   memcpy+#define ft_memmove  memmove+#define ft_memset   memset+#define ft_strcat   strcat+#define ft_strcmp   strcmp+#define ft_strcpy   strcpy+#define ft_strlen   strlen+#define ft_strncmp  strncmp+#define ft_strncpy  strncpy+#define ft_strrchr  strrchr+#define ft_strstr   strstr+++  /**********************************************************************/+  /*                                                                    */+  /*                           file handling                            */+  /*                                                                    */+  /**********************************************************************/+++#include <stdio.h>++#define FT_FILE     FILE+#define ft_fclose   fclose+#define ft_fopen    fopen+#define ft_fread    fread+#define ft_fseek    fseek+#define ft_ftell    ftell+#define ft_sprintf  sprintf+++  /**********************************************************************/+  /*                                                                    */+  /*                             sorting                                */+  /*                                                                    */+  /**********************************************************************/+++#include <stdlib.h>++#define ft_qsort  qsort+++  /**********************************************************************/+  /*                                                                    */+  /*                        memory allocation                           */+  /*                                                                    */+  /**********************************************************************/+++#define ft_scalloc   calloc+#define ft_sfree     free+#define ft_smalloc   malloc+#define ft_srealloc  realloc+++  /**********************************************************************/+  /*                                                                    */+  /*                          miscellaneous                             */+  /*                                                                    */+  /**********************************************************************/+++#define ft_atol   atol+#define ft_labs   labs+++  /**********************************************************************/+  /*                                                                    */+  /*                         execution control                          */+  /*                                                                    */+  /**********************************************************************/+++#include <setjmp.h>++#define ft_jmp_buf     jmp_buf  /* note: this cannot be a typedef since */+                                /*       jmp_buf is defined as a macro  */+                                /*       on certain platforms           */++#define ft_longjmp     longjmp+#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) )    /* same thing here */+++  /* the following is only used for debugging purposes, i.e., if */+  /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined    */++#include <stdarg.h>+++#endif /* __FTSTDLIB_H__ */+++/* END */
+ include/freetype/freetype.h view
@@ -0,0 +1,3919 @@+/***************************************************************************/+/*                                                                         */+/*  freetype.h                                                             */+/*                                                                         */+/*    FreeType high-level API and common types (specification only).       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef FT_FREETYPE_H+#error "`ft2build.h' hasn't been included yet!"+#error "Please always use macros to include FreeType header files."+#error "Example:"+#error "  #include <ft2build.h>"+#error "  #include FT_FREETYPE_H"+#endif+++#ifndef __FREETYPE_H__+#define __FREETYPE_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_ERRORS_H+#include FT_TYPES_H+++FT_BEGIN_HEADER++++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    user_allocation                                                    */+  /*                                                                       */+  /* <Title>                                                               */+  /*    User allocation                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    How client applications should allocate FreeType data structures.  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FreeType assumes that structures allocated by the user and passed  */+  /*    as arguments are zeroed out except for the actual data.  In other  */+  /*    words, it is recommended to use `calloc' (or variants of it)       */+  /*    instead of `malloc' for allocation.                                */+  /*                                                                       */+  /*************************************************************************/++++  /*************************************************************************/+  /*************************************************************************/+  /*                                                                       */+  /*                        B A S I C   T Y P E S                          */+  /*                                                                       */+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    base_interface                                                     */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Base Interface                                                     */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    The FreeType~2 base font interface.                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section describes the public high-level API of FreeType~2.    */+  /*                                                                       */+  /* <Order>                                                               */+  /*    FT_Library                                                         */+  /*    FT_Face                                                            */+  /*    FT_Size                                                            */+  /*    FT_GlyphSlot                                                       */+  /*    FT_CharMap                                                         */+  /*    FT_Encoding                                                        */+  /*                                                                       */+  /*    FT_FaceRec                                                         */+  /*                                                                       */+  /*    FT_FACE_FLAG_SCALABLE                                              */+  /*    FT_FACE_FLAG_FIXED_SIZES                                           */+  /*    FT_FACE_FLAG_FIXED_WIDTH                                           */+  /*    FT_FACE_FLAG_HORIZONTAL                                            */+  /*    FT_FACE_FLAG_VERTICAL                                              */+  /*    FT_FACE_FLAG_SFNT                                                  */+  /*    FT_FACE_FLAG_KERNING                                               */+  /*    FT_FACE_FLAG_MULTIPLE_MASTERS                                      */+  /*    FT_FACE_FLAG_GLYPH_NAMES                                           */+  /*    FT_FACE_FLAG_EXTERNAL_STREAM                                       */+  /*    FT_FACE_FLAG_FAST_GLYPHS                                           */+  /*    FT_FACE_FLAG_HINTER                                                */+  /*                                                                       */+  /*    FT_STYLE_FLAG_BOLD                                                 */+  /*    FT_STYLE_FLAG_ITALIC                                               */+  /*                                                                       */+  /*    FT_SizeRec                                                         */+  /*    FT_Size_Metrics                                                    */+  /*                                                                       */+  /*    FT_GlyphSlotRec                                                    */+  /*    FT_Glyph_Metrics                                                   */+  /*    FT_SubGlyph                                                        */+  /*                                                                       */+  /*    FT_Bitmap_Size                                                     */+  /*                                                                       */+  /*    FT_Init_FreeType                                                   */+  /*    FT_Done_FreeType                                                   */+  /*                                                                       */+  /*    FT_New_Face                                                        */+  /*    FT_Done_Face                                                       */+  /*    FT_New_Memory_Face                                                 */+  /*    FT_Open_Face                                                       */+  /*    FT_Open_Args                                                       */+  /*    FT_Parameter                                                       */+  /*    FT_Attach_File                                                     */+  /*    FT_Attach_Stream                                                   */+  /*                                                                       */+  /*    FT_Set_Char_Size                                                   */+  /*    FT_Set_Pixel_Sizes                                                 */+  /*    FT_Request_Size                                                    */+  /*    FT_Select_Size                                                     */+  /*    FT_Size_Request_Type                                               */+  /*    FT_Size_Request                                                    */+  /*    FT_Set_Transform                                                   */+  /*    FT_Load_Glyph                                                      */+  /*    FT_Get_Char_Index                                                  */+  /*    FT_Get_Name_Index                                                  */+  /*    FT_Load_Char                                                       */+  /*                                                                       */+  /*    FT_OPEN_MEMORY                                                     */+  /*    FT_OPEN_STREAM                                                     */+  /*    FT_OPEN_PATHNAME                                                   */+  /*    FT_OPEN_DRIVER                                                     */+  /*    FT_OPEN_PARAMS                                                     */+  /*                                                                       */+  /*    FT_LOAD_DEFAULT                                                    */+  /*    FT_LOAD_RENDER                                                     */+  /*    FT_LOAD_MONOCHROME                                                 */+  /*    FT_LOAD_LINEAR_DESIGN                                              */+  /*    FT_LOAD_NO_SCALE                                                   */+  /*    FT_LOAD_NO_HINTING                                                 */+  /*    FT_LOAD_NO_BITMAP                                                  */+  /*    FT_LOAD_CROP_BITMAP                                                */+  /*                                                                       */+  /*    FT_LOAD_VERTICAL_LAYOUT                                            */+  /*    FT_LOAD_IGNORE_TRANSFORM                                           */+  /*    FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH                                */+  /*    FT_LOAD_FORCE_AUTOHINT                                             */+  /*    FT_LOAD_NO_RECURSE                                                 */+  /*    FT_LOAD_PEDANTIC                                                   */+  /*                                                                       */+  /*    FT_LOAD_TARGET_NORMAL                                              */+  /*    FT_LOAD_TARGET_LIGHT                                               */+  /*    FT_LOAD_TARGET_MONO                                                */+  /*    FT_LOAD_TARGET_LCD                                                 */+  /*    FT_LOAD_TARGET_LCD_V                                               */+  /*                                                                       */+  /*    FT_Render_Glyph                                                    */+  /*    FT_Render_Mode                                                     */+  /*    FT_Get_Kerning                                                     */+  /*    FT_Kerning_Mode                                                    */+  /*    FT_Get_Track_Kerning                                               */+  /*    FT_Get_Glyph_Name                                                  */+  /*    FT_Get_Postscript_Name                                             */+  /*                                                                       */+  /*    FT_CharMapRec                                                      */+  /*    FT_Select_Charmap                                                  */+  /*    FT_Set_Charmap                                                     */+  /*    FT_Get_Charmap_Index                                               */+  /*                                                                       */+  /*    FT_FSTYPE_INSTALLABLE_EMBEDDING                                    */+  /*    FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING                             */+  /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING                              */+  /*    FT_FSTYPE_EDITABLE_EMBEDDING                                       */+  /*    FT_FSTYPE_NO_SUBSETTING                                            */+  /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY                                    */+  /*                                                                       */+  /*    FT_Get_FSType_Flags                                                */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Glyph_Metrics                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model the metrics of a single glyph.  The      */+  /*    values are expressed in 26.6 fractional pixel format; if the flag  */+  /*    @FT_LOAD_NO_SCALE has been used while loading the glyph, values    */+  /*    are expressed in font units instead.                               */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    width ::                                                           */+  /*      The glyph's width.                                               */+  /*                                                                       */+  /*    height ::                                                          */+  /*      The glyph's height.                                              */+  /*                                                                       */+  /*    horiBearingX ::                                                    */+  /*      Left side bearing for horizontal layout.                         */+  /*                                                                       */+  /*    horiBearingY ::                                                    */+  /*      Top side bearing for horizontal layout.                          */+  /*                                                                       */+  /*    horiAdvance ::                                                     */+  /*      Advance width for horizontal layout.                             */+  /*                                                                       */+  /*    vertBearingX ::                                                    */+  /*      Left side bearing for vertical layout.                           */+  /*                                                                       */+  /*    vertBearingY ::                                                    */+  /*      Top side bearing for vertical layout.                            */+  /*                                                                       */+  /*    vertAdvance ::                                                     */+  /*      Advance height for vertical layout.                              */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If not disabled with @FT_LOAD_NO_HINTING, the values represent     */+  /*    dimensions of the hinted glyph (in case hinting is applicable).    */+  /*                                                                       */+  typedef struct  FT_Glyph_Metrics_+  {+    FT_Pos  width;+    FT_Pos  height;++    FT_Pos  horiBearingX;+    FT_Pos  horiBearingY;+    FT_Pos  horiAdvance;++    FT_Pos  vertBearingX;+    FT_Pos  vertBearingY;+    FT_Pos  vertAdvance;++  } FT_Glyph_Metrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Bitmap_Size                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure models the metrics of a bitmap strike (i.e., a set  */+  /*    of glyphs for a given point size and resolution) in a bitmap font. */+  /*    It is used for the `available_sizes' field of @FT_Face.            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    height :: The vertical distance, in pixels, between two            */+  /*              consecutive baselines.  It is always positive.           */+  /*                                                                       */+  /*    width  :: The average width, in pixels, of all glyphs in the       */+  /*              strike.                                                  */+  /*                                                                       */+  /*    size   :: The nominal size of the strike in 26.6 fractional        */+  /*              points.  This field is not very useful.                  */+  /*                                                                       */+  /*    x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional   */+  /*              pixels.                                                  */+  /*                                                                       */+  /*    y_ppem :: The vertical ppem (nominal height) in 26.6 fractional    */+  /*              pixels.                                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Windows FNT:                                                       */+  /*      The nominal size given in a FNT font is not reliable.  Thus when */+  /*      the driver finds it incorrect, it sets `size' to some calculated */+  /*      values and sets `x_ppem' and `y_ppem' to the pixel width and     */+  /*      height given in the font, respectively.                          */+  /*                                                                       */+  /*    TrueType embedded bitmaps:                                         */+  /*      `size', `width', and `height' values are not contained in the    */+  /*      bitmap strike itself.  They are computed from the global font    */+  /*      parameters.                                                      */+  /*                                                                       */+  typedef struct  FT_Bitmap_Size_+  {+    FT_Short  height;+    FT_Short  width;++    FT_Pos    size;++    FT_Pos    x_ppem;+    FT_Pos    y_ppem;++  } FT_Bitmap_Size;+++  /*************************************************************************/+  /*************************************************************************/+  /*                                                                       */+  /*                     O B J E C T   C L A S S E S                       */+  /*                                                                       */+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Library                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a FreeType library instance.  Each `library' is        */+  /*    completely independent from the others; it is the `root' of a set  */+  /*    of objects like fonts, faces, sizes, etc.                          */+  /*                                                                       */+  /*    It also embeds a memory manager (see @FT_Memory), as well as a     */+  /*    scan-line converter object (see @FT_Raster).                       */+  /*                                                                       */+  /*    For multi-threading applications each thread should have its own   */+  /*    FT_Library object.                                                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Library objects are normally created by @FT_Init_FreeType, and     */+  /*    destroyed with @FT_Done_FreeType.                                  */+  /*                                                                       */+  typedef struct FT_LibraryRec_  *FT_Library;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Module                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given FreeType module object.  Each module can be a  */+  /*    font driver, a renderer, or anything else that provides services   */+  /*    to the formers.                                                    */+  /*                                                                       */+  typedef struct FT_ModuleRec_*  FT_Module;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Driver                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given FreeType font driver object.  Each font driver */+  /*    is a special module capable of creating faces from font files.     */+  /*                                                                       */+  typedef struct FT_DriverRec_*  FT_Driver;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Renderer                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given FreeType renderer.  A renderer is a special    */+  /*    module in charge of converting a glyph image to a bitmap, when     */+  /*    necessary.  Each renderer supports a given glyph image format, and */+  /*    one or more target surface depths.                                 */+  /*                                                                       */+  typedef struct FT_RendererRec_*  FT_Renderer;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Face                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given typographic face object.  A face object models */+  /*    a given typeface, in a given style.                                */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Each face object also owns a single @FT_GlyphSlot object, as well  */+  /*    as one or more @FT_Size objects.                                   */+  /*                                                                       */+  /*    Use @FT_New_Face or @FT_Open_Face to create a new face object from */+  /*    a given filepathname or a custom input stream.                     */+  /*                                                                       */+  /*    Use @FT_Done_Face to destroy it (along with its slot and sizes).   */+  /*                                                                       */+  /* <Also>                                                                */+  /*    See @FT_FaceRec for the publicly accessible fields of a given face */+  /*    object.                                                            */+  /*                                                                       */+  typedef struct FT_FaceRec_*  FT_Face;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Size                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an object used to model a face scaled to a given       */+  /*    character size.                                                    */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Each @FT_Face has an _active_ @FT_Size object that is used by      */+  /*    functions like @FT_Load_Glyph to determine the scaling             */+  /*    transformation which is used to load and hint glyphs and metrics.  */+  /*                                                                       */+  /*    You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes,                */+  /*    @FT_Request_Size or even @FT_Select_Size to change the content     */+  /*    (i.e., the scaling values) of the active @FT_Size.                 */+  /*                                                                       */+  /*    You can use @FT_New_Size to create additional size objects for a   */+  /*    given @FT_Face, but they won't be used by other functions until    */+  /*    you activate it through @FT_Activate_Size.  Only one size can be   */+  /*    activated at any given time per face.                              */+  /*                                                                       */+  /* <Also>                                                                */+  /*    See @FT_SizeRec for the publicly accessible fields of a given size */+  /*    object.                                                            */+  /*                                                                       */+  typedef struct FT_SizeRec_*  FT_Size;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_GlyphSlot                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given `glyph slot'.  A slot is a container where it  */+  /*    is possible to load any of the glyphs contained in its parent      */+  /*    face.                                                              */+  /*                                                                       */+  /*    In other words, each time you call @FT_Load_Glyph or               */+  /*    @FT_Load_Char, the slot's content is erased by the new glyph data, */+  /*    i.e., the glyph's metrics, its image (bitmap or outline), and      */+  /*    other control information.                                         */+  /*                                                                       */+  /* <Also>                                                                */+  /*    See @FT_GlyphSlotRec for the publicly accessible glyph fields.     */+  /*                                                                       */+  typedef struct FT_GlyphSlotRec_*  FT_GlyphSlot;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_CharMap                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a given character map.  A charmap is used to translate */+  /*    character codes in a given encoding into glyph indexes for its     */+  /*    parent's face.  Some font formats may provide several charmaps per */+  /*    font.                                                              */+  /*                                                                       */+  /*    Each face object owns zero or more charmaps, but only one of them  */+  /*    can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char.   */+  /*                                                                       */+  /*    The list of available charmaps in a face is available through the  */+  /*    `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec.   */+  /*                                                                       */+  /*    The currently active charmap is available as `face->charmap'.      */+  /*    You should call @FT_Set_Charmap to change it.                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    When a new face is created (either through @FT_New_Face or         */+  /*    @FT_Open_Face), the library looks for a Unicode charmap within     */+  /*    the list and automatically activates it.                           */+  /*                                                                       */+  /* <Also>                                                                */+  /*    See @FT_CharMapRec for the publicly accessible fields of a given   */+  /*    character map.                                                     */+  /*                                                                       */+  typedef struct FT_CharMapRec_*  FT_CharMap;+++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_ENC_TAG                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro converts four-letter tags into an unsigned long.  It is */+  /*    used to define `encoding' identifiers (see @FT_Encoding).          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Since many 16-bit compilers don't like 32-bit enumerations, you    */+  /*    should redefine this macro in case of problems to something like   */+  /*    this:                                                              */+  /*                                                                       */+  /*    {                                                                  */+  /*      #define FT_ENC_TAG( value, a, b, c, d )  value                   */+  /*    }                                                                  */+  /*                                                                       */+  /*    to get a simple enumeration without assigning special numbers.     */+  /*                                                                       */++#ifndef FT_ENC_TAG+#define FT_ENC_TAG( value, a, b, c, d )         \+          value = ( ( (FT_UInt32)(a) << 24 ) |  \+                    ( (FT_UInt32)(b) << 16 ) |  \+                    ( (FT_UInt32)(c) <<  8 ) |  \+                      (FT_UInt32)(d)         )++#endif /* FT_ENC_TAG */+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Encoding                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration used to specify character sets supported by         */+  /*    charmaps.  Used in the @FT_Select_Charmap API function.            */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Despite the name, this enumeration lists specific character        */+  /*    repertories (i.e., charsets), and not text encoding methods (e.g., */+  /*    UTF-8, UTF-16, etc.).                                              */+  /*                                                                       */+  /*    Other encodings might be defined in the future.                    */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_ENCODING_NONE ::                                                */+  /*      The encoding value~0 is reserved.                                */+  /*                                                                       */+  /*    FT_ENCODING_UNICODE ::                                             */+  /*      Corresponds to the Unicode character set.  This value covers     */+  /*      all versions of the Unicode repertoire, including ASCII and      */+  /*      Latin-1.  Most fonts include a Unicode charmap, but not all      */+  /*      of them.                                                         */+  /*                                                                       */+  /*      For example, if you want to access Unicode value U+1F028 (and    */+  /*      the font contains it), use value 0x1F028 as the input value for  */+  /*      @FT_Get_Char_Index.                                              */+  /*                                                                       */+  /*    FT_ENCODING_MS_SYMBOL ::                                           */+  /*      Corresponds to the Microsoft Symbol encoding, used to encode     */+  /*      mathematical symbols in the 32..255 character code range.  For   */+  /*      more information, see `http://www.ceviz.net/symbol.htm'.         */+  /*                                                                       */+  /*    FT_ENCODING_SJIS ::                                                */+  /*      Corresponds to Japanese SJIS encoding.  More info at             */+  /*      at `http://langsupport.japanreference.com/encoding.shtml'.       */+  /*      See note on multi-byte encodings below.                          */+  /*                                                                       */+  /*    FT_ENCODING_GB2312 ::                                              */+  /*      Corresponds to an encoding system for Simplified Chinese as used */+  /*      used in mainland China.                                          */+  /*                                                                       */+  /*    FT_ENCODING_BIG5 ::                                                */+  /*      Corresponds to an encoding system for Traditional Chinese as     */+  /*      used in Taiwan and Hong Kong.                                    */+  /*                                                                       */+  /*    FT_ENCODING_WANSUNG ::                                             */+  /*      Corresponds to the Korean encoding system known as Wansung.      */+  /*      For more information see                                         */+  /*      `http://www.microsoft.com/typography/unicode/949.txt'.           */+  /*                                                                       */+  /*    FT_ENCODING_JOHAB ::                                               */+  /*      The Korean standard character set (KS~C 5601-1992), which        */+  /*      corresponds to MS Windows code page 1361.  This character set    */+  /*      includes all possible Hangeul character combinations.            */+  /*                                                                       */+  /*    FT_ENCODING_ADOBE_LATIN_1 ::                                       */+  /*      Corresponds to a Latin-1 encoding as defined in a Type~1         */+  /*      PostScript font.  It is limited to 256 character codes.          */+  /*                                                                       */+  /*    FT_ENCODING_ADOBE_STANDARD ::                                      */+  /*      Corresponds to the Adobe Standard encoding, as found in Type~1,  */+  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */+  /*      codes.                                                           */+  /*                                                                       */+  /*    FT_ENCODING_ADOBE_EXPERT ::                                        */+  /*      Corresponds to the Adobe Expert encoding, as found in Type~1,    */+  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */+  /*      codes.                                                           */+  /*                                                                       */+  /*    FT_ENCODING_ADOBE_CUSTOM ::                                        */+  /*      Corresponds to a custom encoding, as found in Type~1, CFF, and   */+  /*      OpenType/CFF fonts.  It is limited to 256 character codes.       */+  /*                                                                       */+  /*    FT_ENCODING_APPLE_ROMAN ::                                         */+  /*      Corresponds to the 8-bit Apple roman encoding.  Many TrueType    */+  /*      and OpenType fonts contain a charmap for this encoding, since    */+  /*      older versions of Mac OS are able to use it.                     */+  /*                                                                       */+  /*    FT_ENCODING_OLD_LATIN_2 ::                                         */+  /*      This value is deprecated and was never used nor reported by      */+  /*      FreeType.  Don't use or test for it.                             */+  /*                                                                       */+  /*    FT_ENCODING_MS_SJIS ::                                             */+  /*      Same as FT_ENCODING_SJIS.  Deprecated.                           */+  /*                                                                       */+  /*    FT_ENCODING_MS_GB2312 ::                                           */+  /*      Same as FT_ENCODING_GB2312.  Deprecated.                         */+  /*                                                                       */+  /*    FT_ENCODING_MS_BIG5 ::                                             */+  /*      Same as FT_ENCODING_BIG5.  Deprecated.                           */+  /*                                                                       */+  /*    FT_ENCODING_MS_WANSUNG ::                                          */+  /*      Same as FT_ENCODING_WANSUNG.  Deprecated.                        */+  /*                                                                       */+  /*    FT_ENCODING_MS_JOHAB ::                                            */+  /*      Same as FT_ENCODING_JOHAB.  Deprecated.                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    By default, FreeType automatically synthesizes a Unicode charmap   */+  /*    for PostScript fonts, using their glyph names dictionaries.        */+  /*    However, it also reports the encodings defined explicitly in the   */+  /*    font file, for the cases when they are needed, with the Adobe      */+  /*    values as well.                                                    */+  /*                                                                       */+  /*    FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap  */+  /*    is neither Unicode nor ISO-8859-1 (otherwise it is set to          */+  /*    FT_ENCODING_UNICODE).  Use @FT_Get_BDF_Charset_ID to find out      */+  /*    which encoding is really present.  If, for example, the            */+  /*    `cs_registry' field is `KOI8' and the `cs_encoding' field is `R',  */+  /*    the font is encoded in KOI8-R.                                     */+  /*                                                                       */+  /*    FT_ENCODING_NONE is always set (with a single exception) by the    */+  /*    winfonts driver.  Use @FT_Get_WinFNT_Header and examine the        */+  /*    `charset' field of the @FT_WinFNT_HeaderRec structure to find out  */+  /*    which encoding is really present.  For example,                    */+  /*    @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for       */+  /*    Russian).                                                          */+  /*                                                                       */+  /*    FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */+  /*    and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to  */+  /*    FT_ENCODING_APPLE_ROMAN).                                          */+  /*                                                                       */+  /*    If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function       */+  /*    @FT_Get_CMap_Language_ID  to query the Mac language ID which may   */+  /*    be needed to be able to distinguish Apple encoding variants.  See  */+  /*                                                                       */+  /*      http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT  */+  /*                                                                       */+  /*    to get an idea how to do that.  Basically, if the language ID      */+  /*    is~0, don't use it, otherwise subtract 1 from the language ID.     */+  /*    Then examine `encoding_id'.  If, for example, `encoding_id' is     */+  /*    @TT_MAC_ID_ROMAN and the language ID (minus~1) is                  */+  /*    `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman.        */+  /*    @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi       */+  /*    variant the Arabic encoding.                                       */+  /*                                                                       */+  typedef enum  FT_Encoding_+  {+    FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ),++    FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),+    FT_ENC_TAG( FT_ENCODING_UNICODE,   'u', 'n', 'i', 'c' ),++    FT_ENC_TAG( FT_ENCODING_SJIS,    's', 'j', 'i', 's' ),+    FT_ENC_TAG( FT_ENCODING_GB2312,  'g', 'b', ' ', ' ' ),+    FT_ENC_TAG( FT_ENCODING_BIG5,    'b', 'i', 'g', '5' ),+    FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ),+    FT_ENC_TAG( FT_ENCODING_JOHAB,   'j', 'o', 'h', 'a' ),++    /* for backwards compatibility */+    FT_ENCODING_MS_SJIS    = FT_ENCODING_SJIS,+    FT_ENCODING_MS_GB2312  = FT_ENCODING_GB2312,+    FT_ENCODING_MS_BIG5    = FT_ENCODING_BIG5,+    FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG,+    FT_ENCODING_MS_JOHAB   = FT_ENCODING_JOHAB,++    FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ),+    FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT,   'A', 'D', 'B', 'E' ),+    FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM,   'A', 'D', 'B', 'C' ),+    FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1,  'l', 'a', 't', '1' ),++    FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ),++    FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' )++  } FT_Encoding;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    ft_encoding_xxx                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    These constants are deprecated; use the corresponding @FT_Encoding */+  /*    values instead.                                                    */+  /*                                                                       */+#define ft_encoding_none            FT_ENCODING_NONE+#define ft_encoding_unicode         FT_ENCODING_UNICODE+#define ft_encoding_symbol          FT_ENCODING_MS_SYMBOL+#define ft_encoding_latin_1         FT_ENCODING_ADOBE_LATIN_1+#define ft_encoding_latin_2         FT_ENCODING_OLD_LATIN_2+#define ft_encoding_sjis            FT_ENCODING_SJIS+#define ft_encoding_gb2312          FT_ENCODING_GB2312+#define ft_encoding_big5            FT_ENCODING_BIG5+#define ft_encoding_wansung         FT_ENCODING_WANSUNG+#define ft_encoding_johab           FT_ENCODING_JOHAB++#define ft_encoding_adobe_standard  FT_ENCODING_ADOBE_STANDARD+#define ft_encoding_adobe_expert    FT_ENCODING_ADOBE_EXPERT+#define ft_encoding_adobe_custom    FT_ENCODING_ADOBE_CUSTOM+#define ft_encoding_apple_roman     FT_ENCODING_APPLE_ROMAN+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_CharMapRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The base charmap structure.                                        */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    face        :: A handle to the parent face object.                 */+  /*                                                                       */+  /*    encoding    :: An @FT_Encoding tag identifying the charmap.  Use   */+  /*                   this with @FT_Select_Charmap.                       */+  /*                                                                       */+  /*    platform_id :: An ID number describing the platform for the        */+  /*                   following encoding ID.  This comes directly from    */+  /*                   the TrueType specification and should be emulated   */+  /*                   for other formats.                                  */+  /*                                                                       */+  /*    encoding_id :: A platform specific encoding number.  This also     */+  /*                   comes from the TrueType specification and should be */+  /*                   emulated similarly.                                 */+  /*                                                                       */+  typedef struct  FT_CharMapRec_+  {+    FT_Face      face;+    FT_Encoding  encoding;+    FT_UShort    platform_id;+    FT_UShort    encoding_id;++  } FT_CharMapRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*                                                                       */+  /*                 B A S E   O B J E C T   C L A S S E S                 */+  /*                                                                       */+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Face_Internal                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An opaque handle to an `FT_Face_InternalRec' structure, used to    */+  /*    model private data of a given @FT_Face object.                     */+  /*                                                                       */+  /*    This structure might change between releases of FreeType~2 and is  */+  /*    not generally available to client applications.                    */+  /*                                                                       */+  typedef struct FT_Face_InternalRec_*  FT_Face_Internal;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_FaceRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FreeType root face class structure.  A face object models a        */+  /*    typeface in a font file.                                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_faces           :: The number of faces in the font file.  Some */+  /*                           font formats can have multiple faces in     */+  /*                           a font file.                                */+  /*                                                                       */+  /*    face_index          :: The index of the face in the font file.  It */+  /*                           is set to~0 if there is only one face in    */+  /*                           the font file.                              */+  /*                                                                       */+  /*    face_flags          :: A set of bit flags that give important      */+  /*                           information about the face; see             */+  /*                           @FT_FACE_FLAG_XXX for the details.          */+  /*                                                                       */+  /*    style_flags         :: A set of bit flags indicating the style of  */+  /*                           the face; see @FT_STYLE_FLAG_XXX for the    */+  /*                           details.                                    */+  /*                                                                       */+  /*    num_glyphs          :: The number of glyphs in the face.  If the   */+  /*                           face is scalable and has sbits (see         */+  /*                           `num_fixed_sizes'), it is set to the number */+  /*                           of outline glyphs.                          */+  /*                                                                       */+  /*                           For CID-keyed fonts, this value gives the   */+  /*                           highest CID used in the font.               */+  /*                                                                       */+  /*    family_name         :: The face's family name.  This is an ASCII   */+  /*                           string, usually in English, which describes */+  /*                           the typeface's family (like `Times New      */+  /*                           Roman', `Bodoni', `Garamond', etc).  This   */+  /*                           is a least common denominator used to list  */+  /*                           fonts.  Some formats (TrueType & OpenType)  */+  /*                           provide localized and Unicode versions of   */+  /*                           this string.  Applications should use the   */+  /*                           format specific interface to access them.   */+  /*                           Can be NULL (e.g., in fonts embedded in a   */+  /*                           PDF file).                                  */+  /*                                                                       */+  /*    style_name          :: The face's style name.  This is an ASCII    */+  /*                           string, usually in English, which describes */+  /*                           the typeface's style (like `Italic',        */+  /*                           `Bold', `Condensed', etc).  Not all font    */+  /*                           formats provide a style name, so this field */+  /*                           is optional, and can be set to NULL.  As    */+  /*                           for `family_name', some formats provide     */+  /*                           localized and Unicode versions of this      */+  /*                           string.  Applications should use the format */+  /*                           specific interface to access them.          */+  /*                                                                       */+  /*    num_fixed_sizes     :: The number of bitmap strikes in the face.   */+  /*                           Even if the face is scalable, there might   */+  /*                           still be bitmap strikes, which are called   */+  /*                           `sbits' in that case.                       */+  /*                                                                       */+  /*    available_sizes     :: An array of @FT_Bitmap_Size for all bitmap  */+  /*                           strikes in the face.  It is set to NULL if  */+  /*                           there is no bitmap strike.                  */+  /*                                                                       */+  /*    num_charmaps        :: The number of charmaps in the face.         */+  /*                                                                       */+  /*    charmaps            :: An array of the charmaps of the face.       */+  /*                                                                       */+  /*    generic             :: A field reserved for client uses.  See the  */+  /*                           @FT_Generic type description.               */+  /*                                                                       */+  /*    bbox                :: The font bounding box.  Coordinates are     */+  /*                           expressed in font units (see                */+  /*                           `units_per_EM').  The box is large enough   */+  /*                           to contain any glyph from the font.  Thus,  */+  /*                           `bbox.yMax' can be seen as the `maximal     */+  /*                           ascender', and `bbox.yMin' as the `minimal  */+  /*                           descender'.  Only relevant for scalable     */+  /*                           formats.                                    */+  /*                                                                       */+  /*                           Note that the bounding box might be off by  */+  /*                           (at least) one pixel for hinted fonts.  See */+  /*                           @FT_Size_Metrics for further discussion.    */+  /*                                                                       */+  /*    units_per_EM        :: The number of font units per EM square for  */+  /*                           this face.  This is typically 2048 for      */+  /*                           TrueType fonts, and 1000 for Type~1 fonts.  */+  /*                           Only relevant for scalable formats.         */+  /*                                                                       */+  /*    ascender            :: The typographic ascender of the face,       */+  /*                           expressed in font units.  For font formats  */+  /*                           not having this information, it is set to   */+  /*                           `bbox.yMax'.  Only relevant for scalable    */+  /*                           formats.                                    */+  /*                                                                       */+  /*    descender           :: The typographic descender of the face,      */+  /*                           expressed in font units.  For font formats  */+  /*                           not having this information, it is set to   */+  /*                           `bbox.yMin'.  Note that this field is       */+  /*                           usually negative.  Only relevant for        */+  /*                           scalable formats.                           */+  /*                                                                       */+  /*    height              :: The height is the vertical distance         */+  /*                           between two consecutive baselines,          */+  /*                           expressed in font units.  It is always      */+  /*                           positive.  Only relevant for scalable       */+  /*                           formats.                                    */+  /*                                                                       */+  /*    max_advance_width   :: The maximal advance width, in font units,   */+  /*                           for all glyphs in this face.  This can be   */+  /*                           used to make word wrapping computations     */+  /*                           faster.  Only relevant for scalable         */+  /*                           formats.                                    */+  /*                                                                       */+  /*    max_advance_height  :: The maximal advance height, in font units,  */+  /*                           for all glyphs in this face.  This is only  */+  /*                           relevant for vertical layouts, and is set   */+  /*                           to `height' for fonts that do not provide   */+  /*                           vertical metrics.  Only relevant for        */+  /*                           scalable formats.                           */+  /*                                                                       */+  /*    underline_position  :: The position, in font units, of the         */+  /*                           underline line for this face.  It is the    */+  /*                           center of the underlining stem.  Only       */+  /*                           relevant for scalable formats.              */+  /*                                                                       */+  /*    underline_thickness :: The thickness, in font units, of the        */+  /*                           underline for this face.  Only relevant for */+  /*                           scalable formats.                           */+  /*                                                                       */+  /*    glyph               :: The face's associated glyph slot(s).        */+  /*                                                                       */+  /*    size                :: The current active size for this face.      */+  /*                                                                       */+  /*    charmap             :: The current active charmap for this face.   */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Fields may be changed after a call to @FT_Attach_File or           */+  /*    @FT_Attach_Stream.                                                 */+  /*                                                                       */+  typedef struct  FT_FaceRec_+  {+    FT_Long           num_faces;+    FT_Long           face_index;++    FT_Long           face_flags;+    FT_Long           style_flags;++    FT_Long           num_glyphs;++    FT_String*        family_name;+    FT_String*        style_name;++    FT_Int            num_fixed_sizes;+    FT_Bitmap_Size*   available_sizes;++    FT_Int            num_charmaps;+    FT_CharMap*       charmaps;++    FT_Generic        generic;++    /*# The following member variables (down to `underline_thickness') */+    /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */+    /*# for bitmap fonts.                                              */+    FT_BBox           bbox;++    FT_UShort         units_per_EM;+    FT_Short          ascender;+    FT_Short          descender;+    FT_Short          height;++    FT_Short          max_advance_width;+    FT_Short          max_advance_height;++    FT_Short          underline_position;+    FT_Short          underline_thickness;++    FT_GlyphSlot      glyph;+    FT_Size           size;+    FT_CharMap        charmap;++    /*@private begin */++    FT_Driver         driver;+    FT_Memory         memory;+    FT_Stream         stream;++    FT_ListRec        sizes_list;++    FT_Generic        autohint;+    void*             extensions;++    FT_Face_Internal  internal;++    /*@private end */++  } FT_FaceRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_FACE_FLAG_XXX                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit flags used in the `face_flags' field of the          */+  /*    @FT_FaceRec structure.  They inform client applications of         */+  /*    properties of the corresponding face.                              */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_FACE_FLAG_SCALABLE ::                                           */+  /*      Indicates that the face contains outline glyphs.  This doesn't   */+  /*      prevent bitmap strikes, i.e., a face can have both this and      */+  /*      and @FT_FACE_FLAG_FIXED_SIZES set.                               */+  /*                                                                       */+  /*    FT_FACE_FLAG_FIXED_SIZES ::                                        */+  /*      Indicates that the face contains bitmap strikes.  See also the   */+  /*      `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec.   */+  /*                                                                       */+  /*    FT_FACE_FLAG_FIXED_WIDTH ::                                        */+  /*      Indicates that the face contains fixed-width characters (like    */+  /*      Courier, Lucido, MonoType, etc.).                                */+  /*                                                                       */+  /*    FT_FACE_FLAG_SFNT ::                                               */+  /*      Indicates that the face uses the `sfnt' storage scheme.  For     */+  /*      now, this means TrueType and OpenType.                           */+  /*                                                                       */+  /*    FT_FACE_FLAG_HORIZONTAL ::                                         */+  /*      Indicates that the face contains horizontal glyph metrics.  This */+  /*      should be set for all common formats.                            */+  /*                                                                       */+  /*    FT_FACE_FLAG_VERTICAL ::                                           */+  /*      Indicates that the face contains vertical glyph metrics.  This   */+  /*      is only available in some formats, not all of them.              */+  /*                                                                       */+  /*    FT_FACE_FLAG_KERNING ::                                            */+  /*      Indicates that the face contains kerning information.  If set,   */+  /*      the kerning distance can be retrieved through the function       */+  /*      @FT_Get_Kerning.  Otherwise the function always return the       */+  /*      vector (0,0).  Note that FreeType doesn't handle kerning data    */+  /*      from the `GPOS' table (as present in some OpenType fonts).       */+  /*                                                                       */+  /*    FT_FACE_FLAG_FAST_GLYPHS ::                                        */+  /*      THIS FLAG IS DEPRECATED.  DO NOT USE OR TEST IT.                 */+  /*                                                                       */+  /*    FT_FACE_FLAG_MULTIPLE_MASTERS ::                                   */+  /*      Indicates that the font contains multiple masters and is capable */+  /*      of interpolating between them.  See the multiple-masters         */+  /*      specific API for details.                                        */+  /*                                                                       */+  /*    FT_FACE_FLAG_GLYPH_NAMES ::                                        */+  /*      Indicates that the font contains glyph names that can be         */+  /*      retrieved through @FT_Get_Glyph_Name.  Note that some TrueType   */+  /*      fonts contain broken glyph name tables.  Use the function        */+  /*      @FT_Has_PS_Glyph_Names when needed.                              */+  /*                                                                       */+  /*    FT_FACE_FLAG_EXTERNAL_STREAM ::                                    */+  /*      Used internally by FreeType to indicate that a face's stream was */+  /*      provided by the client application and should not be destroyed   */+  /*      when @FT_Done_Face is called.  Don't read or test this flag.     */+  /*                                                                       */+  /*    FT_FACE_FLAG_HINTER ::                                             */+  /*      Set if the font driver has a hinting machine of its own.  For    */+  /*      example, with TrueType fonts, it makes sense to use data from    */+  /*      the SFNT `gasp' table only if the native TrueType hinting engine */+  /*      (with the bytecode interpreter) is available and active.         */+  /*                                                                       */+  /*    FT_FACE_FLAG_CID_KEYED ::                                          */+  /*      Set if the font is CID-keyed.  In that case, the font is not     */+  /*      accessed by glyph indices but by CID values.  For subsetted      */+  /*      CID-keyed fonts this has the consequence that not all index      */+  /*      values are a valid argument to FT_Load_Glyph.  Only the CID      */+  /*      values for which corresponding glyphs in the subsetted font      */+  /*      exist make FT_Load_Glyph return successfully; in all other cases */+  /*      you get an `FT_Err_Invalid_Argument' error.                      */+  /*                                                                       */+  /*      Note that CID-keyed fonts which are in an SFNT wrapper don't     */+  /*      have this flag set since the glyphs are accessed in the normal   */+  /*      way (using contiguous indices); the `CID-ness' isn't visible to  */+  /*      the application.                                                 */+  /*                                                                       */+  /*    FT_FACE_FLAG_TRICKY ::                                             */+  /*      Set if the font is `tricky', this is, it always needs the        */+  /*      font format's native hinting engine to get a reasonable result.  */+  /*      A typical example is the Chinese font `mingli.ttf' which uses    */+  /*      TrueType bytecode instructions to move and scale all of its      */+  /*      subglyphs.                                                       */+  /*                                                                       */+  /*      It is not possible to autohint such fonts using                  */+  /*      @FT_LOAD_FORCE_AUTOHINT; it will also ignore                     */+  /*      @FT_LOAD_NO_HINTING.  You have to set both FT_LOAD_NO_HINTING    */+  /*      and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */+  /*      probably never want this except for demonstration purposes.      */+  /*                                                                       */+  /*      Currently, there are six TrueType fonts in the list of tricky    */+  /*      fonts; they are hard-coded in file `ttobjs.c'.                   */+  /*                                                                       */+#define FT_FACE_FLAG_SCALABLE          ( 1L <<  0 )+#define FT_FACE_FLAG_FIXED_SIZES       ( 1L <<  1 )+#define FT_FACE_FLAG_FIXED_WIDTH       ( 1L <<  2 )+#define FT_FACE_FLAG_SFNT              ( 1L <<  3 )+#define FT_FACE_FLAG_HORIZONTAL        ( 1L <<  4 )+#define FT_FACE_FLAG_VERTICAL          ( 1L <<  5 )+#define FT_FACE_FLAG_KERNING           ( 1L <<  6 )+#define FT_FACE_FLAG_FAST_GLYPHS       ( 1L <<  7 )+#define FT_FACE_FLAG_MULTIPLE_MASTERS  ( 1L <<  8 )+#define FT_FACE_FLAG_GLYPH_NAMES       ( 1L <<  9 )+#define FT_FACE_FLAG_EXTERNAL_STREAM   ( 1L << 10 )+#define FT_FACE_FLAG_HINTER            ( 1L << 11 )+#define FT_FACE_FLAG_CID_KEYED         ( 1L << 12 )+#define FT_FACE_FLAG_TRICKY            ( 1L << 13 )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_HORIZONTAL( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains+   *   horizontal metrics (this is true for all font formats though).+   *+   * @also:+   *   @FT_HAS_VERTICAL can be used to check for vertical metrics.+   *+   */+#define FT_HAS_HORIZONTAL( face ) \+          ( face->face_flags & FT_FACE_FLAG_HORIZONTAL )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_VERTICAL( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains vertical+   *   metrics.+   *+   */+#define FT_HAS_VERTICAL( face ) \+          ( face->face_flags & FT_FACE_FLAG_VERTICAL )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_KERNING( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains kerning+   *   data that can be accessed with @FT_Get_Kerning.+   *+   */+#define FT_HAS_KERNING( face ) \+          ( face->face_flags & FT_FACE_FLAG_KERNING )+++  /*************************************************************************+   *+   * @macro:+   *   FT_IS_SCALABLE( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains a scalable+   *   font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF,+   *   and PFR font formats.+   *+   */+#define FT_IS_SCALABLE( face ) \+          ( face->face_flags & FT_FACE_FLAG_SCALABLE )+++  /*************************************************************************+   *+   * @macro:+   *   FT_IS_SFNT( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains a font+   *   whose format is based on the SFNT storage scheme.  This usually+   *   means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded+   *   bitmap fonts.+   *+   *   If this macro is true, all functions defined in @FT_SFNT_NAMES_H and+   *   @FT_TRUETYPE_TABLES_H are available.+   *+   */+#define FT_IS_SFNT( face ) \+          ( face->face_flags & FT_FACE_FLAG_SFNT )+++  /*************************************************************************+   *+   * @macro:+   *   FT_IS_FIXED_WIDTH( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains a font face+   *   that contains fixed-width (or `monospace', `fixed-pitch', etc.)+   *   glyphs.+   *+   */+#define FT_IS_FIXED_WIDTH( face ) \+          ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_FIXED_SIZES( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains some+   *   embedded bitmaps.  See the `available_sizes' field of the+   *   @FT_FaceRec structure.+   *+   */+#define FT_HAS_FIXED_SIZES( face ) \+          ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_FAST_GLYPHS( face )+   *+   * @description:+   *   Deprecated.+   *+   */+#define FT_HAS_FAST_GLYPHS( face )  0+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_GLYPH_NAMES( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains some glyph+   *   names that can be accessed through @FT_Get_Glyph_Name.+   *+   */+#define FT_HAS_GLYPH_NAMES( face ) \+          ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES )+++  /*************************************************************************+   *+   * @macro:+   *   FT_HAS_MULTIPLE_MASTERS( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains some+   *   multiple masters.  The functions provided by @FT_MULTIPLE_MASTERS_H+   *   are then available to choose the exact design you want.+   *+   */+#define FT_HAS_MULTIPLE_MASTERS( face ) \+          ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )+++  /*************************************************************************+   *+   * @macro:+   *   FT_IS_CID_KEYED( face )+   *+   * @description:+   *   A macro that returns true whenever a face object contains a CID-keyed+   *   font.  See the discussion of @FT_FACE_FLAG_CID_KEYED for more+   *   details.+   *+   *   If this macro is true, all functions defined in @FT_CID_H are+   *   available.+   *+   */+#define FT_IS_CID_KEYED( face ) \+          ( face->face_flags & FT_FACE_FLAG_CID_KEYED )+++  /*************************************************************************+   *+   * @macro:+   *   FT_IS_TRICKY( face )+   *+   * @description:+   *   A macro that returns true whenever a face represents a `tricky' font.+   *   See the discussion of @FT_FACE_FLAG_TRICKY for more details.+   *+   */+#define FT_IS_TRICKY( face ) \+          ( face->face_flags & FT_FACE_FLAG_TRICKY )+++  /*************************************************************************/+  /*                                                                       */+  /* <Const>                                                               */+  /*    FT_STYLE_FLAG_XXX                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit-flags used to indicate the style of a given face.    */+  /*    These are used in the `style_flags' field of @FT_FaceRec.          */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_STYLE_FLAG_ITALIC ::                                            */+  /*      Indicates that a given face style is italic or oblique.          */+  /*                                                                       */+  /*    FT_STYLE_FLAG_BOLD ::                                              */+  /*      Indicates that a given face is bold.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The style information as provided by FreeType is very basic.  More */+  /*    details are beyond the scope and should be done on a higher level  */+  /*    (for example, by analyzing various fields of the `OS/2' table in   */+  /*    SFNT based fonts).                                                 */+  /*                                                                       */+#define FT_STYLE_FLAG_ITALIC  ( 1 << 0 )+#define FT_STYLE_FLAG_BOLD    ( 1 << 1 )+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Size_Internal                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An opaque handle to an `FT_Size_InternalRec' structure, used to    */+  /*    model private data of a given @FT_Size object.                     */+  /*                                                                       */+  typedef struct FT_Size_InternalRec_*  FT_Size_Internal;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Size_Metrics                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The size metrics structure gives the metrics of a size object.     */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    x_ppem       :: The width of the scaled EM square in pixels, hence */+  /*                    the term `ppem' (pixels per EM).  It is also       */+  /*                    referred to as `nominal width'.                    */+  /*                                                                       */+  /*    y_ppem       :: The height of the scaled EM square in pixels,      */+  /*                    hence the term `ppem' (pixels per EM).  It is also */+  /*                    referred to as `nominal height'.                   */+  /*                                                                       */+  /*    x_scale      :: A 16.16 fractional scaling value used to convert   */+  /*                    horizontal metrics from font units to 26.6         */+  /*                    fractional pixels.  Only relevant for scalable     */+  /*                    font formats.                                      */+  /*                                                                       */+  /*    y_scale      :: A 16.16 fractional scaling value used to convert   */+  /*                    vertical metrics from font units to 26.6           */+  /*                    fractional pixels.  Only relevant for scalable     */+  /*                    font formats.                                      */+  /*                                                                       */+  /*    ascender     :: The ascender in 26.6 fractional pixels.  See       */+  /*                    @FT_FaceRec for the details.                       */+  /*                                                                       */+  /*    descender    :: The descender in 26.6 fractional pixels.  See      */+  /*                    @FT_FaceRec for the details.                       */+  /*                                                                       */+  /*    height       :: The height in 26.6 fractional pixels.  See         */+  /*                    @FT_FaceRec for the details.                       */+  /*                                                                       */+  /*    max_advance  :: The maximal advance width in 26.6 fractional       */+  /*                    pixels.  See @FT_FaceRec for the details.          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The scaling values, if relevant, are determined first during a     */+  /*    size changing operation.  The remaining fields are then set by the */+  /*    driver.  For scalable formats, they are usually set to scaled      */+  /*    values of the corresponding fields in @FT_FaceRec.                 */+  /*                                                                       */+  /*    Note that due to glyph hinting, these values might not be exact    */+  /*    for certain fonts.  Thus they must be treated as unreliable        */+  /*    with an error margin of at least one pixel!                        */+  /*                                                                       */+  /*    Indeed, the only way to get the exact metrics is to render _all_   */+  /*    glyphs.  As this would be a definite performance hit, it is up to  */+  /*    client applications to perform such computations.                  */+  /*                                                                       */+  /*    The FT_Size_Metrics structure is valid for bitmap fonts also.      */+  /*                                                                       */+  typedef struct  FT_Size_Metrics_+  {+    FT_UShort  x_ppem;      /* horizontal pixels per EM               */+    FT_UShort  y_ppem;      /* vertical pixels per EM                 */++    FT_Fixed   x_scale;     /* scaling values used to convert font    */+    FT_Fixed   y_scale;     /* units to 26.6 fractional pixels        */++    FT_Pos     ascender;    /* ascender in 26.6 frac. pixels          */+    FT_Pos     descender;   /* descender in 26.6 frac. pixels         */+    FT_Pos     height;      /* text height in 26.6 frac. pixels       */+    FT_Pos     max_advance; /* max horizontal advance, in 26.6 pixels */++  } FT_Size_Metrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_SizeRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FreeType root size class structure.  A size object models a face   */+  /*    object at a given size.                                            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    face    :: Handle to the parent face object.                       */+  /*                                                                       */+  /*    generic :: A typeless pointer, which is unused by the FreeType     */+  /*               library or any of its drivers.  It can be used by       */+  /*               client applications to link their own data to each size */+  /*               object.                                                 */+  /*                                                                       */+  /*    metrics :: Metrics for this size object.  This field is read-only. */+  /*                                                                       */+  typedef struct  FT_SizeRec_+  {+    FT_Face           face;      /* parent face object              */+    FT_Generic        generic;   /* generic pointer for client uses */+    FT_Size_Metrics   metrics;   /* size metrics                    */+    FT_Size_Internal  internal;++  } FT_SizeRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_SubGlyph                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The subglyph structure is an internal object used to describe      */+  /*    subglyphs (for example, in the case of composites).                */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The subglyph implementation is not part of the high-level API,     */+  /*    hence the forward structure declaration.                           */+  /*                                                                       */+  /*    You can however retrieve subglyph information with                 */+  /*    @FT_Get_SubGlyph_Info.                                             */+  /*                                                                       */+  typedef struct FT_SubGlyphRec_*  FT_SubGlyph;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Slot_Internal                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An opaque handle to an `FT_Slot_InternalRec' structure, used to    */+  /*    model private data of a given @FT_GlyphSlot object.                */+  /*                                                                       */+  typedef struct FT_Slot_InternalRec_*  FT_Slot_Internal;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_GlyphSlotRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FreeType root glyph slot class structure.  A glyph slot is a       */+  /*    container where individual glyphs can be loaded, be they in        */+  /*    outline or bitmap format.                                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    library           :: A handle to the FreeType library instance     */+  /*                         this slot belongs to.                         */+  /*                                                                       */+  /*    face              :: A handle to the parent face object.           */+  /*                                                                       */+  /*    next              :: In some cases (like some font tools), several */+  /*                         glyph slots per face object can be a good     */+  /*                         thing.  As this is rare, the glyph slots are  */+  /*                         listed through a direct, single-linked list   */+  /*                         using its `next' field.                       */+  /*                                                                       */+  /*    generic           :: A typeless pointer which is unused by the     */+  /*                         FreeType library or any of its drivers.  It   */+  /*                         can be used by client applications to link    */+  /*                         their own data to each glyph slot object.     */+  /*                                                                       */+  /*    metrics           :: The metrics of the last loaded glyph in the   */+  /*                         slot.  The returned values depend on the last */+  /*                         load flags (see the @FT_Load_Glyph API        */+  /*                         function) and can be expressed either in 26.6 */+  /*                         fractional pixels or font units.              */+  /*                                                                       */+  /*                         Note that even when the glyph image is        */+  /*                         transformed, the metrics are not.             */+  /*                                                                       */+  /*    linearHoriAdvance :: The advance width of the unhinted glyph.      */+  /*                         Its value is expressed in 16.16 fractional    */+  /*                         pixels, unless @FT_LOAD_LINEAR_DESIGN is set  */+  /*                         when loading the glyph.  This field can be    */+  /*                         important to perform correct WYSIWYG layout.  */+  /*                         Only relevant for outline glyphs.             */+  /*                                                                       */+  /*    linearVertAdvance :: The advance height of the unhinted glyph.     */+  /*                         Its value is expressed in 16.16 fractional    */+  /*                         pixels, unless @FT_LOAD_LINEAR_DESIGN is set  */+  /*                         when loading the glyph.  This field can be    */+  /*                         important to perform correct WYSIWYG layout.  */+  /*                         Only relevant for outline glyphs.             */+  /*                                                                       */+  /*    advance           :: This shorthand is, depending on               */+  /*                         @FT_LOAD_IGNORE_TRANSFORM, the transformed    */+  /*                         advance width for the glyph (in 26.6          */+  /*                         fractional pixel format).  As specified with  */+  /*                         @FT_LOAD_VERTICAL_LAYOUT, it uses either the  */+  /*                         `horiAdvance' or the `vertAdvance' value of   */+  /*                         `metrics' field.                              */+  /*                                                                       */+  /*    format            :: This field indicates the format of the image  */+  /*                         contained in the glyph slot.  Typically       */+  /*                         @FT_GLYPH_FORMAT_BITMAP,                      */+  /*                         @FT_GLYPH_FORMAT_OUTLINE, or                  */+  /*                         @FT_GLYPH_FORMAT_COMPOSITE, but others are    */+  /*                         possible.                                     */+  /*                                                                       */+  /*    bitmap            :: This field is used as a bitmap descriptor     */+  /*                         when the slot format is                       */+  /*                         @FT_GLYPH_FORMAT_BITMAP.  Note that the       */+  /*                         address and content of the bitmap buffer can  */+  /*                         change between calls of @FT_Load_Glyph and a  */+  /*                         few other functions.                          */+  /*                                                                       */+  /*    bitmap_left       :: This is the bitmap's left bearing expressed   */+  /*                         in integer pixels.  Of course, this is only   */+  /*                         valid if the format is                        */+  /*                         @FT_GLYPH_FORMAT_BITMAP.                      */+  /*                                                                       */+  /*    bitmap_top        :: This is the bitmap's top bearing expressed in */+  /*                         integer pixels.  Remember that this is the    */+  /*                         distance from the baseline to the top-most    */+  /*                         glyph scanline, upwards y~coordinates being   */+  /*                         *positive*.                                   */+  /*                                                                       */+  /*    outline           :: The outline descriptor for the current glyph  */+  /*                         image if its format is                        */+  /*                         @FT_GLYPH_FORMAT_OUTLINE.  Once a glyph is    */+  /*                         loaded, `outline' can be transformed,         */+  /*                         distorted, embolded, etc.  However, it must   */+  /*                         not be freed.                                 */+  /*                                                                       */+  /*    num_subglyphs     :: The number of subglyphs in a composite glyph. */+  /*                         This field is only valid for the composite    */+  /*                         glyph format that should normally only be     */+  /*                         loaded with the @FT_LOAD_NO_RECURSE flag.     */+  /*                         For now this is internal to FreeType.         */+  /*                                                                       */+  /*    subglyphs         :: An array of subglyph descriptors for          */+  /*                         composite glyphs.  There are `num_subglyphs'  */+  /*                         elements in there.  Currently internal to     */+  /*                         FreeType.                                     */+  /*                                                                       */+  /*    control_data      :: Certain font drivers can also return the      */+  /*                         control data for a given glyph image (e.g.    */+  /*                         TrueType bytecode, Type~1 charstrings, etc.). */+  /*                         This field is a pointer to such data.         */+  /*                                                                       */+  /*    control_len       :: This is the length in bytes of the control    */+  /*                         data.                                         */+  /*                                                                       */+  /*    other             :: Really wicked formats can use this pointer to */+  /*                         present their own glyph image to client       */+  /*                         applications.  Note that the application      */+  /*                         needs to know about the image format.         */+  /*                                                                       */+  /*    lsb_delta         :: The difference between hinted and unhinted    */+  /*                         left side bearing while autohinting is        */+  /*                         active.  Zero otherwise.                      */+  /*                                                                       */+  /*    rsb_delta         :: The difference between hinted and unhinted    */+  /*                         right side bearing while autohinting is       */+  /*                         active.  Zero otherwise.                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If @FT_Load_Glyph is called with default flags (see                */+  /*    @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in   */+  /*    its native format (e.g., an outline glyph for TrueType and Type~1  */+  /*    formats).                                                          */+  /*                                                                       */+  /*    This image can later be converted into a bitmap by calling         */+  /*    @FT_Render_Glyph.  This function finds the current renderer for    */+  /*    the native image's format, then invokes it.                        */+  /*                                                                       */+  /*    The renderer is in charge of transforming the native image through */+  /*    the slot's face transformation fields, then converting it into a   */+  /*    bitmap that is returned in `slot->bitmap'.                         */+  /*                                                                       */+  /*    Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */+  /*    to specify the position of the bitmap relative to the current pen  */+  /*    position (e.g., coordinates (0,0) on the baseline).  Of course,    */+  /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Here a small pseudo code fragment which shows how to use           */+  /*    `lsb_delta' and `rsb_delta':                                       */+  /*                                                                       */+  /*    {                                                                  */+  /*      FT_Pos  origin_x       = 0;                                      */+  /*      FT_Pos  prev_rsb_delta = 0;                                      */+  /*                                                                       */+  /*                                                                       */+  /*      for all glyphs do                                                */+  /*        <compute kern between current and previous glyph and add it to */+  /*         `origin_x'>                                                   */+  /*                                                                       */+  /*        <load glyph with `FT_Load_Glyph'>                              */+  /*                                                                       */+  /*        if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 )           */+  /*          origin_x -= 64;                                              */+  /*        else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 )      */+  /*          origin_x += 64;                                              */+  /*                                                                       */+  /*        prev_rsb_delta = face->glyph->rsb_delta;                       */+  /*                                                                       */+  /*        <save glyph image, or render glyph, or ...>                    */+  /*                                                                       */+  /*        origin_x += face->glyph->advance.x;                            */+  /*      endfor                                                           */+  /*    }                                                                  */+  /*                                                                       */+  typedef struct  FT_GlyphSlotRec_+  {+    FT_Library        library;+    FT_Face           face;+    FT_GlyphSlot      next;+    FT_UInt           reserved;       /* retained for binary compatibility */+    FT_Generic        generic;++    FT_Glyph_Metrics  metrics;+    FT_Fixed          linearHoriAdvance;+    FT_Fixed          linearVertAdvance;+    FT_Vector         advance;++    FT_Glyph_Format   format;++    FT_Bitmap         bitmap;+    FT_Int            bitmap_left;+    FT_Int            bitmap_top;++    FT_Outline        outline;++    FT_UInt           num_subglyphs;+    FT_SubGlyph       subglyphs;++    void*             control_data;+    long              control_len;++    FT_Pos            lsb_delta;+    FT_Pos            rsb_delta;++    void*             other;++    FT_Slot_Internal  internal;++  } FT_GlyphSlotRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*                                                                       */+  /*                         F U N C T I O N S                             */+  /*                                                                       */+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Init_FreeType                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a new FreeType library object.  The set of modules      */+  /*    that are registered by this function is determined at build time.  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    alibrary :: A handle to a new library object.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    In case you want to provide your own memory allocating routines,   */+  /*    use @FT_New_Library instead, followed by a call to                 */+  /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module).  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Init_FreeType( FT_Library  *alibrary );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_FreeType                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy a given FreeType library object and all of its children,   */+  /*    including resources, drivers, faces, sizes, etc.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to the target library object.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Done_FreeType( FT_Library  library );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_OPEN_XXX                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit-field constants used within the `flags' field of the */+  /*    @FT_Open_Args structure.                                           */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_OPEN_MEMORY   :: This is a memory-based stream.                 */+  /*                                                                       */+  /*    FT_OPEN_STREAM   :: Copy the stream from the `stream' field.       */+  /*                                                                       */+  /*    FT_OPEN_PATHNAME :: Create a new input stream from a C~path        */+  /*                        name.                                          */+  /*                                                                       */+  /*    FT_OPEN_DRIVER   :: Use the `driver' field.                        */+  /*                                                                       */+  /*    FT_OPEN_PARAMS   :: Use the `num_params' and `params' fields.      */+  /*                                                                       */+  /*    ft_open_memory   :: Deprecated; use @FT_OPEN_MEMORY instead.       */+  /*                                                                       */+  /*    ft_open_stream   :: Deprecated; use @FT_OPEN_STREAM instead.       */+  /*                                                                       */+  /*    ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead.     */+  /*                                                                       */+  /*    ft_open_driver   :: Deprecated; use @FT_OPEN_DRIVER instead.       */+  /*                                                                       */+  /*    ft_open_params   :: Deprecated; use @FT_OPEN_PARAMS instead.       */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME'     */+  /*    flags are mutually exclusive.                                      */+  /*                                                                       */+#define FT_OPEN_MEMORY    0x1+#define FT_OPEN_STREAM    0x2+#define FT_OPEN_PATHNAME  0x4+#define FT_OPEN_DRIVER    0x8+#define FT_OPEN_PARAMS    0x10++#define ft_open_memory    FT_OPEN_MEMORY     /* deprecated */+#define ft_open_stream    FT_OPEN_STREAM     /* deprecated */+#define ft_open_pathname  FT_OPEN_PATHNAME   /* deprecated */+#define ft_open_driver    FT_OPEN_DRIVER     /* deprecated */+#define ft_open_params    FT_OPEN_PARAMS     /* deprecated */+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Parameter                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to pass more or less generic parameters to */+  /*    @FT_Open_Face.                                                     */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    tag  :: A four-byte identification tag.                            */+  /*                                                                       */+  /*    data :: A pointer to the parameter data.                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The ID and function of parameters are driver-specific.  See the    */+  /*    various FT_PARAM_TAG_XXX flags for more information.               */+  /*                                                                       */+  typedef struct  FT_Parameter_+  {+    FT_ULong    tag;+    FT_Pointer  data;++  } FT_Parameter;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Open_Args                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to indicate how to open a new font file or        */+  /*    stream.  A pointer to such a structure can be used as a parameter  */+  /*    for the functions @FT_Open_Face and @FT_Attach_Stream.             */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    flags       :: A set of bit flags indicating how to use the        */+  /*                   structure.                                          */+  /*                                                                       */+  /*    memory_base :: The first byte of the file in memory.               */+  /*                                                                       */+  /*    memory_size :: The size in bytes of the file in memory.            */+  /*                                                                       */+  /*    pathname    :: A pointer to an 8-bit file pathname.                */+  /*                                                                       */+  /*    stream      :: A handle to a source stream object.                 */+  /*                                                                       */+  /*    driver      :: This field is exclusively used by @FT_Open_Face;    */+  /*                   it simply specifies the font driver to use to open  */+  /*                   the face.  If set to~0, FreeType tries to load the  */+  /*                   face with each one of the drivers in its list.      */+  /*                                                                       */+  /*    num_params  :: The number of extra parameters.                     */+  /*                                                                       */+  /*    params      :: Extra parameters passed to the font driver when     */+  /*                   opening a new face.                                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream type is determined by the contents of `flags' which     */+  /*    are tested in the following order by @FT_Open_Face:                */+  /*                                                                       */+  /*    If the `FT_OPEN_MEMORY' bit is set, assume that this is a          */+  /*    memory file of `memory_size' bytes, located at `memory_address'.   */+  /*    The data are are not copied, and the client is responsible for     */+  /*    releasing and destroying them _after_ the corresponding call to    */+  /*    @FT_Done_Face.                                                     */+  /*                                                                       */+  /*    Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a       */+  /*    custom input stream `stream' is used.                              */+  /*                                                                       */+  /*    Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this  */+  /*    is a normal file and use `pathname' to open it.                    */+  /*                                                                       */+  /*    If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to    */+  /*    open the file with the driver whose handler is in `driver'.        */+  /*                                                                       */+  /*    If the `FT_OPEN_PARAMS' bit is set, the parameters given by        */+  /*    `num_params' and `params' is used.  They are ignored otherwise.    */+  /*                                                                       */+  /*    Ideally, both the `pathname' and `params' fields should be tagged  */+  /*    as `const'; this is missing for API backwards compatibility.  In   */+  /*    other words, applications should treat them as read-only.          */+  /*                                                                       */+  typedef struct  FT_Open_Args_+  {+    FT_UInt         flags;+    const FT_Byte*  memory_base;+    FT_Long         memory_size;+    FT_String*      pathname;+    FT_Stream       stream;+    FT_Module       driver;+    FT_Int          num_params;+    FT_Parameter*   params;++  } FT_Open_Args;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function calls @FT_Open_Face to open a font by its pathname.  */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    pathname   :: A path to the font file.                             */+  /*                                                                       */+  /*    face_index :: The index of the face within the font.  The first    */+  /*                  face has index~0.                                    */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.  If `face_index' is   */+  /*                  greater than or equal to zero, it must be non-NULL.  */+  /*                  See @FT_Open_Face for more details.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Face( FT_Library   library,+               const char*  filepathname,+               FT_Long      face_index,+               FT_Face     *aface );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Memory_Face                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function calls @FT_Open_Face to open a font which has been    */+  /*    loaded into memory.                                                */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    file_base  :: A pointer to the beginning of the font data.         */+  /*                                                                       */+  /*    file_size  :: The size of the memory chunk used by the font data.  */+  /*                                                                       */+  /*    face_index :: The index of the face within the font.  The first    */+  /*                  face has index~0.                                    */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.  If `face_index' is   */+  /*                  greater than or equal to zero, it must be non-NULL.  */+  /*                  See @FT_Open_Face for more details.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You must not deallocate the memory before calling @FT_Done_Face.   */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Memory_Face( FT_Library      library,+                      const FT_Byte*  file_base,+                      FT_Long         file_size,+                      FT_Long         face_index,+                      FT_Face        *aface );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Open_Face                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a face object from a given resource described by            */+  /*    @FT_Open_Args.                                                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    args       :: A pointer to an `FT_Open_Args' structure which must  */+  /*                  be filled by the caller.                             */+  /*                                                                       */+  /*    face_index :: The index of the face within the font.  The first    */+  /*                  face has index~0.                                    */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.  If `face_index' is   */+  /*                  greater than or equal to zero, it must be non-NULL.  */+  /*                  See note below.                                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Unlike FreeType 1.x, this function automatically creates a glyph   */+  /*    slot for the face object which can be accessed directly through    */+  /*    `face->glyph'.                                                     */+  /*                                                                       */+  /*    FT_Open_Face can be used to quickly check whether the font         */+  /*    format of a given font resource is supported by FreeType.  If the  */+  /*    `face_index' field is negative, the function's return value is~0   */+  /*    if the font format is recognized, or non-zero otherwise;           */+  /*    the function returns a more or less empty face handle in `*aface'  */+  /*    (if `aface' isn't NULL).  The only useful field in this special    */+  /*    case is `face->num_faces' which gives the number of faces within   */+  /*    the font file.  After examination, the returned @FT_Face structure */+  /*    should be deallocated with a call to @FT_Done_Face.                */+  /*                                                                       */+  /*    Each new face object created with this function also owns a        */+  /*    default @FT_Size object, accessible as `face->size'.               */+  /*                                                                       */+  /*    See the discussion of reference counters in the description of     */+  /*    @FT_Reference_Face.                                                */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Open_Face( FT_Library           library,+                const FT_Open_Args*  args,+                FT_Long              face_index,+                FT_Face             *aface );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Attach_File                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function calls @FT_Attach_Stream to attach a file.            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face         :: The target face object.                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    filepathname :: The pathname.                                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Attach_File( FT_Face      face,+                  const char*  filepathname );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Attach_Stream                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    `Attach' data to a face object.  Normally, this is used to read    */+  /*    additional information for the face object.  For example, you can  */+  /*    attach an AFM file that comes with a Type~1 font to get the        */+  /*    kerning values and other metrics.                                  */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The target face object.                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    parameters :: A pointer to @FT_Open_Args which must be filled by   */+  /*                  the caller.                                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The meaning of the `attach' (i.e., what really happens when the    */+  /*    new file is read) is not fixed by FreeType itself.  It really      */+  /*    depends on the font format (and thus the font driver).             */+  /*                                                                       */+  /*    Client applications are expected to know what they are doing       */+  /*    when invoking this function.  Most drivers simply do not implement */+  /*    file attachments.                                                  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Attach_Stream( FT_Face        face,+                    FT_Open_Args*  parameters );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Reference_Face                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A counter gets initialized to~1 at the time an @FT_Face structure  */+  /*    is created.  This function increments the counter.  @FT_Done_Face  */+  /*    then only destroys a face if the counter is~1, otherwise it simply */+  /*    decrements the counter.                                            */+  /*                                                                       */+  /*    This function helps in managing life-cycles of structures which    */+  /*    reference @FT_Face objects.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to a target face object.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.4.2                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Reference_Face( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_Face                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Discard a given face object, as well as all of its child slots and */+  /*    sizes.                                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to a target face object.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    See the discussion of reference counters in the description of     */+  /*    @FT_Reference_Face.                                                */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Done_Face( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Select_Size                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Select a bitmap strike.                                            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face         :: A handle to a target face object.                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    strike_index :: The index of the bitmap strike in the              */+  /*                    `available_sizes' field of @FT_FaceRec structure.  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Select_Size( FT_Face  face,+                  FT_Int   strike_index );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Size_Request_Type                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration type that lists the supported size request types.   */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_SIZE_REQUEST_TYPE_NOMINAL ::                                    */+  /*      The nominal size.  The `units_per_EM' field of @FT_FaceRec is    */+  /*      used to determine both scaling values.                           */+  /*                                                                       */+  /*    FT_SIZE_REQUEST_TYPE_REAL_DIM ::                                   */+  /*      The real dimension.  The sum of the the `Ascender' and (minus    */+  /*      of) the `Descender' fields of @FT_FaceRec are used to determine  */+  /*      both scaling values.                                             */+  /*                                                                       */+  /*    FT_SIZE_REQUEST_TYPE_BBOX ::                                       */+  /*      The font bounding box.  The width and height of the `bbox' field */+  /*      of @FT_FaceRec are used to determine the horizontal and vertical */+  /*      scaling value, respectively.                                     */+  /*                                                                       */+  /*    FT_SIZE_REQUEST_TYPE_CELL ::                                       */+  /*      The `max_advance_width' field of @FT_FaceRec is used to          */+  /*      determine the horizontal scaling value; the vertical scaling     */+  /*      value is determined the same way as                              */+  /*      @FT_SIZE_REQUEST_TYPE_REAL_DIM does.  Finally, both scaling      */+  /*      values are set to the smaller one.  This type is useful if you   */+  /*      want to specify the font size for, say, a window of a given      */+  /*      dimension and 80x24 cells.                                       */+  /*                                                                       */+  /*    FT_SIZE_REQUEST_TYPE_SCALES ::                                     */+  /*      Specify the scaling values directly.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The above descriptions only apply to scalable formats.  For bitmap */+  /*    formats, the behaviour is up to the driver.                        */+  /*                                                                       */+  /*    See the note section of @FT_Size_Metrics if you wonder how size    */+  /*    requesting relates to scaling values.                              */+  /*                                                                       */+  typedef enum  FT_Size_Request_Type_+  {+    FT_SIZE_REQUEST_TYPE_NOMINAL,+    FT_SIZE_REQUEST_TYPE_REAL_DIM,+    FT_SIZE_REQUEST_TYPE_BBOX,+    FT_SIZE_REQUEST_TYPE_CELL,+    FT_SIZE_REQUEST_TYPE_SCALES,++    FT_SIZE_REQUEST_TYPE_MAX++  } FT_Size_Request_Type;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Size_RequestRec                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a size request.                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    type           :: See @FT_Size_Request_Type.                       */+  /*                                                                       */+  /*    width          :: The desired width.                               */+  /*                                                                       */+  /*    height         :: The desired height.                              */+  /*                                                                       */+  /*    horiResolution :: The horizontal resolution.  If set to zero,      */+  /*                      `width' is treated as a 26.6 fractional pixel    */+  /*                      value.                                           */+  /*                                                                       */+  /*    vertResolution :: The vertical resolution.  If set to zero,        */+  /*                      `height' is treated as a 26.6 fractional pixel   */+  /*                      value.                                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If `width' is zero, then the horizontal scaling value is set equal */+  /*    to the vertical scaling value, and vice versa.                     */+  /*                                                                       */+  typedef struct  FT_Size_RequestRec_+  {+    FT_Size_Request_Type  type;+    FT_Long               width;+    FT_Long               height;+    FT_UInt               horiResolution;+    FT_UInt               vertResolution;++  } FT_Size_RequestRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Size_Request                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a size request structure.                              */+  /*                                                                       */+  typedef struct FT_Size_RequestRec_  *FT_Size_Request;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Request_Size                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Resize the scale of the active @FT_Size object in a face.          */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face :: A handle to a target face object.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    req  :: A pointer to a @FT_Size_RequestRec.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Although drivers may select the bitmap strike matching the         */+  /*    request, you should not rely on this if you intend to select a     */+  /*    particular bitmap strike.  Use @FT_Select_Size instead in that     */+  /*    case.                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Request_Size( FT_Face          face,+                   FT_Size_Request  req );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Char_Size                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function calls @FT_Request_Size to request the nominal size   */+  /*    (in points).                                                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face            :: A handle to a target face object.               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    char_width      :: The nominal width, in 26.6 fractional points.   */+  /*                                                                       */+  /*    char_height     :: The nominal height, in 26.6 fractional points.  */+  /*                                                                       */+  /*    horz_resolution :: The horizontal resolution in dpi.               */+  /*                                                                       */+  /*    vert_resolution :: The vertical resolution in dpi.                 */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If either the character width or height is zero, it is set equal   */+  /*    to the other value.                                                */+  /*                                                                       */+  /*    If either the horizontal or vertical resolution is zero, it is set */+  /*    equal to the other value.                                          */+  /*                                                                       */+  /*    A character width or height smaller than 1pt is set to 1pt; if     */+  /*    both resolution values are zero, they are set to 72dpi.            */+  /*                                                                       */+  /*    Don't use this function if you are using the FreeType cache API.   */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Char_Size( FT_Face     face,+                    FT_F26Dot6  char_width,+                    FT_F26Dot6  char_height,+                    FT_UInt     horz_resolution,+                    FT_UInt     vert_resolution );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Pixel_Sizes                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function calls @FT_Request_Size to request the nominal size   */+  /*    (in pixels).                                                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face         :: A handle to the target face object.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    pixel_width  :: The nominal width, in pixels.                      */+  /*                                                                       */+  /*    pixel_height :: The nominal height, in pixels.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Pixel_Sizes( FT_Face  face,+                      FT_UInt  pixel_width,+                      FT_UInt  pixel_height );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Load_Glyph                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to load a single glyph into the glyph slot of a    */+  /*    face object.                                                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face        :: A handle to the target face object where the glyph  */+  /*                   is loaded.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    glyph_index :: The index of the glyph in the font file.  For       */+  /*                   CID-keyed fonts (either in PS or in CFF format)     */+  /*                   this argument specifies the CID value.              */+  /*                                                                       */+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */+  /*                   @FT_LOAD_XXX constants can be used to control the   */+  /*                   glyph loading process (e.g., whether the outline    */+  /*                   should be scaled, whether to load bitmaps or not,   */+  /*                   whether to hint the outline, etc).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The loaded glyph may be transformed.  See @FT_Set_Transform for    */+  /*    the details.                                                       */+  /*                                                                       */+  /*    For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is        */+  /*    returned for invalid CID values (this is, for CID values which     */+  /*    don't have a corresponding glyph in the font).  See the discussion */+  /*    of the @FT_FACE_FLAG_CID_KEYED flag for more details.              */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Load_Glyph( FT_Face   face,+                 FT_UInt   glyph_index,+                 FT_Int32  load_flags );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Load_Char                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to load a single glyph into the glyph slot of a    */+  /*    face object, according to its character code.                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face        :: A handle to a target face object where the glyph    */+  /*                   is loaded.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    char_code   :: The glyph's character code, according to the        */+  /*                   current charmap used in the face.                   */+  /*                                                                       */+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */+  /*                   @FT_LOAD_XXX constants can be used to control the   */+  /*                   glyph loading process (e.g., whether the outline    */+  /*                   should be scaled, whether to load bitmaps or not,   */+  /*                   whether to hint the outline, etc).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph.  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Load_Char( FT_Face   face,+                FT_ULong  char_code,+                FT_Int32  load_flags );+++  /*************************************************************************+   *+   * @enum:+   *   FT_LOAD_XXX+   *+   * @description:+   *   A list of bit-field constants used with @FT_Load_Glyph to indicate+   *   what kind of operations to perform during glyph loading.+   *+   * @values:+   *   FT_LOAD_DEFAULT ::+   *     Corresponding to~0, this value is used as the default glyph load+   *     operation.  In this case, the following happens:+   *+   *     1. FreeType looks for a bitmap for the glyph corresponding to the+   *        face's current size.  If one is found, the function returns.+   *        The bitmap data can be accessed from the glyph slot (see note+   *        below).+   *+   *     2. If no embedded bitmap is searched or found, FreeType looks for a+   *        scalable outline.  If one is found, it is loaded from the font+   *        file, scaled to device pixels, then `hinted' to the pixel grid+   *        in order to optimize it.  The outline data can be accessed from+   *        the glyph slot (see note below).+   *+   *     Note that by default, the glyph loader doesn't render outlines into+   *     bitmaps.  The following flags are used to modify this default+   *     behaviour to more specific and useful cases.+   *+   *   FT_LOAD_NO_SCALE ::+   *     Don't scale the outline glyph loaded, but keep it in font units.+   *+   *     This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and+   *     unsets @FT_LOAD_RENDER.+   *+   *   FT_LOAD_NO_HINTING ::+   *     Disable hinting.  This generally generates `blurrier' bitmap glyph+   *     when the glyph is rendered in any of the anti-aliased modes.  See+   *     also the note below.+   *+   *     This flag is implied by @FT_LOAD_NO_SCALE.+   *+   *   FT_LOAD_RENDER ::+   *     Call @FT_Render_Glyph after the glyph is loaded.  By default, the+   *     glyph is rendered in @FT_RENDER_MODE_NORMAL mode.  This can be+   *     overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME.+   *+   *     This flag is unset by @FT_LOAD_NO_SCALE.+   *+   *   FT_LOAD_NO_BITMAP ::+   *     Ignore bitmap strikes when loading.  Bitmap-only fonts ignore this+   *     flag.+   *+   *     @FT_LOAD_NO_SCALE always sets this flag.+   *+   *   FT_LOAD_VERTICAL_LAYOUT ::+   *     Load the glyph for vertical text layout.  _Don't_ use it as it is+   *     problematic currently.+   *+   *   FT_LOAD_FORCE_AUTOHINT ::+   *     Indicates that the auto-hinter is preferred over the font's native+   *     hinter.  See also the note below.+   *+   *   FT_LOAD_CROP_BITMAP ::+   *     Indicates that the font driver should crop the loaded bitmap glyph+   *     (i.e., remove all space around its black bits).  Not all drivers+   *     implement this.+   *+   *   FT_LOAD_PEDANTIC ::+   *     Indicates that the font driver should perform pedantic verifications+   *     during glyph loading.  This is mostly used to detect broken glyphs+   *     in fonts.  By default, FreeType tries to handle broken fonts also.+   *+   *   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::+   *     Indicates that the font driver should ignore the global advance+   *     width defined in the font.  By default, that value is used as the+   *     advance width for all glyphs when the face has+   *     @FT_FACE_FLAG_FIXED_WIDTH set.+   *+   *     This flag exists for historical reasons (to support buggy CJK+   *     fonts).+   *+   *   FT_LOAD_NO_RECURSE ::+   *     This flag is only used internally.  It merely indicates that the+   *     font driver should not load composite glyphs recursively.  Instead,+   *     it should set the `num_subglyph' and `subglyphs' values of the+   *     glyph slot accordingly, and set `glyph->format' to+   *     @FT_GLYPH_FORMAT_COMPOSITE.+   *+   *     The description of sub-glyphs is not available to client+   *     applications for now.+   *+   *     This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.+   *+   *   FT_LOAD_IGNORE_TRANSFORM ::+   *     Indicates that the transform matrix set by @FT_Set_Transform should+   *     be ignored.+   *+   *   FT_LOAD_MONOCHROME ::+   *     This flag is used with @FT_LOAD_RENDER to indicate that you want to+   *     render an outline glyph to a 1-bit monochrome bitmap glyph, with+   *     8~pixels packed into each byte of the bitmap data.+   *+   *     Note that this has no effect on the hinting algorithm used.  You+   *     should rather use @FT_LOAD_TARGET_MONO so that the+   *     monochrome-optimized hinting algorithm is used.+   *+   *   FT_LOAD_LINEAR_DESIGN ::+   *     Indicates that the `linearHoriAdvance' and `linearVertAdvance'+   *     fields of @FT_GlyphSlotRec should be kept in font units.  See+   *     @FT_GlyphSlotRec for details.+   *+   *   FT_LOAD_NO_AUTOHINT ::+   *     Disable auto-hinter.  See also the note below.+   *+   * @note:+   *   By default, hinting is enabled and the font's native hinter (see+   *   @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter.  You can+   *   disable hinting by setting @FT_LOAD_NO_HINTING or change the+   *   precedence by setting @FT_LOAD_FORCE_AUTOHINT.  You can also set+   *   @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be+   *   used at all.+   *+   *   See the description of @FT_FACE_FLAG_TRICKY for a special exception+   *   (affecting only a handful of Asian fonts).+   *+   *   Besides deciding which hinter to use, you can also decide which+   *   hinting algorithm to use.  See @FT_LOAD_TARGET_XXX for details.+   *+   */+#define FT_LOAD_DEFAULT                      0x0+#define FT_LOAD_NO_SCALE                     0x1+#define FT_LOAD_NO_HINTING                   0x2+#define FT_LOAD_RENDER                       0x4+#define FT_LOAD_NO_BITMAP                    0x8+#define FT_LOAD_VERTICAL_LAYOUT              0x10+#define FT_LOAD_FORCE_AUTOHINT               0x20+#define FT_LOAD_CROP_BITMAP                  0x40+#define FT_LOAD_PEDANTIC                     0x80+#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH  0x200+#define FT_LOAD_NO_RECURSE                   0x400+#define FT_LOAD_IGNORE_TRANSFORM             0x800+#define FT_LOAD_MONOCHROME                   0x1000+#define FT_LOAD_LINEAR_DESIGN                0x2000+#define FT_LOAD_NO_AUTOHINT                  0x8000U++  /* */++  /* used internally only by certain font drivers! */+#define FT_LOAD_ADVANCE_ONLY                 0x100+#define FT_LOAD_SBITS_ONLY                   0x4000+++  /**************************************************************************+   *+   * @enum:+   *   FT_LOAD_TARGET_XXX+   *+   * @description:+   *   A list of values that are used to select a specific hinting algorithm+   *   to use by the hinter.  You should OR one of these values to your+   *   `load_flags' when calling @FT_Load_Glyph.+   *+   *   Note that font's native hinters may ignore the hinting algorithm you+   *   have specified (e.g., the TrueType bytecode interpreter).  You can set+   *   @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.+   *+   *   Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it+   *   always implies @FT_LOAD_FORCE_AUTOHINT.+   *+   * @values:+   *   FT_LOAD_TARGET_NORMAL ::+   *     This corresponds to the default hinting algorithm, optimized for+   *     standard gray-level rendering.  For monochrome output, use+   *     @FT_LOAD_TARGET_MONO instead.+   *+   *   FT_LOAD_TARGET_LIGHT ::+   *     A lighter hinting algorithm for non-monochrome modes.  Many+   *     generated glyphs are more fuzzy but better resemble its original+   *     shape.  A bit like rendering on Mac OS~X.+   *+   *     As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT.+   *+   *   FT_LOAD_TARGET_MONO ::+   *     Strong hinting algorithm that should only be used for monochrome+   *     output.  The result is probably unpleasant if the glyph is rendered+   *     in non-monochrome modes.+   *+   *   FT_LOAD_TARGET_LCD ::+   *     A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally+   *     decimated LCD displays.+   *+   *   FT_LOAD_TARGET_LCD_V ::+   *     A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically+   *     decimated LCD displays.+   *+   * @note:+   *   You should use only _one_ of the FT_LOAD_TARGET_XXX values in your+   *   `load_flags'.  They can't be ORed.+   *+   *   If @FT_LOAD_RENDER is also set, the glyph is rendered in the+   *   corresponding mode (i.e., the mode which matches the used algorithm+   *   best) unless @FT_LOAD_MONOCHROME is set.+   *+   *   You can use a hinting algorithm that doesn't correspond to the same+   *   rendering mode.  As an example, it is possible to use the `light'+   *   hinting algorithm and have the results rendered in horizontal LCD+   *   pixel mode, with code like+   *+   *     {+   *       FT_Load_Glyph( face, glyph_index,+   *                      load_flags | FT_LOAD_TARGET_LIGHT );+   *+   *       FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD );+   *     }+   *+   */+#define FT_LOAD_TARGET_( x )   ( (FT_Int32)( (x) & 15 ) << 16 )++#define FT_LOAD_TARGET_NORMAL  FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )+#define FT_LOAD_TARGET_LIGHT   FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT  )+#define FT_LOAD_TARGET_MONO    FT_LOAD_TARGET_( FT_RENDER_MODE_MONO   )+#define FT_LOAD_TARGET_LCD     FT_LOAD_TARGET_( FT_RENDER_MODE_LCD    )+#define FT_LOAD_TARGET_LCD_V   FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V  )+++  /**************************************************************************+   *+   * @macro:+   *   FT_LOAD_TARGET_MODE+   *+   * @description:+   *   Return the @FT_Render_Mode corresponding to a given+   *   @FT_LOAD_TARGET_XXX value.+   *+   */+#define FT_LOAD_TARGET_MODE( x )  ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Transform                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to set the transformation that is applied to glyph */+  /*    images when they are loaded into a glyph slot through              */+  /*    @FT_Load_Glyph.                                                    */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the source face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use~0 for */+  /*              the identity matrix.                                     */+  /*    delta  :: A pointer to the translation vector.  Use~0 for the null */+  /*              vector.                                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The transformation is only applied to scalable image formats after */+  /*    the glyph has been loaded.  It means that hinting is unaltered by  */+  /*    the transformation and is performed on the character size given in */+  /*    the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes.         */+  /*                                                                       */+  /*    Note that this also transforms the `face.glyph.advance' field, but */+  /*    *not* the values in `face.glyph.metrics'.                          */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Set_Transform( FT_Face     face,+                    FT_Matrix*  matrix,+                    FT_Vector*  delta );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Render_Mode                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration type that lists the render modes supported by       */+  /*    FreeType~2.  Each mode corresponds to a specific type of scanline  */+  /*    conversion performed on the outline.                               */+  /*                                                                       */+  /*    For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode'     */+  /*    field in the @FT_GlyphSlotRec structure gives the format of the    */+  /*    returned bitmap.                                                   */+  /*                                                                       */+  /*    All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity.   */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_RENDER_MODE_NORMAL ::                                           */+  /*      This is the default render mode; it corresponds to 8-bit         */+  /*      anti-aliased bitmaps.                                            */+  /*                                                                       */+  /*    FT_RENDER_MODE_LIGHT ::                                            */+  /*      This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only        */+  /*      defined as a separate value because render modes are also used   */+  /*      indirectly to define hinting algorithm selectors.  See           */+  /*      @FT_LOAD_TARGET_XXX for details.                                 */+  /*                                                                       */+  /*    FT_RENDER_MODE_MONO ::                                             */+  /*      This mode corresponds to 1-bit bitmaps (with 2~levels of         */+  /*      opacity).                                                        */+  /*                                                                       */+  /*    FT_RENDER_MODE_LCD ::                                              */+  /*      This mode corresponds to horizontal RGB and BGR sub-pixel        */+  /*      displays like LCD screens.  It produces 8-bit bitmaps that are   */+  /*      3~times the width of the original glyph outline in pixels, and   */+  /*      which use the @FT_PIXEL_MODE_LCD mode.                           */+  /*                                                                       */+  /*    FT_RENDER_MODE_LCD_V ::                                            */+  /*      This mode corresponds to vertical RGB and BGR sub-pixel displays */+  /*      (like PDA screens, rotated LCD displays, etc.).  It produces     */+  /*      8-bit bitmaps that are 3~times the height of the original        */+  /*      glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode.   */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */+  /*    filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */+  /*    (not active in the default builds).  It is up to the caller to     */+  /*    either call @FT_Library_SetLcdFilter (if available) or do the      */+  /*    filtering itself.                                                  */+  /*                                                                       */+  /*    The selected render mode only affects vector glyphs of a font.     */+  /*    Embedded bitmaps often have a different pixel mode like            */+  /*    @FT_PIXEL_MODE_MONO.  You can use @FT_Bitmap_Convert to transform  */+  /*    them into 8-bit pixmaps.                                           */+  /*                                                                       */+  typedef enum  FT_Render_Mode_+  {+    FT_RENDER_MODE_NORMAL = 0,+    FT_RENDER_MODE_LIGHT,+    FT_RENDER_MODE_MONO,+    FT_RENDER_MODE_LCD,+    FT_RENDER_MODE_LCD_V,++    FT_RENDER_MODE_MAX++  } FT_Render_Mode;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    ft_render_mode_xxx                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    These constants are deprecated.  Use the corresponding             */+  /*    @FT_Render_Mode values instead.                                    */+  /*                                                                       */+  /* <Values>                                                              */+  /*    ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL                */+  /*    ft_render_mode_mono   :: see @FT_RENDER_MODE_MONO                  */+  /*                                                                       */+#define ft_render_mode_normal  FT_RENDER_MODE_NORMAL+#define ft_render_mode_mono    FT_RENDER_MODE_MONO+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Render_Glyph                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Convert a given glyph image to a bitmap.  It does so by inspecting */+  /*    the glyph image format, finding the relevant renderer, and         */+  /*    invoking it.                                                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    slot        :: A handle to the glyph slot containing the image to  */+  /*                   convert.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    render_mode :: This is the render mode used to render the glyph    */+  /*                   image into a bitmap.  See @FT_Render_Mode for a     */+  /*                   list of possible values.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Render_Glyph( FT_GlyphSlot    slot,+                   FT_Render_Mode  render_mode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Kerning_Mode                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration used to specify which kerning values to return in   */+  /*    @FT_Get_Kerning.                                                   */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_KERNING_DEFAULT  :: Return scaled and grid-fitted kerning       */+  /*                           distances (value is~0).                     */+  /*                                                                       */+  /*    FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning    */+  /*                           distances.                                  */+  /*                                                                       */+  /*    FT_KERNING_UNSCALED :: Return the kerning vector in original font  */+  /*                           units.                                      */+  /*                                                                       */+  typedef enum  FT_Kerning_Mode_+  {+    FT_KERNING_DEFAULT  = 0,+    FT_KERNING_UNFITTED,+    FT_KERNING_UNSCALED++  } FT_Kerning_Mode;+++  /*************************************************************************/+  /*                                                                       */+  /* <Const>                                                               */+  /*    ft_kerning_default                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This constant is deprecated.  Please use @FT_KERNING_DEFAULT       */+  /*    instead.                                                           */+  /*                                                                       */+#define ft_kerning_default   FT_KERNING_DEFAULT+++  /*************************************************************************/+  /*                                                                       */+  /* <Const>                                                               */+  /*    ft_kerning_unfitted                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This constant is deprecated.  Please use @FT_KERNING_UNFITTED      */+  /*    instead.                                                           */+  /*                                                                       */+#define ft_kerning_unfitted  FT_KERNING_UNFITTED+++  /*************************************************************************/+  /*                                                                       */+  /* <Const>                                                               */+  /*    ft_kerning_unscaled                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This constant is deprecated.  Please use @FT_KERNING_UNSCALED      */+  /*    instead.                                                           */+  /*                                                                       */+#define ft_kerning_unscaled  FT_KERNING_UNSCALED+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Kerning                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the kerning vector between two glyphs of a same face.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to a source face object.                   */+  /*                                                                       */+  /*    left_glyph  :: The index of the left glyph in the kern pair.       */+  /*                                                                       */+  /*    right_glyph :: The index of the right glyph in the kern pair.      */+  /*                                                                       */+  /*    kern_mode   :: See @FT_Kerning_Mode for more information.          */+  /*                   Determines the scale and dimension of the returned  */+  /*                   kerning vector.                                     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    akerning    :: The kerning vector.  This is either in font units   */+  /*                   or in pixels (26.6 format) for scalable formats,    */+  /*                   and in pixels for fixed-sizes formats.              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only horizontal layouts (left-to-right & right-to-left) are        */+  /*    supported by this method.  Other layouts, or more sophisticated    */+  /*    kernings, are out of the scope of this API function -- they can be */+  /*    implemented through format-specific interfaces.                    */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Kerning( FT_Face     face,+                  FT_UInt     left_glyph,+                  FT_UInt     right_glyph,+                  FT_UInt     kern_mode,+                  FT_Vector  *akerning );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Track_Kerning                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the track kerning for a given face object at a given size.  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face       :: A handle to a source face object.                    */+  /*                                                                       */+  /*    point_size :: The point size in 16.16 fractional points.           */+  /*                                                                       */+  /*    degree     :: The degree of tightness.                             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    akerning   :: The kerning in 16.16 fractional points.              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Track_Kerning( FT_Face    face,+                        FT_Fixed   point_size,+                        FT_Int     degree,+                        FT_Fixed*  akerning );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Glyph_Name                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the ASCII name of a given glyph in a face.  This only     */+  /*    works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1.   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to a source face object.                   */+  /*                                                                       */+  /*    glyph_index :: The glyph index.                                    */+  /*                                                                       */+  /*    buffer_max  :: The maximal number of bytes available in the        */+  /*                   buffer.                                             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    buffer      :: A pointer to a target buffer where the name is      */+  /*                   copied to.                                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    An error is returned if the face doesn't provide glyph names or if */+  /*    the glyph index is invalid.  In all cases of failure, the first    */+  /*    byte of `buffer' is set to~0 to indicate an empty name.            */+  /*                                                                       */+  /*    The glyph name is truncated to fit within the buffer if it is too  */+  /*    long.  The returned string is always zero-terminated.              */+  /*                                                                       */+  /*    This function is not compiled within the library if the config     */+  /*    macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in              */+  /*    `include/freetype/config/ftoptions.h'.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Glyph_Name( FT_Face     face,+                     FT_UInt     glyph_index,+                     FT_Pointer  buffer,+                     FT_UInt     buffer_max );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Postscript_Name                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the ASCII PostScript name of a given face, if available.  */+  /*    This only works with PostScript and TrueType fonts.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source face object.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A pointer to the face's PostScript name.  NULL if unavailable.     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The returned pointer is owned by the face and is destroyed with    */+  /*    it.                                                                */+  /*                                                                       */+  FT_EXPORT( const char* )+  FT_Get_Postscript_Name( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Select_Charmap                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Select a given charmap by its encoding tag (as listed in           */+  /*    `freetype.h').                                                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face     :: A handle to the source face object.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    encoding :: A handle to the selected encoding.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function returns an error if no charmap in the face           */+  /*    corresponds to the encoding queried here.                          */+  /*                                                                       */+  /*    Because many fonts contain more than a single cmap for Unicode     */+  /*    encoding, this function has some special code to select the one    */+  /*    which covers Unicode best (`best' in the sense that a UCS-4 cmap   */+  /*    is preferred to a UCS-2 cmap).  It is thus preferable to           */+  /*    @FT_Set_Charmap in this case.                                      */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Select_Charmap( FT_Face      face,+                     FT_Encoding  encoding );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Charmap                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Select a given charmap for character code to glyph index mapping.  */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face    :: A handle to the source face object.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    charmap :: A handle to the selected charmap.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function returns an error if the charmap is not part of       */+  /*    the face (i.e., if it is not listed in the `face->charmaps'        */+  /*    table).                                                            */+  /*                                                                       */+  /*    It also fails if a type~14 charmap is selected.                    */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Charmap( FT_Face     face,+                  FT_CharMap  charmap );+++  /*************************************************************************+   *+   * @function:+   *   FT_Get_Charmap_Index+   *+   * @description:+   *   Retrieve index of a given charmap.+   *+   * @input:+   *   charmap ::+   *     A handle to a charmap.+   *+   * @return:+   *   The index into the array of character maps within the face to which+   *   `charmap' belongs.  If an error occurs, -1 is returned.+   *+   */+  FT_EXPORT( FT_Int )+  FT_Get_Charmap_Index( FT_CharMap  charmap );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Char_Index                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the glyph index of a given character code.  This function   */+  /*    uses a charmap object to do the mapping.                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: A handle to the source face object.                    */+  /*                                                                       */+  /*    charcode :: The character code.                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The glyph index.  0~means `undefined character code'.              */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If you use FreeType to manipulate the contents of font files       */+  /*    directly, be aware that the glyph index returned by this function  */+  /*    doesn't always correspond to the internal indices used within      */+  /*    the file.  This is done to ensure that value~0 always corresponds  */+  /*    to the `missing glyph'.                                            */+  /*                                                                       */+  FT_EXPORT( FT_UInt )+  FT_Get_Char_Index( FT_Face   face,+                     FT_ULong  charcode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_First_Char                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to return the first character code in the    */+  /*    current charmap of a given face.  It also returns the              */+  /*    corresponding glyph index.                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face    :: A handle to the source face object.                     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    agindex :: Glyph index of first character code.  0~if charmap is   */+  /*               empty.                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The charmap's first character code.                                */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You should use this function with @FT_Get_Next_Char to be able to  */+  /*    parse all character codes available in a given charmap.  The code  */+  /*    should look like this:                                             */+  /*                                                                       */+  /*    {                                                                  */+  /*      FT_ULong  charcode;                                              */+  /*      FT_UInt   gindex;                                                */+  /*                                                                       */+  /*                                                                       */+  /*      charcode = FT_Get_First_Char( face, &gindex );                   */+  /*      while ( gindex != 0 )                                            */+  /*      {                                                                */+  /*        ... do something with (charcode,gindex) pair ...               */+  /*                                                                       */+  /*        charcode = FT_Get_Next_Char( face, charcode, &gindex );        */+  /*      }                                                                */+  /*    }                                                                  */+  /*                                                                       */+  /*    Note that `*agindex' is set to~0 if the charmap is empty.  The     */+  /*    result itself can be~0 in two cases: if the charmap is empty or    */+  /*    if the value~0 is the first valid character code.                  */+  /*                                                                       */+  FT_EXPORT( FT_ULong )+  FT_Get_First_Char( FT_Face   face,+                     FT_UInt  *agindex );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Next_Char                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to return the next character code in the     */+  /*    current charmap of a given face following the value `char_code',   */+  /*    as well as the corresponding glyph index.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face      :: A handle to the source face object.                   */+  /*    char_code :: The starting character code.                          */+  /*                                                                       */+  /* <Output>                                                              */+  /*    agindex   :: Glyph index of next character code.  0~if charmap     */+  /*                 is empty.                                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The charmap's next character code.                                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You should use this function with @FT_Get_First_Char to walk       */+  /*    over all character codes available in a given charmap.  See the    */+  /*    note for this function for a simple code example.                  */+  /*                                                                       */+  /*    Note that `*agindex' is set to~0 when there are no more codes in   */+  /*    the charmap.                                                       */+  /*                                                                       */+  FT_EXPORT( FT_ULong )+  FT_Get_Next_Char( FT_Face    face,+                    FT_ULong   char_code,+                    FT_UInt   *agindex );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Name_Index                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the glyph index of a given glyph name.  This function uses  */+  /*    driver specific objects to do the translation.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face       :: A handle to the source face object.                  */+  /*                                                                       */+  /*    glyph_name :: The glyph name.                                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The glyph index.  0~means `undefined character code'.              */+  /*                                                                       */+  FT_EXPORT( FT_UInt )+  FT_Get_Name_Index( FT_Face     face,+                     FT_String*  glyph_name );+++  /*************************************************************************+   *+   * @macro:+   *   FT_SUBGLYPH_FLAG_XXX+   *+   * @description:+   *   A list of constants used to describe subglyphs.  Please refer to the+   *   TrueType specification for the meaning of the various flags.+   *+   * @values:+   *   FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS ::+   *   FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ::+   *   FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID ::+   *   FT_SUBGLYPH_FLAG_SCALE ::+   *   FT_SUBGLYPH_FLAG_XY_SCALE ::+   *   FT_SUBGLYPH_FLAG_2X2 ::+   *   FT_SUBGLYPH_FLAG_USE_MY_METRICS ::+   *+   */+#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS          1+#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES      2+#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID        4+#define FT_SUBGLYPH_FLAG_SCALE                   8+#define FT_SUBGLYPH_FLAG_XY_SCALE             0x40+#define FT_SUBGLYPH_FLAG_2X2                  0x80+#define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200+++  /*************************************************************************+   *+   * @func:+   *   FT_Get_SubGlyph_Info+   *+   * @description:+   *   Retrieve a description of a given subglyph.  Only use it if+   *   `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is+   *   returned otherwise.+   *+   * @input:+   *   glyph ::+   *     The source glyph slot.+   *+   *   sub_index ::+   *     The index of the subglyph.  Must be less than+   *     `glyph->num_subglyphs'.+   *+   * @output:+   *   p_index ::+   *     The glyph index of the subglyph.+   *+   *   p_flags ::+   *     The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX.+   *+   *   p_arg1 ::+   *     The subglyph's first argument (if any).+   *+   *   p_arg2 ::+   *     The subglyph's second argument (if any).+   *+   *   p_transform ::+   *     The subglyph transformation (if any).+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   The values of `*p_arg1', `*p_arg2', and `*p_transform' must be+   *   interpreted depending on the flags returned in `*p_flags'.  See the+   *   TrueType specification for details.+   *+   */+  FT_EXPORT( FT_Error )+  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,+                        FT_UInt       sub_index,+                        FT_Int       *p_index,+                        FT_UInt      *p_flags,+                        FT_Int       *p_arg1,+                        FT_Int       *p_arg2,+                        FT_Matrix    *p_transform );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_FSTYPE_XXX                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit flags used in the `fsType' field of the OS/2 table   */+  /*    in a TrueType or OpenType font and the `FSType' entry in a         */+  /*    PostScript font.  These bit flags are returned by                  */+  /*    @FT_Get_FSType_Flags; they inform client applications of embedding */+  /*    and subsetting restrictions associated with a font.                */+  /*                                                                       */+  /*    See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for  */+  /*    more details.                                                      */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_FSTYPE_INSTALLABLE_EMBEDDING ::                                 */+  /*      Fonts with no fsType bit set may be embedded and permanently     */+  /*      installed on the remote system by an application.                */+  /*                                                                       */+  /*    FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING ::                          */+  /*      Fonts that have only this bit set must not be modified, embedded */+  /*      or exchanged in any manner without first obtaining permission of */+  /*      the font software copyright owner.                               */+  /*                                                                       */+  /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING ::                           */+  /*      If this bit is set, the font may be embedded and temporarily     */+  /*      loaded on the remote system.  Documents containing Preview &     */+  /*      Print fonts must be opened `read-only'; no edits can be applied  */+  /*      to the document.                                                 */+  /*                                                                       */+  /*    FT_FSTYPE_EDITABLE_EMBEDDING ::                                    */+  /*      If this bit is set, the font may be embedded but must only be    */+  /*      installed temporarily on other systems.  In contrast to Preview  */+  /*      & Print fonts, documents containing editable fonts may be opened */+  /*      for reading, editing is permitted, and changes may be saved.     */+  /*                                                                       */+  /*    FT_FSTYPE_NO_SUBSETTING ::                                         */+  /*      If this bit is set, the font may not be subsetted prior to       */+  /*      embedding.                                                       */+  /*                                                                       */+  /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY ::                                 */+  /*      If this bit is set, only bitmaps contained in the font may be    */+  /*      embedded; no outline data may be embedded.  If there are no      */+  /*      bitmaps available in the font, then the font is unembeddable.    */+  /*                                                                       */+  /* <Note>                                                                */+  /*    While the fsType flags can indicate that a font may be embedded, a */+  /*    license with the font vendor may be separately required to use the */+  /*    font in this way.                                                  */+  /*                                                                       */+#define FT_FSTYPE_INSTALLABLE_EMBEDDING         0x0000+#define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING  0x0002+#define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING   0x0004+#define FT_FSTYPE_EDITABLE_EMBEDDING            0x0008+#define FT_FSTYPE_NO_SUBSETTING                 0x0100+#define FT_FSTYPE_BITMAP_EMBEDDING_ONLY         0x0200+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_FSType_Flags                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the fsType flags for a font.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source face object.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The fsType flags, @FT_FSTYPE_XXX.                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Use this function rather than directly reading the `fs_type' field */+  /*    in the @PS_FontInfoRec structure which is only guaranteed to       */+  /*    return the correct results for Type~1 fonts.                       */+  /*                                                                       */+  FT_EXPORT( FT_UShort )+  FT_Get_FSType_Flags( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    glyph_variants                                                     */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Glyph Variants                                                     */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    The FreeType~2 interface to Unicode Ideographic Variation          */+  /*    Sequences (IVS), using the SFNT cmap format~14.                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Many CJK characters have variant forms.  They are a sort of grey   */+  /*    area somewhere between being totally irrelevant and semantically   */+  /*    distinct; for this reason, the Unicode consortium decided to       */+  /*    introduce Ideographic Variation Sequences (IVS), consisting of a   */+  /*    Unicode base character and one of 240 variant selectors            */+  /*    (U+E0100-U+E01EF), instead of further extending the already huge   */+  /*    code range for CJK characters.                                     */+  /*                                                                       */+  /*    An IVS is registered and unique; for further details please refer  */+  /*    to Unicode Technical Report #37, the Ideographic Variation         */+  /*    Database.  To date (October 2007), the character with the most     */+  /*    variants is U+908A, having 8~such IVS.                             */+  /*                                                                       */+  /*    Adobe and MS decided to support IVS with a new cmap subtable       */+  /*    (format~14).  It is an odd subtable because it is not a mapping of */+  /*    input code points to glyphs, but contains lists of all variants    */+  /*    supported by the font.                                             */+  /*                                                                       */+  /*    A variant may be either `default' or `non-default'.  A default     */+  /*    variant is the one you will get for that code point if you look it */+  /*    up in the standard Unicode cmap.  A non-default variant is a       */+  /*    different glyph.                                                   */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_GetCharVariantIndex                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the glyph index of a given character code as modified by    */+  /*    the variation selector.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      A handle to the source face object.                              */+  /*                                                                       */+  /*    charcode ::                                                        */+  /*      The character code point in Unicode.                             */+  /*                                                                       */+  /*    variantSelector ::                                                 */+  /*      The Unicode code point of the variation selector.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The glyph index.  0~means either `undefined character code', or    */+  /*    `undefined selector code', or `no variation selector cmap          */+  /*    subtable', or `current CharMap is not Unicode'.                    */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If you use FreeType to manipulate the contents of font files       */+  /*    directly, be aware that the glyph index returned by this function  */+  /*    doesn't always correspond to the internal indices used within      */+  /*    the file.  This is done to ensure that value~0 always corresponds  */+  /*    to the `missing glyph'.                                            */+  /*                                                                       */+  /*    This function is only meaningful if                                */+  /*      a) the font has a variation selector cmap sub table,             */+  /*    and                                                                */+  /*      b) the current charmap has a Unicode encoding.                   */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.6                                                              */+  /*                                                                       */+  FT_EXPORT( FT_UInt )+  FT_Face_GetCharVariantIndex( FT_Face   face,+                               FT_ULong  charcode,+                               FT_ULong  variantSelector );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_GetCharVariantIsDefault                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Check whether this variant of this Unicode character is the one to */+  /*    be found in the `cmap'.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      A handle to the source face object.                              */+  /*                                                                       */+  /*    charcode ::                                                        */+  /*      The character codepoint in Unicode.                              */+  /*                                                                       */+  /*    variantSelector ::                                                 */+  /*      The Unicode codepoint of the variation selector.                 */+  /*                                                                       */+  /* <Return>                                                              */+  /*    1~if found in the standard (Unicode) cmap, 0~if found in the       */+  /*    variation selector cmap, or -1 if it is not a variant.             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function is only meaningful if the font has a variation       */+  /*    selector cmap subtable.                                            */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.6                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Int )+  FT_Face_GetCharVariantIsDefault( FT_Face   face,+                                   FT_ULong  charcode,+                                   FT_ULong  variantSelector );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_GetVariantSelectors                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a zero-terminated list of Unicode variant selectors found   */+  /*    in the font.                                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      A handle to the source face object.                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A pointer to an array of selector code points, or NULL if there is */+  /*    no valid variant selector cmap subtable.                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The last item in the array is~0; the array is owned by the         */+  /*    @FT_Face object but can be overwritten or released on the next     */+  /*    call to a FreeType function.                                       */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.6                                                              */+  /*                                                                       */+  FT_EXPORT( FT_UInt32* )+  FT_Face_GetVariantSelectors( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_GetVariantsOfChar                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a zero-terminated list of Unicode variant selectors found   */+  /*    for the specified character code.                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      A handle to the source face object.                              */+  /*                                                                       */+  /*    charcode ::                                                        */+  /*      The character codepoint in Unicode.                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A pointer to an array of variant selector code points which are    */+  /*    active for the given character, or NULL if the corresponding list  */+  /*    is empty.                                                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The last item in the array is~0; the array is owned by the         */+  /*    @FT_Face object but can be overwritten or released on the next     */+  /*    call to a FreeType function.                                       */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.6                                                              */+  /*                                                                       */+  FT_EXPORT( FT_UInt32* )+  FT_Face_GetVariantsOfChar( FT_Face   face,+                             FT_ULong  charcode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_GetCharsOfVariant                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a zero-terminated list of Unicode character codes found for */+  /*    the specified variant selector.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      A handle to the source face object.                              */+  /*                                                                       */+  /*    variantSelector ::                                                 */+  /*      The variant selector code point in Unicode.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A list of all the code points which are specified by this selector */+  /*    (both default and non-default codes are returned) or NULL if there */+  /*    is no valid cmap or the variant selector is invalid.               */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The last item in the array is~0; the array is owned by the         */+  /*    @FT_Face object but can be overwritten or released on the next     */+  /*    call to a FreeType function.                                       */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.6                                                              */+  /*                                                                       */+  FT_EXPORT( FT_UInt32* )+  FT_Face_GetCharsOfVariant( FT_Face   face,+                             FT_ULong  variantSelector );+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    computations                                                       */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Computations                                                       */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Crunching fixed numbers and vectors.                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains various functions used to perform            */+  /*    computations on 16.16 fixed-float numbers or 2d vectors.           */+  /*                                                                       */+  /* <Order>                                                               */+  /*    FT_MulDiv                                                          */+  /*    FT_MulFix                                                          */+  /*    FT_DivFix                                                          */+  /*    FT_RoundFix                                                        */+  /*    FT_CeilFix                                                         */+  /*    FT_FloorFix                                                        */+  /*    FT_Vector_Transform                                                */+  /*    FT_Matrix_Multiply                                                 */+  /*    FT_Matrix_Invert                                                   */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_MulDiv                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to perform the computation `(a*b)/c'   */+  /*    with maximal accuracy (it uses a 64-bit intermediate integer       */+  /*    whenever necessary).                                               */+  /*                                                                       */+  /*    This function isn't necessarily as fast as some processor specific */+  /*    operations, but is at least completely portable.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The first multiplier.                                         */+  /*    b :: The second multiplier.                                        */+  /*    c :: The divisor.                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a*b)/c'.  This function never traps when trying to */+  /*    divide by zero; it simply returns `MaxInt' or `MinInt' depending   */+  /*    on the signs of `a' and `b'.                                       */+  /*                                                                       */+  FT_EXPORT( FT_Long )+  FT_MulDiv( FT_Long  a,+             FT_Long  b,+             FT_Long  c );+++  /* */++  /* The following #if 0 ... #endif is for the documentation formatter, */+  /* hiding the internal `FT_MULFIX_INLINED' macro.                     */++#if 0+  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_MulFix                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to perform the computation             */+  /*    `(a*b)/0x10000' with maximal accuracy.  Most of the time this is   */+  /*    used to multiply a given value by a 16.16 fixed float factor.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The first multiplier.                                         */+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */+  /*         possible (see note below).                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a*b)/0x10000'.                                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function has been optimized for the case where the absolute   */+  /*    value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */+  /*    As this happens mainly when scaling from notional units to         */+  /*    fractional pixels in FreeType, it resulted in noticeable speed     */+  /*    improvements between versions 2.x and 1.x.                         */+  /*                                                                       */+  /*    As a conclusion, always try to place a 16.16 factor as the         */+  /*    _second_ argument of this function; this can make a great          */+  /*    difference.                                                        */+  /*                                                                       */+  FT_EXPORT( FT_Long )+  FT_MulFix( FT_Long  a,+             FT_Long  b );++  /* */+#endif++#ifdef FT_MULFIX_INLINED+#define FT_MulFix( a, b )  FT_MULFIX_INLINED( a, b )+#else+  FT_EXPORT( FT_Long )+  FT_MulFix( FT_Long  a,+             FT_Long  b );+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_DivFix                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to perform the computation             */+  /*    `(a*0x10000)/b' with maximal accuracy.  Most of the time, this is  */+  /*    used to divide a given value by a 16.16 fixed float factor.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The first multiplier.                                         */+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */+  /*         possible (see note below).                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a*0x10000)/b'.                                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The optimization for FT_DivFix() is simple: If (a~<<~16) fits in   */+  /*    32~bits, then the division is computed directly.  Otherwise, we    */+  /*    use a specialized version of @FT_MulDiv.                           */+  /*                                                                       */+  FT_EXPORT( FT_Long )+  FT_DivFix( FT_Long  a,+             FT_Long  b );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_RoundFix                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to round a 16.16 fixed number.         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The number to be rounded.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a + 0x8000) & -0x10000'.                           */+  /*                                                                       */+  FT_EXPORT( FT_Fixed )+  FT_RoundFix( FT_Fixed  a );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_CeilFix                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to compute the ceiling function of a   */+  /*    16.16 fixed number.                                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The number for which the ceiling function is to be computed.  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a + 0x10000 - 1) & -0x10000'.                      */+  /*                                                                       */+  FT_EXPORT( FT_Fixed )+  FT_CeilFix( FT_Fixed  a );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_FloorFix                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to compute the floor function of a     */+  /*    16.16 fixed number.                                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The number for which the floor function is to be computed.    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `a & -0x10000'.                                      */+  /*                                                                       */+  FT_EXPORT( FT_Fixed )+  FT_FloorFix( FT_Fixed  a );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Vector_Transform                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Transform a single vector through a 2x2 matrix.                    */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    vector :: The target vector to transform.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    matrix :: A pointer to the source 2x2 matrix.                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The result is undefined if either `vector' or `matrix' is invalid. */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Vector_Transform( FT_Vector*        vec,+                       const FT_Matrix*  matrix );+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    version                                                            */+  /*                                                                       */+  /* <Title>                                                               */+  /*    FreeType Version                                                   */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Functions and macros related to FreeType versions.                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Note that those functions and macros are of limited use because    */+  /*    even a new release of FreeType with only documentation changes     */+  /*    increases the version number.                                      */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************+   *+   * @enum:+   *   FREETYPE_XXX+   *+   * @description:+   *   These three macros identify the FreeType source code version.+   *   Use @FT_Library_Version to access them at runtime.+   *+   * @values:+   *   FREETYPE_MAJOR :: The major version number.+   *   FREETYPE_MINOR :: The minor version number.+   *   FREETYPE_PATCH :: The patch level.+   *+   * @note:+   *   The version number of FreeType if built as a dynamic link library+   *   with the `libtool' package is _not_ controlled by these three+   *   macros.+   *+   */+#define FREETYPE_MAJOR  2+#define FREETYPE_MINOR  4+#define FREETYPE_PATCH  4+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Library_Version                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the version of the FreeType library being used.  This is    */+  /*    useful when dynamically linking to the library, since one cannot   */+  /*    use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and               */+  /*    @FREETYPE_PATCH.                                                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A source library handle.                                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    amajor  :: The major version number.                               */+  /*                                                                       */+  /*    aminor  :: The minor version number.                               */+  /*                                                                       */+  /*    apatch  :: The patch version number.                               */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The reason why this function takes a `library' argument is because */+  /*    certain programs implement library initialization in a custom way  */+  /*    that doesn't use @FT_Init_FreeType.                                */+  /*                                                                       */+  /*    In such cases, the library version might not be available before   */+  /*    the library object has been created.                               */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Library_Version( FT_Library   library,+                      FT_Int      *amajor,+                      FT_Int      *aminor,+                      FT_Int      *apatch );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_CheckTrueTypePatents                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parse all bytecode instructions of a TrueType font file to check   */+  /*    whether any of the patented opcodes are used.  This is only useful */+  /*    if you want to be able to use the unpatented hinter with           */+  /*    fonts that do *not* use these opcodes.                             */+  /*                                                                       */+  /*    Note that this function parses *all* glyph instructions in the     */+  /*    font file, which may be slow.                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A face handle.                                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    1~if this is a TrueType font that uses one of the patented         */+  /*    opcodes, 0~otherwise.                                              */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Since May 2010, TrueType hinting is no longer patented.            */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.5                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Bool )+  FT_Face_CheckTrueTypePatents( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Face_SetUnpatentedHinting                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Enable or disable the unpatented hinter for a given face.          */+  /*    Only enable it if you have determined that the face doesn't        */+  /*    use any patented opcodes (see @FT_Face_CheckTrueTypePatents).      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face  :: A face handle.                                            */+  /*                                                                       */+  /*    value :: New boolean setting.                                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The old setting value.  This will always be false if this is not   */+  /*    an SFNT font, or if the unpatented hinter is not compiled in this  */+  /*    instance of the library.                                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Since May 2010, TrueType hinting is no longer patented.            */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.3.5                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Bool )+  FT_Face_SetUnpatentedHinting( FT_Face  face,+                                FT_Bool  value );++  /* */+++FT_END_HEADER++#endif /* __FREETYPE_H__ */+++/* END */
+ include/freetype/ftadvanc.h view
@@ -0,0 +1,179 @@+/***************************************************************************/+/*                                                                         */+/*  ftadvanc.h                                                             */+/*                                                                         */+/*    Quick computation of advance widths (specification only).            */+/*                                                                         */+/*  Copyright 2008 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTADVANC_H__+#define __FTADVANC_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /**************************************************************************+   *+   * @section:+   *   quick_advance+   *+   * @title:+   *   Quick retrieval of advance values+   *+   * @abstract:+   *   Retrieve horizontal and vertical advance values without processing+   *   glyph outlines, if possible.+   *+   * @description:+   *   This section contains functions to quickly extract advance values+   *   without handling glyph outlines, if possible.+   */+++  /*************************************************************************/+  /*                                                                       */+  /* <Const>                                                               */+  /*    FT_ADVANCE_FLAG_FAST_ONLY                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A bit-flag to be OR-ed with the `flags' parameter of the           */+  /*    @FT_Get_Advance and @FT_Get_Advances functions.                    */+  /*                                                                       */+  /*    If set, it indicates that you want these functions to fail if the  */+  /*    corresponding hinting mode or font driver doesn't allow for very   */+  /*    quick advance computation.                                         */+  /*                                                                       */+  /*    Typically, glyphs which are either unscaled, unhinted, bitmapped,  */+  /*    or light-hinted can have their advance width computed very         */+  /*    quickly.                                                           */+  /*                                                                       */+  /*    Normal and bytecode hinted modes, which require loading, scaling,  */+  /*    and hinting of the glyph outline, are extremely slow by            */+  /*    comparison.                                                        */+  /*                                                                       */+#define FT_ADVANCE_FLAG_FAST_ONLY  0x20000000UL+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Advance                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the advance value of a given glyph outline in an          */+  /*    @FT_Face.  By default, the unhinted advance is returned in font    */+  /*    units.                                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face       :: The source @FT_Face handle.                          */+  /*                                                                       */+  /*    gindex     :: The glyph index.                                     */+  /*                                                                       */+  /*    load_flags :: A set of bit flags similar to those used when        */+  /*                  calling @FT_Load_Glyph, used to determine what kind  */+  /*                  of advances you need.                                */+  /* <Output>                                                              */+  /*    padvance :: The advance value, in either font units or 16.16       */+  /*                format.                                                */+  /*                                                                       */+  /*                If @FT_LOAD_VERTICAL_LAYOUT is set, this is the        */+  /*                vertical advance corresponding to a vertical layout.   */+  /*                Otherwise, it is the horizontal advance in a           */+  /*                horizontal layout.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and   */+  /*    if the corresponding font backend doesn't have a quick way to      */+  /*    retrieve the advances.                                             */+  /*                                                                       */+  /*    A scaled advance is returned in 16.16 format but isn't transformed */+  /*    by the affine transformation specified by @FT_Set_Transform.       */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Advance( FT_Face    face,+                  FT_UInt    gindex,+                  FT_Int32   load_flags,+                  FT_Fixed  *padvance );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Advances                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the advance values of several glyph outlines in an        */+  /*    @FT_Face.  By default, the unhinted advances are returned in font  */+  /*    units.                                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: The source @FT_Face handle.                         */+  /*                                                                       */+  /*    start       :: The first glyph index.                              */+  /*                                                                       */+  /*    count       :: The number of advance values you want to retrieve.  */+  /*                                                                       */+  /*    load_flags  :: A set of bit flags similar to those used when       */+  /*                   calling @FT_Load_Glyph.                             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    padvance :: The advances, in either font units or 16.16 format.    */+  /*                This array must contain at least `count' elements.     */+  /*                                                                       */+  /*                If @FT_LOAD_VERTICAL_LAYOUT is set, these are the      */+  /*                vertical advances corresponding to a vertical layout.  */+  /*                Otherwise, they are the horizontal advances in a       */+  /*                horizontal layout.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and   */+  /*    if the corresponding font backend doesn't have a quick way to      */+  /*    retrieve the advances.                                             */+  /*                                                                       */+  /*    Scaled advances are returned in 16.16 format but aren't            */+  /*    transformed by the affine transformation specified by              */+  /*    @FT_Set_Transform.                                                 */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Advances( FT_Face    face,+                   FT_UInt    start,+                   FT_UInt    count,+                   FT_Int32   load_flags,+                   FT_Fixed  *padvances );++/* */+++FT_END_HEADER++#endif /* __FTADVANC_H__ */+++/* END */
+ include/freetype/ftbbox.h view
@@ -0,0 +1,94 @@+/***************************************************************************/+/*                                                                         */+/*  ftbbox.h                                                               */+/*                                                                         */+/*    FreeType exact bbox computation (specification).                     */+/*                                                                         */+/*  Copyright 1996-2001, 2003, 2007 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This component has a _single_ role: to compute exact outline bounding */+  /* boxes.                                                                */+  /*                                                                       */+  /* It is separated from the rest of the engine for various technical     */+  /* reasons.  It may well be integrated in `ftoutln' later.               */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTBBOX_H__+#define __FTBBOX_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    outline_processing                                                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Get_BBox                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Compute the exact bounding box of an outline.  This is slower      */+  /*    than computing the control box.  However, it uses an advanced      */+  /*    algorithm which returns _very_ quickly when the two boxes          */+  /*    coincide.  Otherwise, the outline Bézier arcs are traversed to     */+  /*    extract their extrema.                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    outline :: A pointer to the source outline.                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    abbox   :: The outline's exact bounding box.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Get_BBox( FT_Outline*  outline,+                       FT_BBox     *abbox );+++  /* */+++FT_END_HEADER++#endif /* __FTBBOX_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftbdf.h view
@@ -0,0 +1,209 @@+/***************************************************************************/+/*                                                                         */+/*  ftbdf.h                                                                */+/*                                                                         */+/*    FreeType API for accessing BDF-specific strings (specification).     */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006, 2009 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTBDF_H__+#define __FTBDF_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    bdf_fonts                                                          */+  /*                                                                       */+  /* <Title>                                                               */+  /*    BDF and PCF Files                                                  */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    BDF and PCF specific API.                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of functions specific to BDF */+  /*    and PCF fonts.                                                     */+  /*                                                                       */+  /*************************************************************************/+++  /**********************************************************************+   *+   * @enum:+   *    FT_PropertyType+   *+   * @description:+   *    A list of BDF property types.+   *+   * @values:+   *    BDF_PROPERTY_TYPE_NONE ::+   *      Value~0 is used to indicate a missing property.+   *+   *    BDF_PROPERTY_TYPE_ATOM ::+   *      Property is a string atom.+   *+   *    BDF_PROPERTY_TYPE_INTEGER ::+   *      Property is a 32-bit signed integer.+   *+   *    BDF_PROPERTY_TYPE_CARDINAL ::+   *      Property is a 32-bit unsigned integer.+   */+  typedef enum  BDF_PropertyType_+  {+    BDF_PROPERTY_TYPE_NONE     = 0,+    BDF_PROPERTY_TYPE_ATOM     = 1,+    BDF_PROPERTY_TYPE_INTEGER  = 2,+    BDF_PROPERTY_TYPE_CARDINAL = 3++  } BDF_PropertyType;+++  /**********************************************************************+   *+   * @type:+   *    BDF_Property+   *+   * @description:+   *    A handle to a @BDF_PropertyRec structure to model a given+   *    BDF/PCF property.+   */+  typedef struct BDF_PropertyRec_*  BDF_Property;+++ /**********************************************************************+  *+  * @struct:+  *    BDF_PropertyRec+  *+  * @description:+  *    This structure models a given BDF/PCF property.+  *+  * @fields:+  *    type ::+  *      The property type.+  *+  *    u.atom ::+  *      The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.+  *+  *    u.integer ::+  *      A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.+  *+  *    u.cardinal ::+  *      An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL.+  */+  typedef struct  BDF_PropertyRec_+  {+    BDF_PropertyType  type;+    union {+      const char*     atom;+      FT_Int32        integer;+      FT_UInt32       cardinal;++    } u;++  } BDF_PropertyRec;+++ /**********************************************************************+  *+  * @function:+  *    FT_Get_BDF_Charset_ID+  *+  * @description:+  *    Retrieve a BDF font character set identity, according to+  *    the BDF specification.+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  * @output:+  *    acharset_encoding ::+  *       Charset encoding, as a C~string, owned by the face.+  *+  *    acharset_registry ::+  *       Charset registry, as a C~string, owned by the face.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   This function only works with BDF faces, returning an error otherwise.+  */+  FT_EXPORT( FT_Error )+  FT_Get_BDF_Charset_ID( FT_Face       face,+                         const char*  *acharset_encoding,+                         const char*  *acharset_registry );+++ /**********************************************************************+  *+  * @function:+  *    FT_Get_BDF_Property+  *+  * @description:+  *    Retrieve a BDF property from a BDF or PCF font file.+  *+  * @input:+  *    face :: A handle to the input face.+  *+  *    name :: The property name.+  *+  * @output:+  *    aproperty :: The property.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   This function works with BDF _and_ PCF fonts.  It returns an error+  *   otherwise.  It also returns an error if the property is not in the+  *   font.+  *+  *   A `property' is a either key-value pair within the STARTPROPERTIES+  *   ... ENDPROPERTIES block of a BDF font or a key-value pair from the+  *   `info->props' array within a `FontRec' structure of a PCF font.+  *+  *   Integer properties are always stored as `signed' within PCF fonts;+  *   consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value+  *   for BDF fonts only.+  *+  *   In case of error, `aproperty->type' is always set to+  *   @BDF_PROPERTY_TYPE_NONE.+  */+  FT_EXPORT( FT_Error )+  FT_Get_BDF_Property( FT_Face           face,+                       const char*       prop_name,+                       BDF_PropertyRec  *aproperty );++ /* */++FT_END_HEADER++#endif /* __FTBDF_H__ */+++/* END */
+ include/freetype/ftbitmap.h view
@@ -0,0 +1,227 @@+/***************************************************************************/+/*                                                                         */+/*  ftbitmap.h                                                             */+/*                                                                         */+/*    FreeType utility functions for bitmaps (specification).              */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2008 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTBITMAP_H__+#define __FTBITMAP_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    bitmap_handling                                                    */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Bitmap Handling                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Handling FT_Bitmap objects.                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains functions for converting FT_Bitmap objects.  */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Bitmap_New                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a pointer to an @FT_Bitmap structure.                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    abitmap :: A pointer to the bitmap structure.                      */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Bitmap_New( FT_Bitmap  *abitmap );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Bitmap_Copy                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Copy a bitmap into another one.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to a library object.                           */+  /*                                                                       */+  /*    source  :: A handle to the source bitmap.                          */+  /*                                                                       */+  /* <Output>                                                              */+  /*    target  :: A handle to the target bitmap.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Bitmap_Copy( FT_Library        library,+                  const FT_Bitmap  *source,+                  FT_Bitmap        *target);+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Bitmap_Embolden                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Embolden a bitmap.  The new bitmap will be about `xStrength'       */+  /*    pixels wider and `yStrength' pixels higher.  The left and bottom   */+  /*    borders are kept unchanged.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library   :: A handle to a library object.                         */+  /*                                                                       */+  /*    xStrength :: How strong the glyph is emboldened horizontally.      */+  /*                 Expressed in 26.6 pixel format.                       */+  /*                                                                       */+  /*    yStrength :: How strong the glyph is emboldened vertically.        */+  /*                 Expressed in 26.6 pixel format.                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    bitmap    :: A handle to the target bitmap.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The current implementation restricts `xStrength' to be less than   */+  /*    or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.      */+  /*                                                                       */+  /*    If you want to embolden the bitmap owned by a @FT_GlyphSlotRec,    */+  /*    you should call @FT_GlyphSlot_Own_Bitmap on the slot first.        */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Bitmap_Embolden( FT_Library  library,+                      FT_Bitmap*  bitmap,+                      FT_Pos      xStrength,+                      FT_Pos      yStrength );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Bitmap_Convert                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a  */+  /*    bitmap object with depth 8bpp, making the number of used bytes per */+  /*    line (a.k.a. the `pitch') a multiple of `alignment'.               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library   :: A handle to a library object.                         */+  /*                                                                       */+  /*    source    :: The source bitmap.                                    */+  /*                                                                       */+  /*    alignment :: The pitch of the bitmap is a multiple of this         */+  /*                 parameter.  Common values are 1, 2, or 4.             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    target    :: The target bitmap.                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    It is possible to call @FT_Bitmap_Convert multiple times without   */+  /*    calling @FT_Bitmap_Done (the memory is simply reallocated).        */+  /*                                                                       */+  /*    Use @FT_Bitmap_Done to finally remove the bitmap object.           */+  /*                                                                       */+  /*    The `library' argument is taken to have access to FreeType's       */+  /*    memory handling functions.                                         */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Bitmap_Convert( FT_Library        library,+                     const FT_Bitmap  *source,+                     FT_Bitmap        *target,+                     FT_Int            alignment );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_GlyphSlot_Own_Bitmap                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Make sure that a glyph slot owns `slot->bitmap'.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    slot :: The glyph slot.                                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function is to be used in combination with                    */+  /*    @FT_Bitmap_Embolden.                                               */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Bitmap_Done                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy a bitmap object created with @FT_Bitmap_New.               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to a library object.                           */+  /*                                                                       */+  /*    bitmap  :: The bitmap object to be freed.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The `library' argument is taken to have access to FreeType's       */+  /*    memory handling functions.                                         */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Bitmap_Done( FT_Library  library,+                  FT_Bitmap  *bitmap );+++  /* */+++FT_END_HEADER++#endif /* __FTBITMAP_H__ */+++/* END */
+ include/freetype/ftcache.h view
@@ -0,0 +1,1140 @@+/***************************************************************************/+/*                                                                         */+/*  ftcache.h                                                              */+/*                                                                         */+/*    FreeType Cache subsystem (specification).                            */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTCACHE_H__+#define __FTCACHE_H__+++#include <ft2build.h>+#include FT_GLYPH_H+++FT_BEGIN_HEADER+++  /*************************************************************************+   *+   * <Section>+   *    cache_subsystem+   *+   * <Title>+   *    Cache Sub-System+   *+   * <Abstract>+   *    How to cache face, size, and glyph data with FreeType~2.+   *+   * <Description>+   *   This section describes the FreeType~2 cache sub-system, which is used+   *   to limit the number of concurrently opened @FT_Face and @FT_Size+   *   objects, as well as caching information like character maps and glyph+   *   images while limiting their maximum memory usage.+   *+   *   Note that all types and functions begin with the `FTC_' prefix.+   *+   *   The cache is highly portable and thus doesn't know anything about the+   *   fonts installed on your system, or how to access them.  This implies+   *   the following scheme:+   *+   *   First, available or installed font faces are uniquely identified by+   *   @FTC_FaceID values, provided to the cache by the client.  Note that+   *   the cache only stores and compares these values, and doesn't try to+   *   interpret them in any way.+   *+   *   Second, the cache calls, only when needed, a client-provided function+   *   to convert an @FTC_FaceID into a new @FT_Face object.  The latter is+   *   then completely managed by the cache, including its termination+   *   through @FT_Done_Face.  To monitor termination of face objects, the+   *   finalizer callback in the `generic' field of the @FT_Face object can+   *   be used, which might also be used to store the @FTC_FaceID of the+   *   face.+   *+   *   Clients are free to map face IDs to anything else.  The most simple+   *   usage is to associate them to a (pathname,face_index) pair that is+   *   used to call @FT_New_Face.  However, more complex schemes are also+   *   possible.+   *+   *   Note that for the cache to work correctly, the face ID values must be+   *   *persistent*, which means that the contents they point to should not+   *   change at runtime, or that their value should not become invalid.+   *+   *   If this is unavoidable (e.g., when a font is uninstalled at runtime),+   *   you should call @FTC_Manager_RemoveFaceID as soon as possible, to let+   *   the cache get rid of any references to the old @FTC_FaceID it may+   *   keep internally.  Failure to do so will lead to incorrect behaviour+   *   or even crashes.+   *+   *   To use the cache, start with calling @FTC_Manager_New to create a new+   *   @FTC_Manager object, which models a single cache instance.  You can+   *   then look up @FT_Face and @FT_Size objects with+   *   @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively.+   *+   *   If you want to use the charmap caching, call @FTC_CMapCache_New, then+   *   later use @FTC_CMapCache_Lookup to perform the equivalent of+   *   @FT_Get_Char_Index, only much faster.+   *+   *   If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then+   *   later use @FTC_ImageCache_Lookup to retrieve the corresponding+   *   @FT_Glyph objects from the cache.+   *+   *   If you need lots of small bitmaps, it is much more memory efficient+   *   to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup.  This+   *   returns @FTC_SBitRec structures, which are used to store small+   *   bitmaps directly.  (A small bitmap is one whose metrics and+   *   dimensions all fit into 8-bit integers).+   *+   *   We hope to also provide a kerning cache in the near future.+   *+   *+   * <Order>+   *   FTC_Manager+   *   FTC_FaceID+   *   FTC_Face_Requester+   *+   *   FTC_Manager_New+   *   FTC_Manager_Reset+   *   FTC_Manager_Done+   *   FTC_Manager_LookupFace+   *   FTC_Manager_LookupSize+   *   FTC_Manager_RemoveFaceID+   *+   *   FTC_Node+   *   FTC_Node_Unref+   *+   *   FTC_ImageCache+   *   FTC_ImageCache_New+   *   FTC_ImageCache_Lookup+   *+   *   FTC_SBit+   *   FTC_SBitCache+   *   FTC_SBitCache_New+   *   FTC_SBitCache_Lookup+   *+   *   FTC_CMapCache+   *   FTC_CMapCache_New+   *   FTC_CMapCache_Lookup+   *+   *************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    BASIC TYPE DEFINITIONS                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************+   *+   * @type: FTC_FaceID+   *+   * @description:+   *   An opaque pointer type that is used to identity face objects.  The+   *   contents of such objects is application-dependent.+   *+   *   These pointers are typically used to point to a user-defined+   *   structure containing a font file path, and face index.+   *+   * @note:+   *   Never use NULL as a valid @FTC_FaceID.+   *+   *   Face IDs are passed by the client to the cache manager, which calls,+   *   when needed, the @FTC_Face_Requester to translate them into new+   *   @FT_Face objects.+   *+   *   If the content of a given face ID changes at runtime, or if the value+   *   becomes invalid (e.g., when uninstalling a font), you should+   *   immediately call @FTC_Manager_RemoveFaceID before any other cache+   *   function.+   *+   *   Failure to do so will result in incorrect behaviour or even+   *   memory leaks and crashes.+   */+  typedef FT_Pointer  FTC_FaceID;+++  /************************************************************************+   *+   * @functype:+   *   FTC_Face_Requester+   *+   * @description:+   *   A callback function provided by client applications.  It is used by+   *   the cache manager to translate a given @FTC_FaceID into a new valid+   *   @FT_Face object, on demand.+   *+   * <Input>+   *   face_id ::+   *     The face ID to resolve.+   *+   *   library ::+   *     A handle to a FreeType library object.+   *+   *   req_data ::+   *     Application-provided request data (see note below).+   *+   * <Output>+   *   aface ::+   *     A new @FT_Face handle.+   *+   * <Return>+   *   FreeType error code.  0~means success.+   *+   * <Note>+   *   The third parameter `req_data' is the same as the one passed by the+   *   client when @FTC_Manager_New is called.+   *+   *   The face requester should not perform funny things on the returned+   *   face object, like creating a new @FT_Size for it, or setting a+   *   transformation through @FT_Set_Transform!+   */+  typedef FT_Error+  (*FTC_Face_Requester)( FTC_FaceID  face_id,+                         FT_Library  library,+                         FT_Pointer  request_data,+                         FT_Face*    aface );++ /* */++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /* these macros are incompatible with LLP64, should not be used */++#define FT_POINTER_TO_ULONG( p )  ( (FT_ULong)(FT_Pointer)(p) )++#define FTC_FACE_ID_HASH( i )                                \+          ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^   \+                       ( FT_POINTER_TO_ULONG( i ) << 7 ) ) )++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      CACHE MANAGER OBJECT                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FTC_Manager                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This object corresponds to one instance of the cache-subsystem.    */+  /*    It is used to cache one or more @FT_Face objects, along with       */+  /*    corresponding @FT_Size objects.                                    */+  /*                                                                       */+  /*    The manager intentionally limits the total number of opened        */+  /*    @FT_Face and @FT_Size objects to control memory usage.  See the    */+  /*    `max_faces' and `max_sizes' parameters of @FTC_Manager_New.        */+  /*                                                                       */+  /*    The manager is also used to cache `nodes' of various types while   */+  /*    limiting their total memory usage.                                 */+  /*                                                                       */+  /*    All limitations are enforced by keeping lists of managed objects   */+  /*    in most-recently-used order, and flushing old nodes to make room   */+  /*    for new ones.                                                      */+  /*                                                                       */+  typedef struct FTC_ManagerRec_*  FTC_Manager;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FTC_Node                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An opaque handle to a cache node object.  Each cache node is       */+  /*    reference-counted.  A node with a count of~0 might be flushed      */+  /*    out of a full cache whenever a lookup request is performed.        */+  /*                                                                       */+  /*    If you look up nodes, you have the ability to `acquire' them,      */+  /*    i.e., to increment their reference count.  This will prevent the   */+  /*    node from being flushed out of the cache until you explicitly      */+  /*    `release' it (see @FTC_Node_Unref).                                */+  /*                                                                       */+  /*    See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup.         */+  /*                                                                       */+  typedef struct FTC_NodeRec_*  FTC_Node;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_New                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new cache manager.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library   :: The parent FreeType library handle to use.            */+  /*                                                                       */+  /*    max_faces :: Maximum number of opened @FT_Face objects managed by  */+  /*                 this cache instance.  Use~0 for defaults.             */+  /*                                                                       */+  /*    max_sizes :: Maximum number of opened @FT_Size objects managed by  */+  /*                 this cache instance.  Use~0 for defaults.             */+  /*                                                                       */+  /*    max_bytes :: Maximum number of bytes to use for cached data nodes. */+  /*                 Use~0 for defaults.  Note that this value does not    */+  /*                 account for managed @FT_Face and @FT_Size objects.    */+  /*                                                                       */+  /*    requester :: An application-provided callback used to translate    */+  /*                 face IDs into real @FT_Face objects.                  */+  /*                                                                       */+  /*    req_data  :: A generic pointer that is passed to the requester     */+  /*                 each time it is called (see @FTC_Face_Requester).     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    amanager  :: A handle to a new manager object.  0~in case of       */+  /*                 failure.                                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_Manager_New( FT_Library          library,+                   FT_UInt             max_faces,+                   FT_UInt             max_sizes,+                   FT_ULong            max_bytes,+                   FTC_Face_Requester  requester,+                   FT_Pointer          req_data,+                   FTC_Manager        *amanager );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_Reset                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Empty a given cache manager.  This simply gets rid of all the      */+  /*    currently cached @FT_Face and @FT_Size objects within the manager. */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    manager :: A handle to the manager.                                */+  /*                                                                       */+  FT_EXPORT( void )+  FTC_Manager_Reset( FTC_Manager  manager );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_Done                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy a given manager after emptying it.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    manager :: A handle to the target cache manager object.            */+  /*                                                                       */+  FT_EXPORT( void )+  FTC_Manager_Done( FTC_Manager  manager );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_LookupFace                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the @FT_Face object that corresponds to a given face ID   */+  /*    through a cache manager.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    manager :: A handle to the cache manager.                          */+  /*                                                                       */+  /*    face_id :: The ID of the face object.                              */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aface   :: A handle to the face object.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The returned @FT_Face object is always owned by the manager.  You  */+  /*    should never try to discard it yourself.                           */+  /*                                                                       */+  /*    The @FT_Face object doesn't necessarily have a current size object */+  /*    (i.e., face->size can be 0).  If you need a specific `font size',  */+  /*    use @FTC_Manager_LookupSize instead.                               */+  /*                                                                       */+  /*    Never change the face's transformation matrix (i.e., never call    */+  /*    the @FT_Set_Transform function) on a returned face!  If you need   */+  /*    to transform glyphs, do it yourself after glyph loading.           */+  /*                                                                       */+  /*    When you perform a lookup, out-of-memory errors are detected       */+  /*    _within_ the lookup and force incremental flushes of the cache     */+  /*    until enough memory is released for the lookup to succeed.         */+  /*                                                                       */+  /*    If a lookup fails with `FT_Err_Out_Of_Memory' the cache has        */+  /*    already been completely flushed, and still no memory was available */+  /*    for the operation.                                                 */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_Manager_LookupFace( FTC_Manager  manager,+                          FTC_FaceID   face_id,+                          FT_Face     *aface );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FTC_ScalerRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to describe a given character size in either      */+  /*    pixels or points to the cache manager.  See                        */+  /*    @FTC_Manager_LookupSize.                                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    face_id :: The source face ID.                                     */+  /*                                                                       */+  /*    width   :: The character width.                                    */+  /*                                                                       */+  /*    height  :: The character height.                                   */+  /*                                                                       */+  /*    pixel   :: A Boolean.  If 1, the `width' and `height' fields are   */+  /*               interpreted as integer pixel character sizes.           */+  /*               Otherwise, they are expressed as 1/64th of points.      */+  /*                                                                       */+  /*    x_res   :: Only used when `pixel' is value~0 to indicate the       */+  /*               horizontal resolution in dpi.                           */+  /*                                                                       */+  /*    y_res   :: Only used when `pixel' is value~0 to indicate the       */+  /*               vertical resolution in dpi.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This type is mainly used to retrieve @FT_Size objects through the  */+  /*    cache manager.                                                     */+  /*                                                                       */+  typedef struct  FTC_ScalerRec_+  {+    FTC_FaceID  face_id;+    FT_UInt     width;+    FT_UInt     height;+    FT_Int      pixel;+    FT_UInt     x_res;+    FT_UInt     y_res;++  } FTC_ScalerRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FTC_Scaler                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an @FTC_ScalerRec structure.                           */+  /*                                                                       */+  typedef struct FTC_ScalerRec_*  FTC_Scaler;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_LookupSize                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the @FT_Size object that corresponds to a given           */+  /*    @FTC_ScalerRec pointer through a cache manager.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    manager :: A handle to the cache manager.                          */+  /*                                                                       */+  /*    scaler  :: A scaler handle.                                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    asize   :: A handle to the size object.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The returned @FT_Size object is always owned by the manager.  You  */+  /*    should never try to discard it by yourself.                        */+  /*                                                                       */+  /*    You can access the parent @FT_Face object simply as `size->face'   */+  /*    if you need it.  Note that this object is also owned by the        */+  /*    manager.                                                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    When you perform a lookup, out-of-memory errors are detected       */+  /*    _within_ the lookup and force incremental flushes of the cache     */+  /*    until enough memory is released for the lookup to succeed.         */+  /*                                                                       */+  /*    If a lookup fails with `FT_Err_Out_Of_Memory' the cache has        */+  /*    already been completely flushed, and still no memory is available  */+  /*    for the operation.                                                 */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_Manager_LookupSize( FTC_Manager  manager,+                          FTC_Scaler   scaler,+                          FT_Size     *asize );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Node_Unref                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Decrement a cache node's internal reference count.  When the count */+  /*    reaches 0, it is not destroyed but becomes eligible for subsequent */+  /*    cache flushes.                                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    node    :: The cache node handle.                                  */+  /*                                                                       */+  /*    manager :: The cache manager handle.                               */+  /*                                                                       */+  FT_EXPORT( void )+  FTC_Node_Unref( FTC_Node     node,+                  FTC_Manager  manager );+++  /*************************************************************************+   *+   * @function:+   *   FTC_Manager_RemoveFaceID+   *+   * @description:+   *   A special function used to indicate to the cache manager that+   *   a given @FTC_FaceID is no longer valid, either because its+   *   content changed, or because it was deallocated or uninstalled.+   *+   * @input:+   *   manager ::+   *     The cache manager handle.+   *+   *   face_id ::+   *     The @FTC_FaceID to be removed.+   *+   * @note:+   *   This function flushes all nodes from the cache corresponding to this+   *   `face_id', with the exception of nodes with a non-null reference+   *   count.+   *+   *   Such nodes are however modified internally so as to never appear+   *   in later lookups with the same `face_id' value, and to be immediately+   *   destroyed when released by all their users.+   *+   */+  FT_EXPORT( void )+  FTC_Manager_RemoveFaceID( FTC_Manager  manager,+                            FTC_FaceID   face_id );+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    cache_subsystem                                                    */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************+   *+   * @type:+   *   FTC_CMapCache+   *+   * @description:+   *   An opaque handle used to model a charmap cache.  This cache is to+   *   hold character codes -> glyph indices mappings.+   *+   */+  typedef struct FTC_CMapCacheRec_*  FTC_CMapCache;+++  /*************************************************************************+   *+   * @function:+   *   FTC_CMapCache_New+   *+   * @description:+   *   Create a new charmap cache.+   *+   * @input:+   *   manager ::+   *     A handle to the cache manager.+   *+   * @output:+   *   acache ::+   *     A new cache handle.  NULL in case of error.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   Like all other caches, this one will be destroyed with the cache+   *   manager.+   *+   */+  FT_EXPORT( FT_Error )+  FTC_CMapCache_New( FTC_Manager     manager,+                     FTC_CMapCache  *acache );+++  /************************************************************************+   *+   * @function:+   *   FTC_CMapCache_Lookup+   *+   * @description:+   *   Translate a character code into a glyph index, using the charmap+   *   cache.+   *+   * @input:+   *   cache ::+   *     A charmap cache handle.+   *+   *   face_id ::+   *     The source face ID.+   *+   *   cmap_index ::+   *     The index of the charmap in the source face.  Any negative value+   *     means to use the cache @FT_Face's default charmap.+   *+   *   char_code ::+   *     The character code (in the corresponding charmap).+   *+   * @return:+   *    Glyph index.  0~means `no glyph'.+   *+   */+  FT_EXPORT( FT_UInt )+  FTC_CMapCache_Lookup( FTC_CMapCache  cache,+                        FTC_FaceID     face_id,+                        FT_Int         cmap_index,+                        FT_UInt32      char_code );+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    cache_subsystem                                                    */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       IMAGE CACHE OBJECT                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************+   *+   * @struct:+   *   FTC_ImageTypeRec+   *+   * @description:+   *   A structure used to model the type of images in a glyph cache.+   *+   * @fields:+   *   face_id ::+   *     The face ID.+   *+   *   width ::+   *     The width in pixels.+   *+   *   height ::+   *     The height in pixels.+   *+   *   flags ::+   *     The load flags, as in @FT_Load_Glyph.+   *+   */+  typedef struct  FTC_ImageTypeRec_+  {+    FTC_FaceID  face_id;+    FT_Int      width;+    FT_Int      height;+    FT_Int32    flags;++  } FTC_ImageTypeRec;+++  /*************************************************************************+   *+   * @type:+   *   FTC_ImageType+   *+   * @description:+   *   A handle to an @FTC_ImageTypeRec structure.+   *+   */+  typedef struct FTC_ImageTypeRec_*  FTC_ImageType;+++  /* */+++#define FTC_IMAGE_TYPE_COMPARE( d1, d2 )      \+          ( (d1)->face_id == (d2)->face_id && \+            (d1)->width   == (d2)->width   && \+            (d1)->flags   == (d2)->flags   )++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /* this macro is incompatible with LLP64, should not be used */++#define FTC_IMAGE_TYPE_HASH( d )                          \+          (FT_UFast)( FTC_FACE_ID_HASH( (d)->face_id )  ^ \+                      ( (d)->width << 8 ) ^ (d)->height ^ \+                      ( (d)->flags << 4 )               )++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FTC_ImageCache                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an glyph image cache object.  They are designed to     */+  /*    hold many distinct glyph images while not exceeding a certain      */+  /*    memory threshold.                                                  */+  /*                                                                       */+  typedef struct FTC_ImageCacheRec_*  FTC_ImageCache;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_ImageCache_New                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new glyph image cache.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    manager :: The parent manager for the image cache.                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    acache  :: A handle to the new glyph image cache object.           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_ImageCache_New( FTC_Manager      manager,+                      FTC_ImageCache  *acache );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_ImageCache_Lookup                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve a given glyph image from a glyph image cache.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    cache  :: A handle to the source glyph image cache.                */+  /*                                                                       */+  /*    type   :: A pointer to a glyph image type descriptor.              */+  /*                                                                       */+  /*    gindex :: The glyph index to retrieve.                             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aglyph :: The corresponding @FT_Glyph object.  0~in case of        */+  /*              failure.                                                 */+  /*                                                                       */+  /*    anode  :: Used to return the address of of the corresponding cache */+  /*              node after incrementing its reference count (see note    */+  /*              below).                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The returned glyph is owned and managed by the glyph image cache.  */+  /*    Never try to transform or discard it manually!  You can however    */+  /*    create a copy with @FT_Glyph_Copy and modify the new one.          */+  /*                                                                       */+  /*    If `anode' is _not_ NULL, it receives the address of the cache     */+  /*    node containing the glyph image, after increasing its reference    */+  /*    count.  This ensures that the node (as well as the @FT_Glyph) will */+  /*    always be kept in the cache until you call @FTC_Node_Unref to      */+  /*    `release' it.                                                      */+  /*                                                                       */+  /*    If `anode' is NULL, the cache node is left unchanged, which means  */+  /*    that the @FT_Glyph could be flushed out of the cache on the next   */+  /*    call to one of the caching sub-system APIs.  Don't assume that it  */+  /*    is persistent!                                                     */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_ImageCache_Lookup( FTC_ImageCache  cache,+                         FTC_ImageType   type,+                         FT_UInt         gindex,+                         FT_Glyph       *aglyph,+                         FTC_Node       *anode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_ImageCache_LookupScaler                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec    */+  /*    to specify the face ID and its size.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    cache      :: A handle to the source glyph image cache.            */+  /*                                                                       */+  /*    scaler     :: A pointer to a scaler descriptor.                    */+  /*                                                                       */+  /*    load_flags :: The corresponding load flags.                        */+  /*                                                                       */+  /*    gindex     :: The glyph index to retrieve.                         */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aglyph     :: The corresponding @FT_Glyph object.  0~in case of    */+  /*                  failure.                                             */+  /*                                                                       */+  /*    anode      :: Used to return the address of of the corresponding   */+  /*                  cache node after incrementing its reference count    */+  /*                  (see note below).                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The returned glyph is owned and managed by the glyph image cache.  */+  /*    Never try to transform or discard it manually!  You can however    */+  /*    create a copy with @FT_Glyph_Copy and modify the new one.          */+  /*                                                                       */+  /*    If `anode' is _not_ NULL, it receives the address of the cache     */+  /*    node containing the glyph image, after increasing its reference    */+  /*    count.  This ensures that the node (as well as the @FT_Glyph) will */+  /*    always be kept in the cache until you call @FTC_Node_Unref to      */+  /*    `release' it.                                                      */+  /*                                                                       */+  /*    If `anode' is NULL, the cache node is left unchanged, which means  */+  /*    that the @FT_Glyph could be flushed out of the cache on the next   */+  /*    call to one of the caching sub-system APIs.  Don't assume that it  */+  /*    is persistent!                                                     */+  /*                                                                       */+  /*    Calls to @FT_Set_Char_Size and friends have no effect on cached    */+  /*    glyphs; you should always use the FreeType cache API instead.      */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,+                               FTC_Scaler      scaler,+                               FT_ULong        load_flags,+                               FT_UInt         gindex,+                               FT_Glyph       *aglyph,+                               FTC_Node       *anode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FTC_SBit                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a small bitmap descriptor.  See the @FTC_SBitRec       */+  /*    structure for details.                                             */+  /*                                                                       */+  typedef struct FTC_SBitRec_*  FTC_SBit;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FTC_SBitRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very compact structure used to describe a small glyph bitmap.    */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    width     :: The bitmap width in pixels.                           */+  /*                                                                       */+  /*    height    :: The bitmap height in pixels.                          */+  /*                                                                       */+  /*    left      :: The horizontal distance from the pen position to the  */+  /*                 left bitmap border (a.k.a. `left side bearing', or    */+  /*                 `lsb').                                               */+  /*                                                                       */+  /*    top       :: The vertical distance from the pen position (on the   */+  /*                 baseline) to the upper bitmap border (a.k.a. `top     */+  /*                 side bearing').  The distance is positive for upwards */+  /*                 y~coordinates.                                        */+  /*                                                                       */+  /*    format    :: The format of the glyph bitmap (monochrome or gray).  */+  /*                                                                       */+  /*    max_grays :: Maximum gray level value (in the range 1 to~255).     */+  /*                                                                       */+  /*    pitch     :: The number of bytes per bitmap line.  May be positive */+  /*                 or negative.                                          */+  /*                                                                       */+  /*    xadvance  :: The horizontal advance width in pixels.               */+  /*                                                                       */+  /*    yadvance  :: The vertical advance height in pixels.                */+  /*                                                                       */+  /*    buffer    :: A pointer to the bitmap pixels.                       */+  /*                                                                       */+  typedef struct  FTC_SBitRec_+  {+    FT_Byte   width;+    FT_Byte   height;+    FT_Char   left;+    FT_Char   top;++    FT_Byte   format;+    FT_Byte   max_grays;+    FT_Short  pitch;+    FT_Char   xadvance;+    FT_Char   yadvance;++    FT_Byte*  buffer;++  } FTC_SBitRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FTC_SBitCache                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a small bitmap cache.  These are special cache objects */+  /*    used to store small glyph bitmaps (and anti-aliased pixmaps) in a  */+  /*    much more efficient way than the traditional glyph image cache     */+  /*    implemented by @FTC_ImageCache.                                    */+  /*                                                                       */+  typedef struct FTC_SBitCacheRec_*  FTC_SBitCache;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_SBitCache_New                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new cache to store small glyph bitmaps.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    manager :: A handle to the source cache manager.                   */+  /*                                                                       */+  /* <Output>                                                              */+  /*    acache  :: A handle to the new sbit cache.  NULL in case of error. */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_SBitCache_New( FTC_Manager     manager,+                     FTC_SBitCache  *acache );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_SBitCache_Lookup                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Look up a given small glyph bitmap in a given sbit cache and       */+  /*    `lock' it to prevent its flushing from the cache until needed.     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    cache  :: A handle to the source sbit cache.                       */+  /*                                                                       */+  /*    type   :: A pointer to the glyph image type descriptor.            */+  /*                                                                       */+  /*    gindex :: The glyph index.                                         */+  /*                                                                       */+  /* <Output>                                                              */+  /*    sbit   :: A handle to a small bitmap descriptor.                   */+  /*                                                                       */+  /*    anode  :: Used to return the address of of the corresponding cache */+  /*              node after incrementing its reference count (see note    */+  /*              below).                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The small bitmap descriptor and its bit buffer are owned by the    */+  /*    cache and should never be freed by the application.  They might    */+  /*    as well disappear from memory on the next cache lookup, so don't   */+  /*    treat them as persistent data.                                     */+  /*                                                                       */+  /*    The descriptor's `buffer' field is set to~0 to indicate a missing  */+  /*    glyph bitmap.                                                      */+  /*                                                                       */+  /*    If `anode' is _not_ NULL, it receives the address of the cache     */+  /*    node containing the bitmap, after increasing its reference count.  */+  /*    This ensures that the node (as well as the image) will always be   */+  /*    kept in the cache until you call @FTC_Node_Unref to `release' it.  */+  /*                                                                       */+  /*    If `anode' is NULL, the cache node is left unchanged, which means  */+  /*    that the bitmap could be flushed out of the cache on the next      */+  /*    call to one of the caching sub-system APIs.  Don't assume that it  */+  /*    is persistent!                                                     */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_SBitCache_Lookup( FTC_SBitCache    cache,+                        FTC_ImageType    type,+                        FT_UInt          gindex,+                        FTC_SBit        *sbit,+                        FTC_Node        *anode );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_SBitCache_LookupScaler                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec     */+  /*    to specify the face ID and its size.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    cache      :: A handle to the source sbit cache.                   */+  /*                                                                       */+  /*    scaler     :: A pointer to the scaler descriptor.                  */+  /*                                                                       */+  /*    load_flags :: The corresponding load flags.                        */+  /*                                                                       */+  /*    gindex     :: The glyph index.                                     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    sbit       :: A handle to a small bitmap descriptor.               */+  /*                                                                       */+  /*    anode      :: Used to return the address of of the corresponding   */+  /*                  cache node after incrementing its reference count    */+  /*                  (see note below).                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The small bitmap descriptor and its bit buffer are owned by the    */+  /*    cache and should never be freed by the application.  They might    */+  /*    as well disappear from memory on the next cache lookup, so don't   */+  /*    treat them as persistent data.                                     */+  /*                                                                       */+  /*    The descriptor's `buffer' field is set to~0 to indicate a missing  */+  /*    glyph bitmap.                                                      */+  /*                                                                       */+  /*    If `anode' is _not_ NULL, it receives the address of the cache     */+  /*    node containing the bitmap, after increasing its reference count.  */+  /*    This ensures that the node (as well as the image) will always be   */+  /*    kept in the cache until you call @FTC_Node_Unref to `release' it.  */+  /*                                                                       */+  /*    If `anode' is NULL, the cache node is left unchanged, which means  */+  /*    that the bitmap could be flushed out of the cache on the next      */+  /*    call to one of the caching sub-system APIs.  Don't assume that it  */+  /*    is persistent!                                                     */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,+                              FTC_Scaler     scaler,+                              FT_ULong       load_flags,+                              FT_UInt        gindex,+                              FTC_SBit      *sbit,+                              FTC_Node      *anode );+++ /* */++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*@***********************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FTC_FontRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to describe a given `font' to the cache    */+  /*    manager.  Note that a `font' is the combination of a given face    */+  /*    with a given character size.                                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    face_id    :: The ID of the face to use.                           */+  /*                                                                       */+  /*    pix_width  :: The character width in integer pixels.               */+  /*                                                                       */+  /*    pix_height :: The character height in integer pixels.              */+  /*                                                                       */+  typedef struct  FTC_FontRec_+  {+    FTC_FaceID  face_id;+    FT_UShort   pix_width;+    FT_UShort   pix_height;++  } FTC_FontRec;+++  /* */+++#define FTC_FONT_COMPARE( f1, f2 )                  \+          ( (f1)->face_id    == (f2)->face_id    && \+            (f1)->pix_width  == (f2)->pix_width  && \+            (f1)->pix_height == (f2)->pix_height )++  /* this macro is incompatible with LLP64, should not be used */+#define FTC_FONT_HASH( f )                              \+          (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \+                       ((f)->pix_width << 8)          ^ \+                       ((f)->pix_height)              )++  typedef FTC_FontRec*  FTC_Font;+++  FT_EXPORT( FT_Error )+  FTC_Manager_Lookup_Face( FTC_Manager  manager,+                           FTC_FaceID   face_id,+                           FT_Face     *aface );++  FT_EXPORT( FT_Error )+  FTC_Manager_Lookup_Size( FTC_Manager  manager,+                           FTC_Font     font,+                           FT_Face     *aface,+                           FT_Size     *asize );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++ /* */++FT_END_HEADER++#endif /* __FTCACHE_H__ */+++/* END */
+ include/freetype/ftchapters.h view
@@ -0,0 +1,103 @@+/***************************************************************************/+/*                                                                         */+/* This file defines the structure of the FreeType reference.              */+/* It is used by the python script which generates the HTML files.         */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* <Chapter>                                                               */+/*    general_remarks                                                      */+/*                                                                         */+/* <Title>                                                                 */+/*    General Remarks                                                      */+/*                                                                         */+/* <Sections>                                                              */+/*    user_allocation                                                      */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* <Chapter>                                                               */+/*    core_api                                                             */+/*                                                                         */+/* <Title>                                                                 */+/*    Core API                                                             */+/*                                                                         */+/* <Sections>                                                              */+/*    version                                                              */+/*    basic_types                                                          */+/*    base_interface                                                       */+/*    glyph_variants                                                       */+/*    glyph_management                                                     */+/*    mac_specific                                                         */+/*    sizes_management                                                     */+/*    header_file_macros                                                   */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* <Chapter>                                                               */+/*    format_specific                                                      */+/*                                                                         */+/* <Title>                                                                 */+/*    Format-Specific API                                                  */+/*                                                                         */+/* <Sections>                                                              */+/*    multiple_masters                                                     */+/*    truetype_tables                                                      */+/*    type1_tables                                                         */+/*    sfnt_names                                                           */+/*    bdf_fonts                                                            */+/*    cid_fonts                                                            */+/*    pfr_fonts                                                            */+/*    winfnt_fonts                                                         */+/*    font_formats                                                         */+/*    gasp_table                                                           */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* <Chapter>                                                               */+/*    cache_subsystem                                                      */+/*                                                                         */+/* <Title>                                                                 */+/*    Cache Sub-System                                                     */+/*                                                                         */+/* <Sections>                                                              */+/*    cache_subsystem                                                      */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* <Chapter>                                                               */+/*    support_api                                                          */+/*                                                                         */+/* <Title>                                                                 */+/*    Support API                                                          */+/*                                                                         */+/* <Sections>                                                              */+/*    computations                                                         */+/*    list_processing                                                      */+/*    outline_processing                                                   */+/*    quick_advance                                                        */+/*    bitmap_handling                                                      */+/*    raster                                                               */+/*    glyph_stroker                                                        */+/*    system_interface                                                     */+/*    module_management                                                    */+/*    gzip                                                                 */+/*    lzw                                                                  */+/*    lcd_filtering                                                        */+/*                                                                         */+/***************************************************************************/
+ include/freetype/ftcid.h view
@@ -0,0 +1,166 @@+/***************************************************************************/+/*                                                                         */+/*  ftcid.h                                                                */+/*                                                                         */+/*    FreeType API for accessing CID font information (specification).     */+/*                                                                         */+/*  Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal.                  */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTCID_H__+#define __FTCID_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    cid_fonts                                                          */+  /*                                                                       */+  /* <Title>                                                               */+  /*    CID Fonts                                                          */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    CID-keyed font specific API.                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of CID-keyed font specific   */+  /*    functions.                                                         */+  /*                                                                       */+  /*************************************************************************/+++  /**********************************************************************+   *+   * @function:+   *    FT_Get_CID_Registry_Ordering_Supplement+   *+   * @description:+   *    Retrieve the Registry/Ordering/Supplement triple (also known as the+   *    "R/O/S") from a CID-keyed font.+   *+   * @input:+   *    face ::+   *       A handle to the input face.+   *+   * @output:+   *    registry ::+   *       The registry, as a C~string, owned by the face.+   *+   *    ordering ::+   *       The ordering, as a C~string, owned by the face.+   *+   *    supplement ::+   *       The supplement.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *    This function only works with CID faces, returning an error+   *    otherwise.+   *+   * @since:+   *    2.3.6+   */+  FT_EXPORT( FT_Error )+  FT_Get_CID_Registry_Ordering_Supplement( FT_Face       face,+                                           const char*  *registry,+                                           const char*  *ordering,+                                           FT_Int       *supplement);+++  /**********************************************************************+   *+   * @function:+   *    FT_Get_CID_Is_Internally_CID_Keyed+   *+   * @description:+   *    Retrieve the type of the input face, CID keyed or not.  In+   *    constrast to the @FT_IS_CID_KEYED macro this function returns+   *    successfully also for CID-keyed fonts in an SNFT wrapper.+   *+   * @input:+   *    face ::+   *       A handle to the input face.+   *+   * @output:+   *    is_cid ::+   *       The type of the face as an @FT_Bool.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *    This function only works with CID faces and OpenType fonts,+   *    returning an error otherwise.+   *+   * @since:+   *    2.3.9+   */+  FT_EXPORT( FT_Error )+  FT_Get_CID_Is_Internally_CID_Keyed( FT_Face   face,+                                      FT_Bool  *is_cid );+++  /**********************************************************************+   *+   * @function:+   *    FT_Get_CID_From_Glyph_Index+   *+   * @description:+   *    Retrieve the CID of the input glyph index.+   *+   * @input:+   *    face ::+   *       A handle to the input face.+   *+   *    glyph_index ::+   *       The input glyph index.+   *+   * @output:+   *    cid ::+   *       The CID as an @FT_UInt.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *    This function only works with CID faces and OpenType fonts,+   *    returning an error otherwise.+   *+   * @since:+   *    2.3.9+   */+  FT_EXPORT( FT_Error )+  FT_Get_CID_From_Glyph_Index( FT_Face   face,+                               FT_UInt   glyph_index,+                               FT_UInt  *cid );++ /* */++FT_END_HEADER++#endif /* __FTCID_H__ */+++/* END */
+ include/freetype/fterrdef.h view
@@ -0,0 +1,244 @@+/***************************************************************************/+/*                                                                         */+/*  fterrdef.h                                                             */+/*                                                                         */+/*    FreeType error codes (specification).                                */+/*                                                                         */+/*  Copyright 2002, 2004, 2006, 2007, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****                LIST OF ERROR CODES/MESSAGES             *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/+++  /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */+  /* including this file.                                           */+++  /* generic errors */++  FT_NOERRORDEF_( Ok,                                        0x00, \+                  "no error" )++  FT_ERRORDEF_( Cannot_Open_Resource,                        0x01, \+                "cannot open resource" )+  FT_ERRORDEF_( Unknown_File_Format,                         0x02, \+                "unknown file format" )+  FT_ERRORDEF_( Invalid_File_Format,                         0x03, \+                "broken file" )+  FT_ERRORDEF_( Invalid_Version,                             0x04, \+                "invalid FreeType version" )+  FT_ERRORDEF_( Lower_Module_Version,                        0x05, \+                "module version is too low" )+  FT_ERRORDEF_( Invalid_Argument,                            0x06, \+                "invalid argument" )+  FT_ERRORDEF_( Unimplemented_Feature,                       0x07, \+                "unimplemented feature" )+  FT_ERRORDEF_( Invalid_Table,                               0x08, \+                "broken table" )+  FT_ERRORDEF_( Invalid_Offset,                              0x09, \+                "broken offset within table" )+  FT_ERRORDEF_( Array_Too_Large,                             0x0A, \+                "array allocation size too large" )++  /* glyph/character errors */++  FT_ERRORDEF_( Invalid_Glyph_Index,                         0x10, \+                "invalid glyph index" )+  FT_ERRORDEF_( Invalid_Character_Code,                      0x11, \+                "invalid character code" )+  FT_ERRORDEF_( Invalid_Glyph_Format,                        0x12, \+                "unsupported glyph image format" )+  FT_ERRORDEF_( Cannot_Render_Glyph,                         0x13, \+                "cannot render this glyph format" )+  FT_ERRORDEF_( Invalid_Outline,                             0x14, \+                "invalid outline" )+  FT_ERRORDEF_( Invalid_Composite,                           0x15, \+                "invalid composite glyph" )+  FT_ERRORDEF_( Too_Many_Hints,                              0x16, \+                "too many hints" )+  FT_ERRORDEF_( Invalid_Pixel_Size,                          0x17, \+                "invalid pixel size" )++  /* handle errors */++  FT_ERRORDEF_( Invalid_Handle,                              0x20, \+                "invalid object handle" )+  FT_ERRORDEF_( Invalid_Library_Handle,                      0x21, \+                "invalid library handle" )+  FT_ERRORDEF_( Invalid_Driver_Handle,                       0x22, \+                "invalid module handle" )+  FT_ERRORDEF_( Invalid_Face_Handle,                         0x23, \+                "invalid face handle" )+  FT_ERRORDEF_( Invalid_Size_Handle,                         0x24, \+                "invalid size handle" )+  FT_ERRORDEF_( Invalid_Slot_Handle,                         0x25, \+                "invalid glyph slot handle" )+  FT_ERRORDEF_( Invalid_CharMap_Handle,                      0x26, \+                "invalid charmap handle" )+  FT_ERRORDEF_( Invalid_Cache_Handle,                        0x27, \+                "invalid cache manager handle" )+  FT_ERRORDEF_( Invalid_Stream_Handle,                       0x28, \+                "invalid stream handle" )++  /* driver errors */++  FT_ERRORDEF_( Too_Many_Drivers,                            0x30, \+                "too many modules" )+  FT_ERRORDEF_( Too_Many_Extensions,                         0x31, \+                "too many extensions" )++  /* memory errors */++  FT_ERRORDEF_( Out_Of_Memory,                               0x40, \+                "out of memory" )+  FT_ERRORDEF_( Unlisted_Object,                             0x41, \+                "unlisted object" )++  /* stream errors */++  FT_ERRORDEF_( Cannot_Open_Stream,                          0x51, \+                "cannot open stream" )+  FT_ERRORDEF_( Invalid_Stream_Seek,                         0x52, \+                "invalid stream seek" )+  FT_ERRORDEF_( Invalid_Stream_Skip,                         0x53, \+                "invalid stream skip" )+  FT_ERRORDEF_( Invalid_Stream_Read,                         0x54, \+                "invalid stream read" )+  FT_ERRORDEF_( Invalid_Stream_Operation,                    0x55, \+                "invalid stream operation" )+  FT_ERRORDEF_( Invalid_Frame_Operation,                     0x56, \+                "invalid frame operation" )+  FT_ERRORDEF_( Nested_Frame_Access,                         0x57, \+                "nested frame access" )+  FT_ERRORDEF_( Invalid_Frame_Read,                          0x58, \+                "invalid frame read" )++  /* raster errors */++  FT_ERRORDEF_( Raster_Uninitialized,                        0x60, \+                "raster uninitialized" )+  FT_ERRORDEF_( Raster_Corrupted,                            0x61, \+                "raster corrupted" )+  FT_ERRORDEF_( Raster_Overflow,                             0x62, \+                "raster overflow" )+  FT_ERRORDEF_( Raster_Negative_Height,                      0x63, \+                "negative height while rastering" )++  /* cache errors */++  FT_ERRORDEF_( Too_Many_Caches,                             0x70, \+                "too many registered caches" )++  /* TrueType and SFNT errors */++  FT_ERRORDEF_( Invalid_Opcode,                              0x80, \+                "invalid opcode" )+  FT_ERRORDEF_( Too_Few_Arguments,                           0x81, \+                "too few arguments" )+  FT_ERRORDEF_( Stack_Overflow,                              0x82, \+                "stack overflow" )+  FT_ERRORDEF_( Code_Overflow,                               0x83, \+                "code overflow" )+  FT_ERRORDEF_( Bad_Argument,                                0x84, \+                "bad argument" )+  FT_ERRORDEF_( Divide_By_Zero,                              0x85, \+                "division by zero" )+  FT_ERRORDEF_( Invalid_Reference,                           0x86, \+                "invalid reference" )+  FT_ERRORDEF_( Debug_OpCode,                                0x87, \+                "found debug opcode" )+  FT_ERRORDEF_( ENDF_In_Exec_Stream,                         0x88, \+                "found ENDF opcode in execution stream" )+  FT_ERRORDEF_( Nested_DEFS,                                 0x89, \+                "nested DEFS" )+  FT_ERRORDEF_( Invalid_CodeRange,                           0x8A, \+                "invalid code range" )+  FT_ERRORDEF_( Execution_Too_Long,                          0x8B, \+                "execution context too long" )+  FT_ERRORDEF_( Too_Many_Function_Defs,                      0x8C, \+                "too many function definitions" )+  FT_ERRORDEF_( Too_Many_Instruction_Defs,                   0x8D, \+                "too many instruction definitions" )+  FT_ERRORDEF_( Table_Missing,                               0x8E, \+                "SFNT font table missing" )+  FT_ERRORDEF_( Horiz_Header_Missing,                        0x8F, \+                "horizontal header (hhea) table missing" )+  FT_ERRORDEF_( Locations_Missing,                           0x90, \+                "locations (loca) table missing" )+  FT_ERRORDEF_( Name_Table_Missing,                          0x91, \+                "name table missing" )+  FT_ERRORDEF_( CMap_Table_Missing,                          0x92, \+                "character map (cmap) table missing" )+  FT_ERRORDEF_( Hmtx_Table_Missing,                          0x93, \+                "horizontal metrics (hmtx) table missing" )+  FT_ERRORDEF_( Post_Table_Missing,                          0x94, \+                "PostScript (post) table missing" )+  FT_ERRORDEF_( Invalid_Horiz_Metrics,                       0x95, \+                "invalid horizontal metrics" )+  FT_ERRORDEF_( Invalid_CharMap_Format,                      0x96, \+                "invalid character map (cmap) format" )+  FT_ERRORDEF_( Invalid_PPem,                                0x97, \+                "invalid ppem value" )+  FT_ERRORDEF_( Invalid_Vert_Metrics,                        0x98, \+                "invalid vertical metrics" )+  FT_ERRORDEF_( Could_Not_Find_Context,                      0x99, \+                "could not find context" )+  FT_ERRORDEF_( Invalid_Post_Table_Format,                   0x9A, \+                "invalid PostScript (post) table format" )+  FT_ERRORDEF_( Invalid_Post_Table,                          0x9B, \+                "invalid PostScript (post) table" )++  /* CFF, CID, and Type 1 errors */++  FT_ERRORDEF_( Syntax_Error,                                0xA0, \+                "opcode syntax error" )+  FT_ERRORDEF_( Stack_Underflow,                             0xA1, \+                "argument stack underflow" )+  FT_ERRORDEF_( Ignore,                                      0xA2, \+                "ignore" )+  FT_ERRORDEF_( No_Unicode_Glyph_Name,                       0xA3, \+                "no Unicode glyph name found" )+++  /* BDF errors */++  FT_ERRORDEF_( Missing_Startfont_Field,                     0xB0, \+                "`STARTFONT' field missing" )+  FT_ERRORDEF_( Missing_Font_Field,                          0xB1, \+                "`FONT' field missing" )+  FT_ERRORDEF_( Missing_Size_Field,                          0xB2, \+                "`SIZE' field missing" )+  FT_ERRORDEF_( Missing_Fontboundingbox_Field,               0xB3, \+                "`FONTBOUNDINGBOX' field missing" )+  FT_ERRORDEF_( Missing_Chars_Field,                         0xB4, \+                "`CHARS' field missing" )+  FT_ERRORDEF_( Missing_Startchar_Field,                     0xB5, \+                "`STARTCHAR' field missing" )+  FT_ERRORDEF_( Missing_Encoding_Field,                      0xB6, \+                "`ENCODING' field missing" )+  FT_ERRORDEF_( Missing_Bbx_Field,                           0xB7, \+                "`BBX' field missing" )+  FT_ERRORDEF_( Bbx_Too_Big,                                 0xB8, \+                "`BBX' too big" )+  FT_ERRORDEF_( Corrupted_Font_Header,                       0xB9, \+                "Font header corrupted or missing fields" )+  FT_ERRORDEF_( Corrupted_Font_Glyphs,                       0xBA, \+                "Font glyphs corrupted or missing fields" )+++/* END */
+ include/freetype/fterrors.h view
@@ -0,0 +1,206 @@+/***************************************************************************/+/*                                                                         */+/*  fterrors.h                                                             */+/*                                                                         */+/*    FreeType error code handling (specification).                        */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2007 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This special header file is used to define the handling of FT2        */+  /* enumeration constants.  It can also be used to generate error message */+  /* strings with a small macro trick explained below.                     */+  /*                                                                       */+  /* I - Error Formats                                                     */+  /* -----------------                                                     */+  /*                                                                       */+  /*   The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be   */+  /*   defined in ftoption.h in order to make the higher byte indicate     */+  /*   the module where the error has happened (this is not compatible     */+  /*   with standard builds of FreeType 2).  You can then use the macro    */+  /*   FT_ERROR_BASE macro to extract the generic error code from an       */+  /*   FT_Error value.                                                     */+  /*                                                                       */+  /*                                                                       */+  /* II - Error Message strings                                            */+  /* --------------------------                                            */+  /*                                                                       */+  /*   The error definitions below are made through special macros that    */+  /*   allow client applications to build a table of error message strings */+  /*   if they need it.  The strings are not included in a normal build of */+  /*   FreeType 2 to save space (most client applications do not use       */+  /*   them).                                                              */+  /*                                                                       */+  /*   To do so, you have to define the following macros before including  */+  /*   this file:                                                          */+  /*                                                                       */+  /*   FT_ERROR_START_LIST ::                                              */+  /*     This macro is called before anything else to define the start of  */+  /*     the error list.  It is followed by several FT_ERROR_DEF calls     */+  /*     (see below).                                                      */+  /*                                                                       */+  /*   FT_ERROR_DEF( e, v, s ) ::                                          */+  /*     This macro is called to define one single error.                  */+  /*     `e' is the error code identifier (e.g. FT_Err_Invalid_Argument).  */+  /*     `v' is the error numerical value.                                 */+  /*     `s' is the corresponding error string.                            */+  /*                                                                       */+  /*   FT_ERROR_END_LIST ::                                                */+  /*     This macro ends the list.                                         */+  /*                                                                       */+  /*   Additionally, you have to undefine __FTERRORS_H__ before #including */+  /*   this file.                                                          */+  /*                                                                       */+  /*   Here is a simple example:                                           */+  /*                                                                       */+  /*     {                                                                 */+  /*       #undef __FTERRORS_H__                                           */+  /*       #define FT_ERRORDEF( e, v, s )  { e, s },                       */+  /*       #define FT_ERROR_START_LIST     {                               */+  /*       #define FT_ERROR_END_LIST       { 0, 0 } };                     */+  /*                                                                       */+  /*       const struct                                                    */+  /*       {                                                               */+  /*         int          err_code;                                        */+  /*         const char*  err_msg;                                         */+  /*       } ft_errors[] =                                                 */+  /*                                                                       */+  /*       #include FT_ERRORS_H                                            */+  /*     }                                                                 */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTERRORS_H__+#define __FTERRORS_H__+++  /* include module base error codes */+#include FT_MODULE_ERRORS_H+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****                       SETUP MACROS                      *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/+++#undef  FT_NEED_EXTERN_C++#undef  FT_ERR_XCAT+#undef  FT_ERR_CAT++#define FT_ERR_XCAT( x, y )  x ## y+#define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )+++  /* FT_ERR_PREFIX is used as a prefix for error identifiers. */+  /* By default, we use `FT_Err_'.                            */+  /*                                                          */+#ifndef FT_ERR_PREFIX+#define FT_ERR_PREFIX  FT_Err_+#endif+++  /* FT_ERR_BASE is used as the base for module-specific errors. */+  /*                                                             */+#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS++#ifndef FT_ERR_BASE+#define FT_ERR_BASE  FT_Mod_Err_Base+#endif++#else++#undef FT_ERR_BASE+#define FT_ERR_BASE  0++#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */+++  /* If FT_ERRORDEF is not defined, we need to define a simple */+  /* enumeration type.                                         */+  /*                                                           */+#ifndef FT_ERRORDEF++#define FT_ERRORDEF( e, v, s )  e = v,+#define FT_ERROR_START_LIST     enum {+#define FT_ERROR_END_LIST       FT_ERR_CAT( FT_ERR_PREFIX, Max ) };++#ifdef __cplusplus+#define FT_NEED_EXTERN_C+  extern "C" {+#endif++#endif /* !FT_ERRORDEF */+++  /* this macro is used to define an error */+#define FT_ERRORDEF_( e, v, s )   \+          FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )++  /* this is only used for <module>_Err_Ok, which must be 0! */+#define FT_NOERRORDEF_( e, v, s ) \+          FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )+++#ifdef FT_ERROR_START_LIST+  FT_ERROR_START_LIST+#endif+++  /* now include the error codes */+#include FT_ERROR_DEFINITIONS_H+++#ifdef FT_ERROR_END_LIST+  FT_ERROR_END_LIST+#endif+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****                      SIMPLE CLEANUP                     *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/++#ifdef FT_NEED_EXTERN_C+  }+#endif++#undef FT_ERROR_START_LIST+#undef FT_ERROR_END_LIST++#undef FT_ERRORDEF+#undef FT_ERRORDEF_+#undef FT_NOERRORDEF_++#undef FT_NEED_EXTERN_C+#undef FT_ERR_CONCAT+#undef FT_ERR_BASE++  /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */+#ifndef FT_KEEP_ERR_PREFIX+#undef FT_ERR_PREFIX+#endif++#endif /* __FTERRORS_H__ */+++/* END */
+ include/freetype/ftgasp.h view
@@ -0,0 +1,120 @@+/***************************************************************************/+/*                                                                         */+/*  ftgasp.h                                                               */+/*                                                                         */+/*    Access of TrueType's `gasp' table (specification).                   */+/*                                                                         */+/*  Copyright 2007, 2008 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef _FT_GASP_H_+#define _FT_GASP_H_++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++  /***************************************************************************+   *+   * @section:+   *   gasp_table+   *+   * @title:+   *   Gasp Table+   *+   * @abstract:+   *   Retrieving TrueType `gasp' table entries.+   *+   * @description:+   *   The function @FT_Get_Gasp can be used to query a TrueType or OpenType+   *   font for specific entries in its `gasp' table, if any.  This is+   *   mainly useful when implementing native TrueType hinting with the+   *   bytecode interpreter to duplicate the Windows text rendering results.+   */++  /*************************************************************************+   *+   * @enum:+   *   FT_GASP_XXX+   *+   * @description:+   *   A list of values and/or bit-flags returned by the @FT_Get_Gasp+   *   function.+   *+   * @values:+   *   FT_GASP_NO_TABLE ::+   *     This special value means that there is no GASP table in this face.+   *     It is up to the client to decide what to do.+   *+   *   FT_GASP_DO_GRIDFIT ::+   *     Grid-fitting and hinting should be performed at the specified ppem.+   *     This *really* means TrueType bytecode interpretation.+   *+   *   FT_GASP_DO_GRAY ::+   *     Anti-aliased rendering should be performed at the specified ppem.+   *+   *   FT_GASP_SYMMETRIC_SMOOTHING ::+   *     Smoothing along multiple axes must be used with ClearType.+   *+   *   FT_GASP_SYMMETRIC_GRIDFIT ::+   *     Grid-fitting must be used with ClearType's symmetric smoothing.+   *+   * @note:+   *   `ClearType' is Microsoft's implementation of LCD rendering, partly+   *   protected by patents.+   *+   * @since:+   *   2.3.0+   */+#define FT_GASP_NO_TABLE               -1+#define FT_GASP_DO_GRIDFIT           0x01+#define FT_GASP_DO_GRAY              0x02+#define FT_GASP_SYMMETRIC_SMOOTHING  0x08+#define FT_GASP_SYMMETRIC_GRIDFIT    0x10+++  /*************************************************************************+   *+   * @func:+   *   FT_Get_Gasp+   *+   * @description:+   *   Read the `gasp' table from a TrueType or OpenType font file and+   *   return the entry corresponding to a given character pixel size.+   *+   * @input:+   *   face :: The source face handle.+   *   ppem :: The vertical character pixel size.+   *+   * @return:+   *   Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no+   *   `gasp' table in the face.+   *+   * @since:+   *   2.3.0+   */+  FT_EXPORT( FT_Int )+  FT_Get_Gasp( FT_Face  face,+               FT_UInt  ppem );++/* */++#endif /* _FT_GASP_H_ */+++/* END */
+ include/freetype/ftglyph.h view
@@ -0,0 +1,613 @@+/***************************************************************************/+/*                                                                         */+/*  ftglyph.h                                                              */+/*                                                                         */+/*    FreeType convenience functions to handle glyphs (specification).     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file contains the definition of several convenience functions    */+  /* that can be used by client applications to easily retrieve glyph      */+  /* bitmaps and outlines from a given face.                               */+  /*                                                                       */+  /* These functions should be optional if you are writing a font server   */+  /* or text layout engine on top of FreeType.  However, they are pretty   */+  /* handy for many other simple uses of the library.                      */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTGLYPH_H__+#define __FTGLYPH_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    glyph_management                                                   */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Glyph Management                                                   */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Generic interface to manage individual glyph data.                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains definitions used to manage glyph data        */+  /*    through generic FT_Glyph objects.  Each of them can contain a      */+  /*    bitmap, a vector outline, or even images in other formats.         */+  /*                                                                       */+  /*************************************************************************/+++  /* forward declaration to a private type */+  typedef struct FT_Glyph_Class_  FT_Glyph_Class;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Glyph                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Handle to an object used to model generic glyph images.  It is a   */+  /*    pointer to the @FT_GlyphRec structure and can contain a glyph      */+  /*    bitmap or pointer.                                                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Glyph objects are not owned by the library.  You must thus release */+  /*    them manually (through @FT_Done_Glyph) _before_ calling            */+  /*    @FT_Done_FreeType.                                                 */+  /*                                                                       */+  typedef struct FT_GlyphRec_*  FT_Glyph;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_GlyphRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The root glyph structure contains a given glyph image plus its     */+  /*    advance width in 16.16 fixed float format.                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    library :: A handle to the FreeType library object.                */+  /*                                                                       */+  /*    clazz   :: A pointer to the glyph's class.  Private.               */+  /*                                                                       */+  /*    format  :: The format of the glyph's image.                        */+  /*                                                                       */+  /*    advance :: A 16.16 vector that gives the glyph's advance width.    */+  /*                                                                       */+  typedef struct  FT_GlyphRec_+  {+    FT_Library             library;+    const FT_Glyph_Class*  clazz;+    FT_Glyph_Format        format;+    FT_Vector              advance;++  } FT_GlyphRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_BitmapGlyph                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an object used to model a bitmap glyph image.  This is */+  /*    a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.     */+  /*                                                                       */+  typedef struct FT_BitmapGlyphRec_*  FT_BitmapGlyph;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_BitmapGlyphRec                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used for bitmap glyph images.  This really is a        */+  /*    `sub-class' of @FT_GlyphRec.                                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root   :: The root @FT_Glyph fields.                               */+  /*                                                                       */+  /*    left   :: The left-side bearing, i.e., the horizontal distance     */+  /*              from the current pen position to the left border of the  */+  /*              glyph bitmap.                                            */+  /*                                                                       */+  /*    top    :: The top-side bearing, i.e., the vertical distance from   */+  /*              the current pen position to the top border of the glyph  */+  /*              bitmap.  This distance is positive for upwards~y!        */+  /*                                                                       */+  /*    bitmap :: A descriptor for the bitmap.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have       */+  /*    `glyph->format == FT_GLYPH_FORMAT_BITMAP'.  This lets you access   */+  /*    the bitmap's contents easily.                                      */+  /*                                                                       */+  /*    The corresponding pixel buffer is always owned by @FT_BitmapGlyph  */+  /*    and is thus created and destroyed with it.                         */+  /*                                                                       */+  typedef struct  FT_BitmapGlyphRec_+  {+    FT_GlyphRec  root;+    FT_Int       left;+    FT_Int       top;+    FT_Bitmap    bitmap;++  } FT_BitmapGlyphRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_OutlineGlyph                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an object used to model an outline glyph image.  This  */+  /*    is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */+  /*                                                                       */+  typedef struct FT_OutlineGlyphRec_*  FT_OutlineGlyph;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_OutlineGlyphRec                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used for outline (vectorial) glyph images.  This       */+  /*    really is a `sub-class' of @FT_GlyphRec.                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root    :: The root @FT_Glyph fields.                              */+  /*                                                                       */+  /*    outline :: A descriptor for the outline.                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have      */+  /*    `glyph->format == FT_GLYPH_FORMAT_OUTLINE'.  This lets you access  */+  /*    the outline's content easily.                                      */+  /*                                                                       */+  /*    As the outline is extracted from a glyph slot, its coordinates are */+  /*    expressed normally in 26.6 pixels, unless the flag                 */+  /*    @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */+  /*                                                                       */+  /*    The outline's tables are always owned by the object and are        */+  /*    destroyed with it.                                                 */+  /*                                                                       */+  typedef struct  FT_OutlineGlyphRec_+  {+    FT_GlyphRec  root;+    FT_Outline   outline;++  } FT_OutlineGlyphRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Glyph                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to extract a glyph image from a slot.  Note that   */+  /*    the created @FT_Glyph object must be released with @FT_Done_Glyph. */+  /*                                                                       */+  /* <Input>                                                               */+  /*    slot   :: A handle to the source glyph slot.                       */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aglyph :: A handle to the glyph object.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Glyph( FT_GlyphSlot  slot,+                FT_Glyph     *aglyph );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Glyph_Copy                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to copy a glyph image.  Note that the created      */+  /*    @FT_Glyph object must be released with @FT_Done_Glyph.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    source :: A handle to the source glyph object.                     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    target :: A handle to the target glyph object.  0~in case of       */+  /*              error.                                                   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Glyph_Copy( FT_Glyph   source,+                 FT_Glyph  *target );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Glyph_Transform                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Transform a glyph image if its format is scalable.                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    glyph  :: A handle to the target glyph object.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    matrix :: A pointer to a 2x2 matrix to apply.                      */+  /*                                                                       */+  /*    delta  :: A pointer to a 2d vector to apply.  Coordinates are      */+  /*              expressed in 1/64th of a pixel.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code (if not 0, the glyph format is not scalable).  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The 2x2 transformation matrix is also applied to the glyph's       */+  /*    advance vector.                                                    */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Glyph_Transform( FT_Glyph    glyph,+                      FT_Matrix*  matrix,+                      FT_Vector*  delta );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Glyph_BBox_Mode                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The mode how the values of @FT_Glyph_Get_CBox are returned.        */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_GLYPH_BBOX_UNSCALED ::                                          */+  /*      Return unscaled font units.                                      */+  /*                                                                       */+  /*    FT_GLYPH_BBOX_SUBPIXELS ::                                         */+  /*      Return unfitted 26.6 coordinates.                                */+  /*                                                                       */+  /*    FT_GLYPH_BBOX_GRIDFIT ::                                           */+  /*      Return grid-fitted 26.6 coordinates.                             */+  /*                                                                       */+  /*    FT_GLYPH_BBOX_TRUNCATE ::                                          */+  /*      Return coordinates in integer pixels.                            */+  /*                                                                       */+  /*    FT_GLYPH_BBOX_PIXELS ::                                            */+  /*      Return grid-fitted pixel coordinates.                            */+  /*                                                                       */+  typedef enum  FT_Glyph_BBox_Mode_+  {+    FT_GLYPH_BBOX_UNSCALED  = 0,+    FT_GLYPH_BBOX_SUBPIXELS = 0,+    FT_GLYPH_BBOX_GRIDFIT   = 1,+    FT_GLYPH_BBOX_TRUNCATE  = 2,+    FT_GLYPH_BBOX_PIXELS    = 3++  } FT_Glyph_BBox_Mode;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    ft_glyph_bbox_xxx                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    These constants are deprecated.  Use the corresponding             */+  /*    @FT_Glyph_BBox_Mode values instead.                                */+  /*                                                                       */+  /* <Values>                                                              */+  /*   ft_glyph_bbox_unscaled  :: See @FT_GLYPH_BBOX_UNSCALED.             */+  /*   ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS.            */+  /*   ft_glyph_bbox_gridfit   :: See @FT_GLYPH_BBOX_GRIDFIT.              */+  /*   ft_glyph_bbox_truncate  :: See @FT_GLYPH_BBOX_TRUNCATE.             */+  /*   ft_glyph_bbox_pixels    :: See @FT_GLYPH_BBOX_PIXELS.               */+  /*                                                                       */+#define ft_glyph_bbox_unscaled   FT_GLYPH_BBOX_UNSCALED+#define ft_glyph_bbox_subpixels  FT_GLYPH_BBOX_SUBPIXELS+#define ft_glyph_bbox_gridfit    FT_GLYPH_BBOX_GRIDFIT+#define ft_glyph_bbox_truncate   FT_GLYPH_BBOX_TRUNCATE+#define ft_glyph_bbox_pixels     FT_GLYPH_BBOX_PIXELS+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Glyph_Get_CBox                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a glyph's `control box'.  The control box encloses all the  */+  /*    outline's points, including Bézier control points.  Though it      */+  /*    coincides with the exact bounding box for most glyphs, it can be   */+  /*    slightly larger in some situations (like when rotating an outline  */+  /*    which contains Bézier outside arcs).                               */+  /*                                                                       */+  /*    Computing the control box is very fast, while getting the bounding */+  /*    box can take much more time as it needs to walk over all segments  */+  /*    and arcs in the outline.  To get the latter, you can use the       */+  /*    `ftbbox' component which is dedicated to this single task.         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    glyph :: A handle to the source glyph object.                      */+  /*                                                                       */+  /*    mode  :: The mode which indicates how to interpret the returned    */+  /*             bounding box values.                                      */+  /*                                                                       */+  /* <Output>                                                              */+  /*    acbox :: The glyph coordinate bounding box.  Coordinates are       */+  /*             expressed in 1/64th of pixels if it is grid-fitted.       */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Coordinates are relative to the glyph origin, using the y~upwards  */+  /*    convention.                                                        */+  /*                                                                       */+  /*    If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode'   */+  /*    must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font        */+  /*    units in 26.6 pixel format.  The value @FT_GLYPH_BBOX_SUBPIXELS    */+  /*    is another name for this constant.                                 */+  /*                                                                       */+  /*    Note that the maximum coordinates are exclusive, which means that  */+  /*    one can compute the width and height of the glyph image (be it in  */+  /*    integer or 26.6 pixels) as:                                        */+  /*                                                                       */+  /*    {                                                                  */+  /*      width  = bbox.xMax - bbox.xMin;                                  */+  /*      height = bbox.yMax - bbox.yMin;                                  */+  /*    }                                                                  */+  /*                                                                       */+  /*    Note also that for 26.6 coordinates, if `bbox_mode' is set to      */+  /*    @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted,  */+  /*    which corresponds to:                                              */+  /*                                                                       */+  /*    {                                                                  */+  /*      bbox.xMin = FLOOR(bbox.xMin);                                    */+  /*      bbox.yMin = FLOOR(bbox.yMin);                                    */+  /*      bbox.xMax = CEILING(bbox.xMax);                                  */+  /*      bbox.yMax = CEILING(bbox.yMax);                                  */+  /*    }                                                                  */+  /*                                                                       */+  /*    To get the bbox in pixel coordinates, set `bbox_mode' to           */+  /*    @FT_GLYPH_BBOX_TRUNCATE.                                           */+  /*                                                                       */+  /*    To get the bbox in grid-fitted pixel coordinates, set `bbox_mode'  */+  /*    to @FT_GLYPH_BBOX_PIXELS.                                          */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Glyph_Get_CBox( FT_Glyph  glyph,+                     FT_UInt   bbox_mode,+                     FT_BBox  *acbox );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Glyph_To_Bitmap                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Convert a given glyph object to a bitmap glyph object.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    the_glyph   :: A pointer to a handle to the target glyph.          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    render_mode :: An enumeration that describes how the data is       */+  /*                   rendered.                                           */+  /*                                                                       */+  /*    origin      :: A pointer to a vector used to translate the glyph   */+  /*                   image before rendering.  Can be~0 (if no            */+  /*                   translation).  The origin is expressed in           */+  /*                   26.6 pixels.                                        */+  /*                                                                       */+  /*    destroy     :: A boolean that indicates that the original glyph    */+  /*                   image should be destroyed by this function.  It is  */+  /*                   never destroyed in case of error.                   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function does nothing if the glyph format isn't scalable.     */+  /*                                                                       */+  /*    The glyph image is translated with the `origin' vector before      */+  /*    rendering.                                                         */+  /*                                                                       */+  /*    The first parameter is a pointer to an @FT_Glyph handle, that will */+  /*    be _replaced_ by this function (with newly allocated data).        */+  /*    Typically, you would use (omitting error handling):                */+  /*                                                                       */+  /*                                                                       */+  /*      {                                                                */+  /*        FT_Glyph        glyph;                                         */+  /*        FT_BitmapGlyph  glyph_bitmap;                                  */+  /*                                                                       */+  /*                                                                       */+  /*        // load glyph                                                  */+  /*        error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT );     */+  /*                                                                       */+  /*        // extract glyph image                                         */+  /*        error = FT_Get_Glyph( face->glyph, &glyph );                   */+  /*                                                                       */+  /*        // convert to a bitmap (default render mode + destroying old)  */+  /*        if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )                 */+  /*        {                                                              */+  /*          error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,   */+  /*                                      0, 1 );                          */+  /*          if ( error ) // `glyph' unchanged                            */+  /*            ...                                                        */+  /*        }                                                              */+  /*                                                                       */+  /*        // access bitmap content by typecasting                        */+  /*        glyph_bitmap = (FT_BitmapGlyph)glyph;                          */+  /*                                                                       */+  /*        // do funny stuff with it, like blitting/drawing               */+  /*        ...                                                            */+  /*                                                                       */+  /*        // discard glyph image (bitmap or not)                         */+  /*        FT_Done_Glyph( glyph );                                        */+  /*      }                                                                */+  /*                                                                       */+  /*                                                                       */+  /*    Here another example, again without error handling:                */+  /*                                                                       */+  /*                                                                       */+  /*      {                                                                */+  /*        FT_Glyph  glyphs[MAX_GLYPHS]                                   */+  /*                                                                       */+  /*                                                                       */+  /*        ...                                                            */+  /*                                                                       */+  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */+  /*          error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) ||       */+  /*                  FT_Get_Glyph ( face->glyph, &glyph[idx] );           */+  /*                                                                       */+  /*        ...                                                            */+  /*                                                                       */+  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */+  /*        {                                                              */+  /*          FT_Glyph  bitmap = glyphs[idx];                              */+  /*                                                                       */+  /*                                                                       */+  /*          ...                                                          */+  /*                                                                       */+  /*          // after this call, `bitmap' no longer points into           */+  /*          // the `glyphs' array (and the old value isn't destroyed)    */+  /*          FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 );    */+  /*                                                                       */+  /*          ...                                                          */+  /*                                                                       */+  /*          FT_Done_Glyph( bitmap );                                     */+  /*        }                                                              */+  /*                                                                       */+  /*        ...                                                            */+  /*                                                                       */+  /*        for ( idx = 0; i < MAX_GLYPHS; i++ )                           */+  /*          FT_Done_Glyph( glyphs[idx] );                                */+  /*      }                                                                */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,+                      FT_Render_Mode  render_mode,+                      FT_Vector*      origin,+                      FT_Bool         destroy );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_Glyph                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy a given glyph.                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    glyph :: A handle to the target glyph object.                      */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Done_Glyph( FT_Glyph  glyph );++  /* */+++  /* other helpful functions */++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    computations                                                       */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Matrix_Multiply                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Perform the matrix operation `b = a*b'.                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: A pointer to matrix `a'.                                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    b :: A pointer to matrix `b'.                                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The result is undefined if either `a' or `b' is zero.              */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Matrix_Multiply( const FT_Matrix*  a,+                      FT_Matrix*        b );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Matrix_Invert                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Invert a 2x2 matrix.  Return an error if it can't be inverted.     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    matrix :: A pointer to the target matrix.  Remains untouched in    */+  /*              case of error.                                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Matrix_Invert( FT_Matrix*  matrix );+++  /* */+++FT_END_HEADER++#endif /* __FTGLYPH_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftgxval.h view
@@ -0,0 +1,358 @@+/***************************************************************************/+/*                                                                         */+/*  ftgxval.h                                                              */+/*                                                                         */+/*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */+/*                                                                         */+/*  Copyright 2004, 2005, 2006 by                                          */+/*  Masatake YAMATO, Redhat K.K,                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/***************************************************************************/+/*                                                                         */+/* gxvalid is derived from both gxlayout module and otvalid module.        */+/* Development of gxlayout is supported by the Information-technology      */+/* Promotion Agency(IPA), Japan.                                           */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTGXVAL_H__+#define __FTGXVAL_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    gx_validation                                                      */+  /*                                                                       */+  /* <Title>                                                               */+  /*    TrueTypeGX/AAT Validation                                          */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    An API to validate TrueTypeGX/AAT tables.                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of functions to validate     */+  /*    some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd,  */+  /*    trak, prop, lcar).                                                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /*                                                                       */+  /* Warning: Use FT_VALIDATE_XXX to validate a table.                     */+  /*          Following definitions are for gxvalid developers.            */+  /*                                                                       */+  /*                                                                       */+  /*************************************************************************/++#define FT_VALIDATE_feat_INDEX     0+#define FT_VALIDATE_mort_INDEX     1+#define FT_VALIDATE_morx_INDEX     2+#define FT_VALIDATE_bsln_INDEX     3+#define FT_VALIDATE_just_INDEX     4+#define FT_VALIDATE_kern_INDEX     5+#define FT_VALIDATE_opbd_INDEX     6+#define FT_VALIDATE_trak_INDEX     7+#define FT_VALIDATE_prop_INDEX     8+#define FT_VALIDATE_lcar_INDEX     9+#define FT_VALIDATE_GX_LAST_INDEX  FT_VALIDATE_lcar_INDEX+++  /*************************************************************************+   *+   * @macro:+   *   FT_VALIDATE_GX_LENGTH+   *+   * @description:+   *   The number of tables checked in this module.  Use it as a parameter+   *   for the `table-length' argument of function @FT_TrueTypeGX_Validate.+   */+#define FT_VALIDATE_GX_LENGTH     (FT_VALIDATE_GX_LAST_INDEX + 1)++  /* */++  /* Up to 0x1000 is used by otvalid.+     Ox2xxx is reserved for feature OT extension. */+#define FT_VALIDATE_GX_START 0x4000+#define FT_VALIDATE_GX_BITFIELD( tag )                  \+  ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX )+++ /**********************************************************************+  *+  * @enum:+  *    FT_VALIDATE_GXXXX+  *+  * @description:+  *    A list of bit-field constants used with @FT_TrueTypeGX_Validate to+  *    indicate which TrueTypeGX/AAT Type tables should be validated.+  *+  * @values:+  *    FT_VALIDATE_feat ::+  *      Validate `feat' table.+  *+  *    FT_VALIDATE_mort ::+  *      Validate `mort' table.+  *+  *    FT_VALIDATE_morx ::+  *      Validate `morx' table.+  *+  *    FT_VALIDATE_bsln ::+  *      Validate `bsln' table.+  *+  *    FT_VALIDATE_just ::+  *      Validate `just' table.+  *+  *    FT_VALIDATE_kern ::+  *      Validate `kern' table.+  *+  *    FT_VALIDATE_opbd ::+  *      Validate `opbd' table.+  *+  *    FT_VALIDATE_trak ::+  *      Validate `trak' table.+  *+  *    FT_VALIDATE_prop ::+  *      Validate `prop' table.+  *+  *    FT_VALIDATE_lcar ::+  *      Validate `lcar' table.+  *+  *    FT_VALIDATE_GX ::+  *      Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern,+  *      opbd, trak, prop and lcar).+  *+  */++#define FT_VALIDATE_feat  FT_VALIDATE_GX_BITFIELD( feat )+#define FT_VALIDATE_mort  FT_VALIDATE_GX_BITFIELD( mort )+#define FT_VALIDATE_morx  FT_VALIDATE_GX_BITFIELD( morx )+#define FT_VALIDATE_bsln  FT_VALIDATE_GX_BITFIELD( bsln )+#define FT_VALIDATE_just  FT_VALIDATE_GX_BITFIELD( just )+#define FT_VALIDATE_kern  FT_VALIDATE_GX_BITFIELD( kern )+#define FT_VALIDATE_opbd  FT_VALIDATE_GX_BITFIELD( opbd )+#define FT_VALIDATE_trak  FT_VALIDATE_GX_BITFIELD( trak )+#define FT_VALIDATE_prop  FT_VALIDATE_GX_BITFIELD( prop )+#define FT_VALIDATE_lcar  FT_VALIDATE_GX_BITFIELD( lcar )++#define FT_VALIDATE_GX  ( FT_VALIDATE_feat | \+                          FT_VALIDATE_mort | \+                          FT_VALIDATE_morx | \+                          FT_VALIDATE_bsln | \+                          FT_VALIDATE_just | \+                          FT_VALIDATE_kern | \+                          FT_VALIDATE_opbd | \+                          FT_VALIDATE_trak | \+                          FT_VALIDATE_prop | \+                          FT_VALIDATE_lcar )+++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_TrueTypeGX_Validate+  *+  * @description:+  *    Validate various TrueTypeGX tables to assure that all offsets and+  *    indices are valid.  The idea is that a higher-level library which+  *    actually does the text layout can access those tables without+  *    error checking (which can be quite time consuming).+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    validation_flags ::+  *       A bit field which specifies the tables to be validated.  See+  *       @FT_VALIDATE_GXXXX for possible values.+  *+  *    table_length ::+  *       The size of the `tables' array.  Normally, @FT_VALIDATE_GX_LENGTH+  *       should be passed.+  *+  * @output:+  *    tables ::+  *       The array where all validated sfnt tables are stored.+  *       The array itself must be allocated by a client.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   This function only works with TrueTypeGX fonts, returning an error+  *   otherwise.+  *+  *   After use, the application should deallocate the buffers pointed to by+  *   each `tables' element, by calling @FT_TrueTypeGX_Free.  A NULL value+  *   indicates that the table either doesn't exist in the font, the+  *   application hasn't asked for validation, or the validator doesn't have+  *   the ability to validate the sfnt table.+  */+  FT_EXPORT( FT_Error )+  FT_TrueTypeGX_Validate( FT_Face   face,+                          FT_UInt   validation_flags,+                          FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],+                          FT_UInt   table_length );+++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_TrueTypeGX_Free+  *+  * @description:+  *    Free the buffer allocated by TrueTypeGX validator.+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    table ::+  *       The pointer to the buffer allocated by+  *       @FT_TrueTypeGX_Validate.+  *+  * @note:+  *   This function must be used to free the buffer allocated by+  *   @FT_TrueTypeGX_Validate only.+  */+  FT_EXPORT( void )+  FT_TrueTypeGX_Free( FT_Face   face,+                      FT_Bytes  table );+++  /* */++ /**********************************************************************+  *+  * @enum:+  *    FT_VALIDATE_CKERNXXX+  *+  * @description:+  *    A list of bit-field constants used with @FT_ClassicKern_Validate+  *    to indicate the classic kern dialect or dialects.  If the selected+  *    type doesn't fit, @FT_ClassicKern_Validate regards the table as+  *    invalid.+  *+  * @values:+  *    FT_VALIDATE_MS ::+  *      Handle the `kern' table as a classic Microsoft kern table.+  *+  *    FT_VALIDATE_APPLE ::+  *      Handle the `kern' table as a classic Apple kern table.+  *+  *    FT_VALIDATE_CKERN ::+  *      Handle the `kern' as either classic Apple or Microsoft kern table.+  */+#define FT_VALIDATE_MS     ( FT_VALIDATE_GX_START << 0 )+#define FT_VALIDATE_APPLE  ( FT_VALIDATE_GX_START << 1 )++#define FT_VALIDATE_CKERN  ( FT_VALIDATE_MS | FT_VALIDATE_APPLE )+++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_ClassicKern_Validate+  *+  * @description:+  *    Validate classic (16-bit format) kern table to assure that the offsets+  *    and indices are valid.  The idea is that a higher-level library which+  *    actually does the text layout can access those tables without error+  *    checking (which can be quite time consuming).+  *+  *    The `kern' table validator in @FT_TrueTypeGX_Validate deals with both+  *    the new 32-bit format and the classic 16-bit format, while+  *    FT_ClassicKern_Validate only supports the classic 16-bit format.+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    validation_flags ::+  *       A bit field which specifies the dialect to be validated.  See+  *       @FT_VALIDATE_CKERNXXX for possible values.+  *+  * @output:+  *    ckern_table ::+  *       A pointer to the kern table.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   After use, the application should deallocate the buffers pointed to by+  *   `ckern_table', by calling @FT_ClassicKern_Free.  A NULL value+  *   indicates that the table doesn't exist in the font.+  */+  FT_EXPORT( FT_Error )+  FT_ClassicKern_Validate( FT_Face    face,+                           FT_UInt    validation_flags,+                           FT_Bytes  *ckern_table );+++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_ClassicKern_Free+  *+  * @description:+  *    Free the buffer allocated by classic Kern validator.+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    table ::+  *       The pointer to the buffer that is allocated by+  *       @FT_ClassicKern_Validate.+  *+  * @note:+  *   This function must be used to free the buffer allocated by+  *   @FT_ClassicKern_Validate only.+  */+  FT_EXPORT( void )+  FT_ClassicKern_Free( FT_Face   face,+                       FT_Bytes  table );+++ /* */+++FT_END_HEADER++#endif /* __FTGXVAL_H__ */+++/* END */
+ include/freetype/ftgzip.h view
@@ -0,0 +1,102 @@+/***************************************************************************/+/*                                                                         */+/*  ftgzip.h                                                               */+/*                                                                         */+/*    Gzip-compressed stream support.                                      */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTGZIP_H__+#define __FTGZIP_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    gzip                                                               */+  /*                                                                       */+  /* <Title>                                                               */+  /*    GZIP Streams                                                       */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Using gzip-compressed font files.                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of Gzip-specific functions.  */+  /*                                                                       */+  /*************************************************************************/+++ /************************************************************************+  *+  * @function:+  *   FT_Stream_OpenGzip+  *+  * @description:+  *   Open a new stream to parse gzip-compressed font files.  This is+  *   mainly used to support the compressed `*.pcf.gz' fonts that come+  *   with XFree86.+  *+  * @input:+  *   stream ::+  *     The target embedding stream.+  *+  *   source ::+  *     The source stream.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   The source stream must be opened _before_ calling this function.+  *+  *   Calling the internal function `FT_Stream_Close' on the new stream will+  *   *not* call `FT_Stream_Close' on the source stream.  None of the stream+  *   objects will be released to the heap.+  *+  *   The stream implementation is very basic and resets the decompression+  *   process each time seeking backwards is needed within the stream.+  *+  *   In certain builds of the library, gzip compression recognition is+  *   automatically handled when calling @FT_New_Face or @FT_Open_Face.+  *   This means that if no font driver is capable of handling the raw+  *   compressed file, the library will try to open a gzipped stream from+  *   it and re-open the face with it.+  *+  *   This function may return `FT_Err_Unimplemented_Feature' if your build+  *   of FreeType was not compiled with zlib support.+  */+  FT_EXPORT( FT_Error )+  FT_Stream_OpenGzip( FT_Stream  stream,+                      FT_Stream  source );++ /* */+++FT_END_HEADER++#endif /* __FTGZIP_H__ */+++/* END */
+ include/freetype/ftimage.h view
@@ -0,0 +1,1313 @@+/***************************************************************************/+/*                                                                         */+/*  ftimage.h                                                              */+/*                                                                         */+/*    FreeType glyph image formats and default raster interface            */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* Note: A `raster' is simply a scan-line converter, used to render      */+  /*       FT_Outlines into FT_Bitmaps.                                    */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTIMAGE_H__+#define __FTIMAGE_H__+++  /* _STANDALONE_ is from ftgrays.c */+#ifndef _STANDALONE_+#include <ft2build.h>+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    basic_types                                                        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Pos                                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The type FT_Pos is used to store vectorial coordinates.  Depending */+  /*    on the context, these can represent distances in integer font      */+  /*    units, or 16.16, or 26.6 fixed float pixel coordinates.            */+  /*                                                                       */+  typedef signed long  FT_Pos;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Vector                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to store a 2D vector; coordinates are of   */+  /*    the FT_Pos type.                                                   */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    x :: The horizontal coordinate.                                    */+  /*    y :: The vertical coordinate.                                      */+  /*                                                                       */+  typedef struct  FT_Vector_+  {+    FT_Pos  x;+    FT_Pos  y;++  } FT_Vector;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_BBox                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to hold an outline's bounding box, i.e., the      */+  /*    coordinates of its extrema in the horizontal and vertical          */+  /*    directions.                                                        */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    xMin :: The horizontal minimum (left-most).                        */+  /*                                                                       */+  /*    yMin :: The vertical minimum (bottom-most).                        */+  /*                                                                       */+  /*    xMax :: The horizontal maximum (right-most).                       */+  /*                                                                       */+  /*    yMax :: The vertical maximum (top-most).                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The bounding box is specified with the coordinates of the lower    */+  /*    left and the upper right corner.  In PostScript, those values are  */+  /*    often called (llx,lly) and (urx,ury), respectively.                */+  /*                                                                       */+  /*    If `yMin' is negative, this value gives the glyph's descender.     */+  /*    Otherwise, the glyph doesn't descend below the baseline.           */+  /*    Similarly, if `ymax' is positive, this value gives the glyph's     */+  /*    ascender.                                                          */+  /*                                                                       */+  /*    `xMin' gives the horizontal distance from the glyph's origin to    */+  /*    the left edge of the glyph's bounding box.  If `xMin' is negative, */+  /*    the glyph extends to the left of the origin.                       */+  /*                                                                       */+  typedef struct  FT_BBox_+  {+    FT_Pos  xMin, yMin;+    FT_Pos  xMax, yMax;++  } FT_BBox;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Pixel_Mode                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration type used to describe the format of pixels in a     */+  /*    given bitmap.  Note that additional formats may be added in the    */+  /*    future.                                                            */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_PIXEL_MODE_NONE ::                                              */+  /*      Value~0 is reserved.                                             */+  /*                                                                       */+  /*    FT_PIXEL_MODE_MONO ::                                              */+  /*      A monochrome bitmap, using 1~bit per pixel.  Note that pixels    */+  /*      are stored in most-significant order (MSB), which means that     */+  /*      the left-most pixel in a byte has value 128.                     */+  /*                                                                       */+  /*    FT_PIXEL_MODE_GRAY ::                                              */+  /*      An 8-bit bitmap, generally used to represent anti-aliased glyph  */+  /*      images.  Each pixel is stored in one byte.  Note that the number */+  /*      of `gray' levels is stored in the `num_grays' field of the       */+  /*      @FT_Bitmap structure (it generally is 256).                      */+  /*                                                                       */+  /*    FT_PIXEL_MODE_GRAY2 ::                                             */+  /*      A 2-bit per pixel bitmap, used to represent embedded             */+  /*      anti-aliased bitmaps in font files according to the OpenType     */+  /*      specification.  We haven't found a single font using this        */+  /*      format, however.                                                 */+  /*                                                                       */+  /*    FT_PIXEL_MODE_GRAY4 ::                                             */+  /*      A 4-bit per pixel bitmap, representing embedded anti-aliased     */+  /*      bitmaps in font files according to the OpenType specification.   */+  /*      We haven't found a single font using this format, however.       */+  /*                                                                       */+  /*    FT_PIXEL_MODE_LCD ::                                               */+  /*      An 8-bit bitmap, representing RGB or BGR decimated glyph images  */+  /*      used for display on LCD displays; the bitmap is three times      */+  /*      wider than the original glyph image.  See also                   */+  /*      @FT_RENDER_MODE_LCD.                                             */+  /*                                                                       */+  /*    FT_PIXEL_MODE_LCD_V ::                                             */+  /*      An 8-bit bitmap, representing RGB or BGR decimated glyph images  */+  /*      used for display on rotated LCD displays; the bitmap is three    */+  /*      times taller than the original glyph image.  See also            */+  /*      @FT_RENDER_MODE_LCD_V.                                           */+  /*                                                                       */+  typedef enum  FT_Pixel_Mode_+  {+    FT_PIXEL_MODE_NONE = 0,+    FT_PIXEL_MODE_MONO,+    FT_PIXEL_MODE_GRAY,+    FT_PIXEL_MODE_GRAY2,+    FT_PIXEL_MODE_GRAY4,+    FT_PIXEL_MODE_LCD,+    FT_PIXEL_MODE_LCD_V,++    FT_PIXEL_MODE_MAX      /* do not remove */++  } FT_Pixel_Mode;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    ft_pixel_mode_xxx                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of deprecated constants.  Use the corresponding             */+  /*    @FT_Pixel_Mode values instead.                                     */+  /*                                                                       */+  /* <Values>                                                              */+  /*    ft_pixel_mode_none  :: See @FT_PIXEL_MODE_NONE.                    */+  /*    ft_pixel_mode_mono  :: See @FT_PIXEL_MODE_MONO.                    */+  /*    ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY.                    */+  /*    ft_pixel_mode_pal2  :: See @FT_PIXEL_MODE_GRAY2.                   */+  /*    ft_pixel_mode_pal4  :: See @FT_PIXEL_MODE_GRAY4.                   */+  /*                                                                       */+#define ft_pixel_mode_none   FT_PIXEL_MODE_NONE+#define ft_pixel_mode_mono   FT_PIXEL_MODE_MONO+#define ft_pixel_mode_grays  FT_PIXEL_MODE_GRAY+#define ft_pixel_mode_pal2   FT_PIXEL_MODE_GRAY2+#define ft_pixel_mode_pal4   FT_PIXEL_MODE_GRAY4++ /* */++#if 0++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Palette_Mode                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT!                           */+  /*                                                                       */+  /*    An enumeration type to describe the format of a bitmap palette,    */+  /*    used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8.               */+  /*                                                                       */+  /* <Values>                                                              */+  /*    ft_palette_mode_rgb  :: The palette is an array of 3-byte RGB      */+  /*                            records.                                   */+  /*                                                                       */+  /*    ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA     */+  /*                            records.                                   */+  /*                                                                       */+  /* <Note>                                                                */+  /*    As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by       */+  /*    FreeType, these types are not handled by the library itself.       */+  /*                                                                       */+  typedef enum  FT_Palette_Mode_+  {+    ft_palette_mode_rgb = 0,+    ft_palette_mode_rgba,++    ft_palette_mode_max   /* do not remove */++  } FT_Palette_Mode;++  /* */++#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Bitmap                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to describe a bitmap or pixmap to the raster.     */+  /*    Note that we now manage pixmaps of various depths through the      */+  /*    `pixel_mode' field.                                                */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    rows         :: The number of bitmap rows.                         */+  /*                                                                       */+  /*    width        :: The number of pixels in bitmap row.                */+  /*                                                                       */+  /*    pitch        :: The pitch's absolute value is the number of bytes  */+  /*                    taken by one bitmap row, including padding.        */+  /*                    However, the pitch is positive when the bitmap has */+  /*                    a `down' flow, and negative when it has an `up'    */+  /*                    flow.  In all cases, the pitch is an offset to add */+  /*                    to a bitmap pointer in order to go down one row.   */+  /*                                                                       */+  /*                    Note that `padding' means the alignment of a       */+  /*                    bitmap to a byte border, and FreeType functions    */+  /*                    normally align to the smallest possible integer    */+  /*                    value.                                             */+  /*                                                                       */+  /*                    For the B/W rasterizer, `pitch' is always an even  */+  /*                    number.                                            */+  /*                                                                       */+  /*                    To change the pitch of a bitmap (say, to make it a */+  /*                    multiple of 4), use @FT_Bitmap_Convert.            */+  /*                    Alternatively, you might use callback functions to */+  /*                    directly render to the application's surface; see  */+  /*                    the file `example2.cpp' in the tutorial for a      */+  /*                    demonstration.                                     */+  /*                                                                       */+  /*    buffer       :: A typeless pointer to the bitmap buffer.  This     */+  /*                    value should be aligned on 32-bit boundaries in    */+  /*                    most cases.                                        */+  /*                                                                       */+  /*    num_grays    :: This field is only used with                       */+  /*                    @FT_PIXEL_MODE_GRAY; it gives the number of gray   */+  /*                    levels used in the bitmap.                         */+  /*                                                                       */+  /*    pixel_mode   :: The pixel mode, i.e., how pixel bits are stored.   */+  /*                    See @FT_Pixel_Mode for possible values.            */+  /*                                                                       */+  /*    palette_mode :: This field is intended for paletted pixel modes;   */+  /*                    it indicates how the palette is stored.  Not       */+  /*                    used currently.                                    */+  /*                                                                       */+  /*    palette      :: A typeless pointer to the bitmap palette; this     */+  /*                    field is intended for paletted pixel modes.  Not   */+  /*                    used currently.                                    */+  /*                                                                       */+  /* <Note>                                                                */+  /*   For now, the only pixel modes supported by FreeType are mono and    */+  /*   grays.  However, drivers might be added in the future to support    */+  /*   more `colorful' options.                                            */+  /*                                                                       */+  typedef struct  FT_Bitmap_+  {+    int             rows;+    int             width;+    int             pitch;+    unsigned char*  buffer;+    short           num_grays;+    char            pixel_mode;+    char            palette_mode;+    void*           palette;++  } FT_Bitmap;+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    outline_processing                                                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Outline                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure is used to describe an outline to the scan-line     */+  /*    converter.                                                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    n_contours :: The number of contours in the outline.               */+  /*                                                                       */+  /*    n_points   :: The number of points in the outline.                 */+  /*                                                                       */+  /*    points     :: A pointer to an array of `n_points' @FT_Vector       */+  /*                  elements, giving the outline's point coordinates.    */+  /*                                                                       */+  /*    tags       :: A pointer to an array of `n_points' chars, giving    */+  /*                  each outline point's type.                           */+  /*                                                                       */+  /*                  If bit~0 is unset, the point is `off' the curve,     */+  /*                  i.e., a Bézier control point, while it is `on' if    */+  /*                  set.                                                 */+  /*                                                                       */+  /*                  Bit~1 is meaningful for `off' points only.  If set,  */+  /*                  it indicates a third-order Bézier arc control point; */+  /*                  and a second-order control point if unset.           */+  /*                                                                       */+  /*                  If bit~2 is set, bits 5-7 contain the drop-out mode  */+  /*                  (as defined in the OpenType specification; the value */+  /*                  is the same as the argument to the SCANMODE          */+  /*                  instruction).                                        */+  /*                                                                       */+  /*                  Bits 3 and~4 are reserved for internal purposes.     */+  /*                                                                       */+  /*    contours   :: An array of `n_contours' shorts, giving the end      */+  /*                  point of each contour within the outline.  For       */+  /*                  example, the first contour is defined by the points  */+  /*                  `0' to `contours[0]', the second one is defined by   */+  /*                  the points `contours[0]+1' to `contours[1]', etc.    */+  /*                                                                       */+  /*    flags      :: A set of bit flags used to characterize the outline  */+  /*                  and give hints to the scan-converter and hinter on   */+  /*                  how to convert/grid-fit it.  See @FT_OUTLINE_FLAGS.  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The B/W rasterizer only checks bit~2 in the `tags' array for the   */+  /*    first point of each contour.  The drop-out mode as given with      */+  /*    @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and       */+  /*    @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden.           */+  /*                                                                       */+  typedef struct  FT_Outline_+  {+    short       n_contours;      /* number of contours in glyph        */+    short       n_points;        /* number of points in the glyph      */++    FT_Vector*  points;          /* the outline's points               */+    char*       tags;            /* the points flags                   */+    short*      contours;        /* the contour end points             */++    int         flags;           /* outline masks                      */++  } FT_Outline;++  /* Following limits must be consistent with */+  /* FT_Outline.{n_contours,n_points}         */+#define FT_OUTLINE_CONTOURS_MAX  SHRT_MAX+#define FT_OUTLINE_POINTS_MAX    SHRT_MAX+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_OUTLINE_FLAGS                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit-field constants use for the flags in an outline's    */+  /*    `flags' field.                                                     */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_OUTLINE_NONE ::                                                 */+  /*      Value~0 is reserved.                                             */+  /*                                                                       */+  /*    FT_OUTLINE_OWNER ::                                                */+  /*      If set, this flag indicates that the outline's field arrays      */+  /*      (i.e., `points', `flags', and `contours') are `owned' by the     */+  /*      outline object, and should thus be freed when it is destroyed.   */+  /*                                                                       */+  /*    FT_OUTLINE_EVEN_ODD_FILL ::                                        */+  /*      By default, outlines are filled using the non-zero winding rule. */+  /*      If set to 1, the outline will be filled using the even-odd fill  */+  /*      rule (only works with the smooth rasterizer).                    */+  /*                                                                       */+  /*    FT_OUTLINE_REVERSE_FILL ::                                         */+  /*      By default, outside contours of an outline are oriented in       */+  /*      clock-wise direction, as defined in the TrueType specification.  */+  /*      This flag is set if the outline uses the opposite direction      */+  /*      (typically for Type~1 fonts).  This flag is ignored by the scan  */+  /*      converter.                                                       */+  /*                                                                       */+  /*    FT_OUTLINE_IGNORE_DROPOUTS ::                                      */+  /*      By default, the scan converter will try to detect drop-outs in   */+  /*      an outline and correct the glyph bitmap to ensure consistent     */+  /*      shape continuity.  If set, this flag hints the scan-line         */+  /*      converter to ignore such cases.  See below for more information. */+  /*                                                                       */+  /*    FT_OUTLINE_SMART_DROPOUTS ::                                       */+  /*      Select smart dropout control.  If unset, use simple dropout      */+  /*      control.  Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See    */+  /*      below for more information.                                      */+  /*                                                                       */+  /*    FT_OUTLINE_INCLUDE_STUBS ::                                        */+  /*      If set, turn pixels on for `stubs', otherwise exclude them.      */+  /*      Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for    */+  /*      more information.                                                */+  /*                                                                       */+  /*    FT_OUTLINE_HIGH_PRECISION ::                                       */+  /*      This flag indicates that the scan-line converter should try to   */+  /*      convert this outline to bitmaps with the highest possible        */+  /*      quality.  It is typically set for small character sizes.  Note   */+  /*      that this is only a hint that might be completely ignored by a   */+  /*      given scan-converter.                                            */+  /*                                                                       */+  /*    FT_OUTLINE_SINGLE_PASS ::                                          */+  /*      This flag is set to force a given scan-converter to only use a   */+  /*      single pass over the outline to render a bitmap glyph image.     */+  /*      Normally, it is set for very large character sizes.  It is only  */+  /*      a hint that might be completely ignored by a given               */+  /*      scan-converter.                                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */+  /*    and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth            */+  /*    rasterizer.                                                        */+  /*                                                                       */+  /*    There exists a second mechanism to pass the drop-out mode to the   */+  /*    B/W rasterizer; see the `tags' field in @FT_Outline.               */+  /*                                                                       */+  /*    Please refer to the description of the `SCANTYPE' instruction in   */+  /*    the OpenType specification (in file `ttinst1.doc') how simple      */+  /*    drop-outs, smart drop-outs, and stubs are defined.                 */+  /*                                                                       */+#define FT_OUTLINE_NONE             0x0+#define FT_OUTLINE_OWNER            0x1+#define FT_OUTLINE_EVEN_ODD_FILL    0x2+#define FT_OUTLINE_REVERSE_FILL     0x4+#define FT_OUTLINE_IGNORE_DROPOUTS  0x8+#define FT_OUTLINE_SMART_DROPOUTS   0x10+#define FT_OUTLINE_INCLUDE_STUBS    0x20++#define FT_OUTLINE_HIGH_PRECISION   0x100+#define FT_OUTLINE_SINGLE_PASS      0x200+++ /*************************************************************************+  *+  * @enum:+  *   ft_outline_flags+  *+  * @description:+  *   These constants are deprecated.  Please use the corresponding+  *   @FT_OUTLINE_FLAGS values.+  *+  * @values:+  *   ft_outline_none            :: See @FT_OUTLINE_NONE.+  *   ft_outline_owner           :: See @FT_OUTLINE_OWNER.+  *   ft_outline_even_odd_fill   :: See @FT_OUTLINE_EVEN_ODD_FILL.+  *   ft_outline_reverse_fill    :: See @FT_OUTLINE_REVERSE_FILL.+  *   ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS.+  *   ft_outline_high_precision  :: See @FT_OUTLINE_HIGH_PRECISION.+  *   ft_outline_single_pass     :: See @FT_OUTLINE_SINGLE_PASS.+  */+#define ft_outline_none             FT_OUTLINE_NONE+#define ft_outline_owner            FT_OUTLINE_OWNER+#define ft_outline_even_odd_fill    FT_OUTLINE_EVEN_ODD_FILL+#define ft_outline_reverse_fill     FT_OUTLINE_REVERSE_FILL+#define ft_outline_ignore_dropouts  FT_OUTLINE_IGNORE_DROPOUTS+#define ft_outline_high_precision   FT_OUTLINE_HIGH_PRECISION+#define ft_outline_single_pass      FT_OUTLINE_SINGLE_PASS++  /* */++#define FT_CURVE_TAG( flag )  ( flag & 3 )++#define FT_CURVE_TAG_ON            1+#define FT_CURVE_TAG_CONIC         0+#define FT_CURVE_TAG_CUBIC         2++#define FT_CURVE_TAG_HAS_SCANMODE  4++#define FT_CURVE_TAG_TOUCH_X       8  /* reserved for the TrueType hinter */+#define FT_CURVE_TAG_TOUCH_Y      16  /* reserved for the TrueType hinter */++#define FT_CURVE_TAG_TOUCH_BOTH    ( FT_CURVE_TAG_TOUCH_X | \+                                     FT_CURVE_TAG_TOUCH_Y )++#define FT_Curve_Tag_On       FT_CURVE_TAG_ON+#define FT_Curve_Tag_Conic    FT_CURVE_TAG_CONIC+#define FT_Curve_Tag_Cubic    FT_CURVE_TAG_CUBIC+#define FT_Curve_Tag_Touch_X  FT_CURVE_TAG_TOUCH_X+#define FT_Curve_Tag_Touch_Y  FT_CURVE_TAG_TOUCH_Y+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Outline_MoveToFunc                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function pointer type used to describe the signature of a `move  */+  /*    to' function during outline walking/decomposition.                 */+  /*                                                                       */+  /*    A `move to' is emitted to start a new contour in an outline.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    to   :: A pointer to the target point of the `move to'.            */+  /*                                                                       */+  /*    user :: A typeless pointer which is passed from the caller of the  */+  /*            decomposition function.                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  typedef int+  (*FT_Outline_MoveToFunc)( const FT_Vector*  to,+                            void*             user );++#define FT_Outline_MoveTo_Func  FT_Outline_MoveToFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Outline_LineToFunc                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function pointer type used to describe the signature of a `line  */+  /*    to' function during outline walking/decomposition.                 */+  /*                                                                       */+  /*    A `line to' is emitted to indicate a segment in the outline.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    to   :: A pointer to the target point of the `line to'.            */+  /*                                                                       */+  /*    user :: A typeless pointer which is passed from the caller of the  */+  /*            decomposition function.                                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  typedef int+  (*FT_Outline_LineToFunc)( const FT_Vector*  to,+                            void*             user );++#define FT_Outline_LineTo_Func  FT_Outline_LineToFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Outline_ConicToFunc                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function pointer type used to describe the signature of a `conic */+  /*    to' function during outline walking or decomposition.              */+  /*                                                                       */+  /*    A `conic to' is emitted to indicate a second-order Bézier arc in   */+  /*    the outline.                                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    control :: An intermediate control point between the last position */+  /*               and the new target in `to'.                             */+  /*                                                                       */+  /*    to      :: A pointer to the target end point of the conic arc.     */+  /*                                                                       */+  /*    user    :: A typeless pointer which is passed from the caller of   */+  /*               the decomposition function.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  typedef int+  (*FT_Outline_ConicToFunc)( const FT_Vector*  control,+                             const FT_Vector*  to,+                             void*             user );++#define FT_Outline_ConicTo_Func  FT_Outline_ConicToFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Outline_CubicToFunc                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function pointer type used to describe the signature of a `cubic */+  /*    to' function during outline walking or decomposition.              */+  /*                                                                       */+  /*    A `cubic to' is emitted to indicate a third-order Bézier arc.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    control1 :: A pointer to the first Bézier control point.           */+  /*                                                                       */+  /*    control2 :: A pointer to the second Bézier control point.          */+  /*                                                                       */+  /*    to       :: A pointer to the target end point.                     */+  /*                                                                       */+  /*    user     :: A typeless pointer which is passed from the caller of  */+  /*                the decomposition function.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  typedef int+  (*FT_Outline_CubicToFunc)( const FT_Vector*  control1,+                             const FT_Vector*  control2,+                             const FT_Vector*  to,+                             void*             user );++#define FT_Outline_CubicTo_Func  FT_Outline_CubicToFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Outline_Funcs                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure to hold various function pointers used during outline  */+  /*    decomposition in order to emit segments, conic, and cubic Béziers. */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    move_to  :: The `move to' emitter.                                 */+  /*                                                                       */+  /*    line_to  :: The segment emitter.                                   */+  /*                                                                       */+  /*    conic_to :: The second-order Bézier arc emitter.                   */+  /*                                                                       */+  /*    cubic_to :: The third-order Bézier arc emitter.                    */+  /*                                                                       */+  /*    shift    :: The shift that is applied to coordinates before they   */+  /*                are sent to the emitter.                               */+  /*                                                                       */+  /*    delta    :: The delta that is applied to coordinates before they   */+  /*                are sent to the emitter, but after the shift.          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The point coordinates sent to the emitters are the transformed     */+  /*    version of the original coordinates (this is important for high    */+  /*    accuracy during scan-conversion).  The transformation is simple:   */+  /*                                                                       */+  /*    {                                                                  */+  /*      x' = (x << shift) - delta                                        */+  /*      y' = (x << shift) - delta                                        */+  /*    }                                                                  */+  /*                                                                       */+  /*    Set the values of `shift' and `delta' to~0 to get the original     */+  /*    point coordinates.                                                 */+  /*                                                                       */+  typedef struct  FT_Outline_Funcs_+  {+    FT_Outline_MoveToFunc   move_to;+    FT_Outline_LineToFunc   line_to;+    FT_Outline_ConicToFunc  conic_to;+    FT_Outline_CubicToFunc  cubic_to;++    int                     shift;+    FT_Pos                  delta;++  } FT_Outline_Funcs;+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    basic_types                                                        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_IMAGE_TAG                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro converts four-letter tags to an unsigned long type.     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Since many 16-bit compilers don't like 32-bit enumerations, you    */+  /*    should redefine this macro in case of problems to something like   */+  /*    this:                                                              */+  /*                                                                       */+  /*    {                                                                  */+  /*      #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  value         */+  /*    }                                                                  */+  /*                                                                       */+  /*    to get a simple enumeration without assigning special numbers.     */+  /*                                                                       */+#ifndef FT_IMAGE_TAG+#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 )  \+          value = ( ( (unsigned long)_x1 << 24 ) | \+                    ( (unsigned long)_x2 << 16 ) | \+                    ( (unsigned long)_x3 << 8  ) | \+                      (unsigned long)_x4         )+#endif /* FT_IMAGE_TAG */+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Glyph_Format                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration type used to describe the format of a given glyph   */+  /*    image.  Note that this version of FreeType only supports two image */+  /*    formats, even though future font drivers will be able to register  */+  /*    their own format.                                                  */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_GLYPH_FORMAT_NONE ::                                            */+  /*      The value~0 is reserved.                                         */+  /*                                                                       */+  /*    FT_GLYPH_FORMAT_COMPOSITE ::                                       */+  /*      The glyph image is a composite of several other images.  This    */+  /*      format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to   */+  /*      report compound glyphs (like accented characters).               */+  /*                                                                       */+  /*    FT_GLYPH_FORMAT_BITMAP ::                                          */+  /*      The glyph image is a bitmap, and can be described as an          */+  /*      @FT_Bitmap.  You generally need to access the `bitmap' field of  */+  /*      the @FT_GlyphSlotRec structure to read it.                       */+  /*                                                                       */+  /*    FT_GLYPH_FORMAT_OUTLINE ::                                         */+  /*      The glyph image is a vectorial outline made of line segments     */+  /*      and Bézier arcs; it can be described as an @FT_Outline; you      */+  /*      generally want to access the `outline' field of the              */+  /*      @FT_GlyphSlotRec structure to read it.                           */+  /*                                                                       */+  /*    FT_GLYPH_FORMAT_PLOTTER ::                                         */+  /*      The glyph image is a vectorial path with no inside and outside   */+  /*      contours.  Some Type~1 fonts, like those in the Hershey family,  */+  /*      contain glyphs in this format.  These are described as           */+  /*      @FT_Outline, but FreeType isn't currently capable of rendering   */+  /*      them correctly.                                                  */+  /*                                                                       */+  typedef enum  FT_Glyph_Format_+  {+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ),++    FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP,    'b', 'i', 't', 's' ),+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE,   'o', 'u', 't', 'l' ),+    FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER,   'p', 'l', 'o', 't' )++  } FT_Glyph_Format;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    ft_glyph_format_xxx                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of deprecated constants.  Use the corresponding             */+  /*    @FT_Glyph_Format values instead.                                   */+  /*                                                                       */+  /* <Values>                                                              */+  /*    ft_glyph_format_none      :: See @FT_GLYPH_FORMAT_NONE.            */+  /*    ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE.       */+  /*    ft_glyph_format_bitmap    :: See @FT_GLYPH_FORMAT_BITMAP.          */+  /*    ft_glyph_format_outline   :: See @FT_GLYPH_FORMAT_OUTLINE.         */+  /*    ft_glyph_format_plotter   :: See @FT_GLYPH_FORMAT_PLOTTER.         */+  /*                                                                       */+#define ft_glyph_format_none       FT_GLYPH_FORMAT_NONE+#define ft_glyph_format_composite  FT_GLYPH_FORMAT_COMPOSITE+#define ft_glyph_format_bitmap     FT_GLYPH_FORMAT_BITMAP+#define ft_glyph_format_outline    FT_GLYPH_FORMAT_OUTLINE+#define ft_glyph_format_plotter    FT_GLYPH_FORMAT_PLOTTER+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****            R A S T E R   D E F I N I T I O N S                *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* A raster is a scan converter, in charge of rendering an outline into  */+  /* a a bitmap.  This section contains the public API for rasters.        */+  /*                                                                       */+  /* Note that in FreeType 2, all rasters are now encapsulated within      */+  /* specific modules called `renderers'.  See `freetype/ftrender.h' for   */+  /* more details on renderers.                                            */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    raster                                                             */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Scanline Converter                                                 */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    How vectorial outlines are converted into bitmaps and pixmaps.     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains technical definitions.                       */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Raster                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle (pointer) to a raster object.  Each object can be used    */+  /*    independently to convert an outline into a bitmap or pixmap.       */+  /*                                                                       */+  typedef struct FT_RasterRec_*  FT_Raster;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Span                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a single span of gray (or black) pixels  */+  /*    when rendering a monochrome or anti-aliased bitmap.                */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    x        :: The span's horizontal start position.                  */+  /*                                                                       */+  /*    len      :: The span's length in pixels.                           */+  /*                                                                       */+  /*    coverage :: The span color/coverage, ranging from 0 (background)   */+  /*                to 255 (foreground).  Only used for anti-aliased       */+  /*                rendering.                                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This structure is used by the span drawing callback type named     */+  /*    @FT_SpanFunc which takes the y~coordinate of the span as a         */+  /*    a parameter.                                                       */+  /*                                                                       */+  /*    The coverage value is always between 0 and 255.  If you want less  */+  /*    gray values, the callback function has to reduce them.             */+  /*                                                                       */+  typedef struct  FT_Span_+  {+    short           x;+    unsigned short  len;+    unsigned char   coverage;++  } FT_Span;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_SpanFunc                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used as a call-back by the anti-aliased renderer in     */+  /*    order to let client applications draw themselves the gray pixel    */+  /*    spans on each scan line.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    y     :: The scanline's y~coordinate.                              */+  /*                                                                       */+  /*    count :: The number of spans to draw on this scanline.             */+  /*                                                                       */+  /*    spans :: A table of `count' spans to draw on the scanline.         */+  /*                                                                       */+  /*    user  :: User-supplied data that is passed to the callback.        */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This callback allows client applications to directly render the    */+  /*    gray spans of the anti-aliased bitmap to any kind of surfaces.     */+  /*                                                                       */+  /*    This can be used to write anti-aliased outlines directly to a      */+  /*    given background bitmap, and even perform translucency.            */+  /*                                                                       */+  /*    Note that the `count' field cannot be greater than a fixed value   */+  /*    defined by the `FT_MAX_GRAY_SPANS' configuration macro in          */+  /*    `ftoption.h'.  By default, this value is set to~32, which means    */+  /*    that if there are more than 32~spans on a given scanline, the      */+  /*    callback is called several times with the same `y' parameter in    */+  /*    order to draw all callbacks.                                       */+  /*                                                                       */+  /*    Otherwise, the callback is only called once per scan-line, and     */+  /*    only for those scanlines that do have `gray' pixels on them.       */+  /*                                                                       */+  typedef void+  (*FT_SpanFunc)( int             y,+                  int             count,+                  const FT_Span*  spans,+                  void*           user );++#define FT_Raster_Span_Func  FT_SpanFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_BitTest_Func                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */+  /*                                                                       */+  /*    A function used as a call-back by the monochrome scan-converter    */+  /*    to test whether a given target pixel is already set to the drawing */+  /*    `color'.  These tests are crucial to implement drop-out control    */+  /*    per-se the TrueType spec.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    y     :: The pixel's y~coordinate.                                 */+  /*                                                                       */+  /*    x     :: The pixel's x~coordinate.                                 */+  /*                                                                       */+  /*    user  :: User-supplied data that is passed to the callback.        */+  /*                                                                       */+  /* <Return>                                                              */+  /*   1~if the pixel is `set', 0~otherwise.                               */+  /*                                                                       */+  typedef int+  (*FT_Raster_BitTest_Func)( int    y,+                             int    x,+                             void*  user );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_BitSet_Func                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */+  /*                                                                       */+  /*    A function used as a call-back by the monochrome scan-converter    */+  /*    to set an individual target pixel.  This is crucial to implement   */+  /*    drop-out control according to the TrueType specification.          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    y     :: The pixel's y~coordinate.                                 */+  /*                                                                       */+  /*    x     :: The pixel's x~coordinate.                                 */+  /*                                                                       */+  /*    user  :: User-supplied data that is passed to the callback.        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    1~if the pixel is `set', 0~otherwise.                              */+  /*                                                                       */+  typedef void+  (*FT_Raster_BitSet_Func)( int    y,+                            int    x,+                            void*  user );+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_RASTER_FLAG_XXX                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A list of bit flag constants as used in the `flags' field of a     */+  /*    @FT_Raster_Params structure.                                       */+  /*                                                                       */+  /* <Values>                                                              */+  /*    FT_RASTER_FLAG_DEFAULT :: This value is 0.                         */+  /*                                                                       */+  /*    FT_RASTER_FLAG_AA      :: This flag is set to indicate that an     */+  /*                              anti-aliased glyph image should be       */+  /*                              generated.  Otherwise, it will be        */+  /*                              monochrome (1-bit).                      */+  /*                                                                       */+  /*    FT_RASTER_FLAG_DIRECT  :: This flag is set to indicate direct      */+  /*                              rendering.  In this mode, client         */+  /*                              applications must provide their own span */+  /*                              callback.  This lets them directly       */+  /*                              draw or compose over an existing bitmap. */+  /*                              If this bit is not set, the target       */+  /*                              pixmap's buffer _must_ be zeroed before  */+  /*                              rendering.                               */+  /*                                                                       */+  /*                              Note that for now, direct rendering is   */+  /*                              only possible with anti-aliased glyphs.  */+  /*                                                                       */+  /*    FT_RASTER_FLAG_CLIP    :: This flag is only used in direct         */+  /*                              rendering mode.  If set, the output will */+  /*                              be clipped to a box specified in the     */+  /*                              `clip_box' field of the                  */+  /*                              @FT_Raster_Params structure.             */+  /*                                                                       */+  /*                              Note that by default, the glyph bitmap   */+  /*                              is clipped to the target pixmap, except  */+  /*                              in direct rendering mode where all spans */+  /*                              are generated if no clipping box is set. */+  /*                                                                       */+#define FT_RASTER_FLAG_DEFAULT  0x0+#define FT_RASTER_FLAG_AA       0x1+#define FT_RASTER_FLAG_DIRECT   0x2+#define FT_RASTER_FLAG_CLIP     0x4++  /* deprecated */+#define ft_raster_flag_default  FT_RASTER_FLAG_DEFAULT+#define ft_raster_flag_aa       FT_RASTER_FLAG_AA+#define ft_raster_flag_direct   FT_RASTER_FLAG_DIRECT+#define ft_raster_flag_clip     FT_RASTER_FLAG_CLIP+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Raster_Params                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure to hold the arguments used by a raster's render        */+  /*    function.                                                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    target      :: The target bitmap.                                  */+  /*                                                                       */+  /*    source      :: A pointer to the source glyph image (e.g., an       */+  /*                   @FT_Outline).                                       */+  /*                                                                       */+  /*    flags       :: The rendering flags.                                */+  /*                                                                       */+  /*    gray_spans  :: The gray span drawing callback.                     */+  /*                                                                       */+  /*    black_spans :: The black span drawing callback.  UNIMPLEMENTED!    */+  /*                                                                       */+  /*    bit_test    :: The bit test callback.  UNIMPLEMENTED!              */+  /*                                                                       */+  /*    bit_set     :: The bit set callback.  UNIMPLEMENTED!               */+  /*                                                                       */+  /*    user        :: User-supplied data that is passed to each drawing   */+  /*                   callback.                                           */+  /*                                                                       */+  /*    clip_box    :: An optional clipping box.  It is only used in       */+  /*                   direct rendering mode.  Note that coordinates here  */+  /*                   should be expressed in _integer_ pixels (and not in */+  /*                   26.6 fixed-point units).                            */+  /*                                                                       */+  /* <Note>                                                                */+  /*    An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA    */+  /*    bit flag is set in the `flags' field, otherwise a monochrome       */+  /*    bitmap is generated.                                               */+  /*                                                                       */+  /*    If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the      */+  /*    raster will call the `gray_spans' callback to draw gray pixel      */+  /*    spans, in the case of an aa glyph bitmap, it will call             */+  /*    `black_spans', and `bit_test' and `bit_set' in the case of a       */+  /*    monochrome bitmap.  This allows direct composition over a          */+  /*    pre-existing bitmap through user-provided callbacks to perform the */+  /*    span drawing/composition.                                          */+  /*                                                                       */+  /*    Note that the `bit_test' and `bit_set' callbacks are required when */+  /*    rendering a monochrome bitmap, as they are crucial to implement    */+  /*    correct drop-out control as defined in the TrueType specification. */+  /*                                                                       */+  typedef struct  FT_Raster_Params_+  {+    const FT_Bitmap*        target;+    const void*             source;+    int                     flags;+    FT_SpanFunc             gray_spans;+    FT_SpanFunc             black_spans;  /* doesn't work! */+    FT_Raster_BitTest_Func  bit_test;     /* doesn't work! */+    FT_Raster_BitSet_Func   bit_set;      /* doesn't work! */+    void*                   user;+    FT_BBox                 clip_box;++  } FT_Raster_Params;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_NewFunc                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to create a new raster object.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory :: A handle to the memory allocator.                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    raster :: A handle to the new raster object.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The `memory' parameter is a typeless pointer in order to avoid     */+  /*    un-wanted dependencies on the rest of the FreeType code.  In       */+  /*    practice, it is an @FT_Memory object, i.e., a handle to the        */+  /*    standard FreeType memory allocator.  However, this field can be    */+  /*    completely ignored by a given raster implementation.               */+  /*                                                                       */+  typedef int+  (*FT_Raster_NewFunc)( void*       memory,+                        FT_Raster*  raster );++#define FT_Raster_New_Func  FT_Raster_NewFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_DoneFunc                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to destroy a given raster object.                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    raster :: A handle to the raster object.                           */+  /*                                                                       */+  typedef void+  (*FT_Raster_DoneFunc)( FT_Raster  raster );++#define FT_Raster_Done_Func  FT_Raster_DoneFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_ResetFunc                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FreeType provides an area of memory called the `render pool',      */+  /*    available to all registered rasters.  This pool can be freely used */+  /*    during a given scan-conversion but is shared by all rasters.  Its  */+  /*    content is thus transient.                                         */+  /*                                                                       */+  /*    This function is called each time the render pool changes, or just */+  /*    after a new raster object is created.                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    raster    :: A handle to the new raster object.                    */+  /*                                                                       */+  /*    pool_base :: The address in memory of the render pool.             */+  /*                                                                       */+  /*    pool_size :: The size in bytes of the render pool.                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Rasters can ignore the render pool and rely on dynamic memory      */+  /*    allocation if they want to (a handle to the memory allocator is    */+  /*    passed to the raster constructor).  However, this is not           */+  /*    recommended for efficiency purposes.                               */+  /*                                                                       */+  typedef void+  (*FT_Raster_ResetFunc)( FT_Raster       raster,+                          unsigned char*  pool_base,+                          unsigned long   pool_size );++#define FT_Raster_Reset_Func  FT_Raster_ResetFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_SetModeFunc                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is a generic facility to change modes or attributes  */+  /*    in a given raster.  This can be used for debugging purposes, or    */+  /*    simply to allow implementation-specific `features' in a given      */+  /*    raster module.                                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    raster :: A handle to the new raster object.                       */+  /*                                                                       */+  /*    mode   :: A 4-byte tag used to name the mode or property.          */+  /*                                                                       */+  /*    args   :: A pointer to the new mode/property to use.               */+  /*                                                                       */+  typedef int+  (*FT_Raster_SetModeFunc)( FT_Raster      raster,+                            unsigned long  mode,+                            void*          args );++#define FT_Raster_Set_Mode_Func  FT_Raster_SetModeFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Raster_RenderFunc                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Invoke a given raster to scan-convert a given glyph image into a   */+  /*    target bitmap.                                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    raster :: A handle to the raster object.                           */+  /*                                                                       */+  /*    params :: A pointer to an @FT_Raster_Params structure used to      */+  /*              store the rendering parameters.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0~means success.                                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The exact format of the source image depends on the raster's glyph */+  /*    format defined in its @FT_Raster_Funcs structure.  It can be an    */+  /*    @FT_Outline or anything else in order to support a large array of  */+  /*    glyph formats.                                                     */+  /*                                                                       */+  /*    Note also that the render function can fail and return a           */+  /*    `FT_Err_Unimplemented_Feature' error code if the raster used does  */+  /*    not support direct composition.                                    */+  /*                                                                       */+  /*    XXX: For now, the standard raster doesn't support direct           */+  /*         composition but this should change for the final release (see */+  /*         the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c'    */+  /*         for examples of distinct implementations which support direct */+  /*         composition).                                                 */+  /*                                                                       */+  typedef int+  (*FT_Raster_RenderFunc)( FT_Raster                raster,+                           const FT_Raster_Params*  params );++#define FT_Raster_Render_Func  FT_Raster_RenderFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Raster_Funcs                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*   A structure used to describe a given raster class to the library.   */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    glyph_format  :: The supported glyph format for this raster.       */+  /*                                                                       */+  /*    raster_new    :: The raster constructor.                           */+  /*                                                                       */+  /*    raster_reset  :: Used to reset the render pool within the raster.  */+  /*                                                                       */+  /*    raster_render :: A function to render a glyph into a given bitmap. */+  /*                                                                       */+  /*    raster_done   :: The raster destructor.                            */+  /*                                                                       */+  typedef struct  FT_Raster_Funcs_+  {+    FT_Glyph_Format        glyph_format;+    FT_Raster_NewFunc      raster_new;+    FT_Raster_ResetFunc    raster_reset;+    FT_Raster_SetModeFunc  raster_set_mode;+    FT_Raster_RenderFunc   raster_render;+    FT_Raster_DoneFunc     raster_done;++  } FT_Raster_Funcs;+++  /* */+++FT_END_HEADER++#endif /* __FTIMAGE_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftincrem.h view
@@ -0,0 +1,353 @@+/***************************************************************************/+/*                                                                         */+/*  ftincrem.h                                                             */+/*                                                                         */+/*    FreeType incremental loading (specification).                        */+/*                                                                         */+/*  Copyright 2002, 2003, 2006, 2007, 2008, 2010 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTINCREM_H__+#define __FTINCREM_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /***************************************************************************+   *+   * @section:+   *    incremental+   *+   * @title:+   *    Incremental Loading+   *+   * @abstract:+   *    Custom Glyph Loading.+   *+   * @description:+   *   This section contains various functions used to perform so-called+   *   `incremental' glyph loading.  This is a mode where all glyphs loaded+   *   from a given @FT_Face are provided by the client application,+   *+   *   Apart from that, all other tables are loaded normally from the font+   *   file.  This mode is useful when FreeType is used within another+   *   engine, e.g., a PostScript Imaging Processor.+   *+   *   To enable this mode, you must use @FT_Open_Face, passing an+   *   @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an+   *   @FT_Incremental_Interface value.  See the comments for+   *   @FT_Incremental_InterfaceRec for an example.+   *+   */+++  /***************************************************************************+   *+   * @type:+   *   FT_Incremental+   *+   * @description:+   *   An opaque type describing a user-provided object used to implement+   *   `incremental' glyph loading within FreeType.  This is used to support+   *   embedded fonts in certain environments (e.g., PostScript interpreters),+   *   where the glyph data isn't in the font file, or must be overridden by+   *   different values.+   *+   * @note:+   *   It is up to client applications to create and implement @FT_Incremental+   *   objects, as long as they provide implementations for the methods+   *   @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc+   *   and @FT_Incremental_GetGlyphMetricsFunc.+   *+   *   See the description of @FT_Incremental_InterfaceRec to understand how+   *   to use incremental objects with FreeType.+   *+   */+  typedef struct FT_IncrementalRec_*  FT_Incremental;+++  /***************************************************************************+   *+   * @struct:+   *   FT_Incremental_MetricsRec+   *+   * @description:+   *   A small structure used to contain the basic glyph metrics returned+   *   by the @FT_Incremental_GetGlyphMetricsFunc method.+   *+   * @fields:+   *   bearing_x ::+   *     Left bearing, in font units.+   *+   *   bearing_y ::+   *     Top bearing, in font units.+   *+   *   advance ::+   *     Horizontal component of glyph advance, in font units.+   *+   *   advance_v ::+   *     Vertical component of glyph advance, in font units.+   *+   * @note:+   *   These correspond to horizontal or vertical metrics depending on the+   *   value of the `vertical' argument to the function+   *   @FT_Incremental_GetGlyphMetricsFunc.+   *+   */+  typedef struct  FT_Incremental_MetricsRec_+  {+    FT_Long  bearing_x;+    FT_Long  bearing_y;+    FT_Long  advance;+    FT_Long  advance_v;     /* since 2.3.12 */++  } FT_Incremental_MetricsRec;+++  /***************************************************************************+   *+   * @struct:+   *   FT_Incremental_Metrics+   *+   * @description:+   *   A handle to an @FT_Incremental_MetricsRec structure.+   *+   */+   typedef struct FT_Incremental_MetricsRec_*  FT_Incremental_Metrics;+++  /***************************************************************************+   *+   * @type:+   *   FT_Incremental_GetGlyphDataFunc+   *+   * @description:+   *   A function called by FreeType to access a given glyph's data bytes+   *   during @FT_Load_Glyph or @FT_Load_Char if incremental loading is+   *   enabled.+   *+   *   Note that the format of the glyph's data bytes depends on the font+   *   file format.  For TrueType, it must correspond to the raw bytes within+   *   the `glyf' table.  For PostScript formats, it must correspond to the+   *   *unencrypted* charstring bytes, without any `lenIV' header.  It is+   *   undefined for any other format.+   *+   * @input:+   *   incremental ::+   *     Handle to an opaque @FT_Incremental handle provided by the client+   *     application.+   *+   *   glyph_index ::+   *     Index of relevant glyph.+   *+   * @output:+   *   adata ::+   *     A structure describing the returned glyph data bytes (which will be+   *     accessed as a read-only byte block).+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   If this function returns successfully the method+   *   @FT_Incremental_FreeGlyphDataFunc will be called later to release+   *   the data bytes.+   *+   *   Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for+   *   compound glyphs.+   *+   */+  typedef FT_Error+  (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental  incremental,+                                      FT_UInt         glyph_index,+                                      FT_Data*        adata );+++  /***************************************************************************+   *+   * @type:+   *   FT_Incremental_FreeGlyphDataFunc+   *+   * @description:+   *   A function used to release the glyph data bytes returned by a+   *   successful call to @FT_Incremental_GetGlyphDataFunc.+   *+   * @input:+   *   incremental ::+   *     A handle to an opaque @FT_Incremental handle provided by the client+   *     application.+   *+   *   data ::+   *     A structure describing the glyph data bytes (which will be accessed+   *     as a read-only byte block).+   *+   */+  typedef void+  (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental  incremental,+                                       FT_Data*        data );+++  /***************************************************************************+   *+   * @type:+   *   FT_Incremental_GetGlyphMetricsFunc+   *+   * @description:+   *   A function used to retrieve the basic metrics of a given glyph index+   *   before accessing its data.  This is necessary because, in certain+   *   formats like TrueType, the metrics are stored in a different place from+   *   the glyph images proper.+   *+   * @input:+   *   incremental ::+   *     A handle to an opaque @FT_Incremental handle provided by the client+   *     application.+   *+   *   glyph_index ::+   *     Index of relevant glyph.+   *+   *   vertical ::+   *     If true, return vertical metrics.+   *+   *   ametrics ::+   *     This parameter is used for both input and output.+   *     The original glyph metrics, if any, in font units.  If metrics are+   *     not available all the values must be set to zero.+   *+   * @output:+   *   ametrics ::+   *     The replacement glyph metrics in font units.+   *+   */+  typedef FT_Error+  (*FT_Incremental_GetGlyphMetricsFunc)+                      ( FT_Incremental              incremental,+                        FT_UInt                     glyph_index,+                        FT_Bool                     vertical,+                        FT_Incremental_MetricsRec  *ametrics );+++  /**************************************************************************+   *+   * @struct:+   *   FT_Incremental_FuncsRec+   *+   * @description:+   *   A table of functions for accessing fonts that load data+   *   incrementally.  Used in @FT_Incremental_InterfaceRec.+   *+   * @fields:+   *   get_glyph_data ::+   *     The function to get glyph data.  Must not be null.+   *+   *   free_glyph_data ::+   *     The function to release glyph data.  Must not be null.+   *+   *   get_glyph_metrics ::+   *     The function to get glyph metrics.  May be null if the font does+   *     not provide overriding glyph metrics.+   *+   */+  typedef struct  FT_Incremental_FuncsRec_+  {+    FT_Incremental_GetGlyphDataFunc     get_glyph_data;+    FT_Incremental_FreeGlyphDataFunc    free_glyph_data;+    FT_Incremental_GetGlyphMetricsFunc  get_glyph_metrics;++  } FT_Incremental_FuncsRec;+++  /***************************************************************************+   *+   * @struct:+   *   FT_Incremental_InterfaceRec+   *+   * @description:+   *   A structure to be used with @FT_Open_Face to indicate that the user+   *   wants to support incremental glyph loading.  You should use it with+   *   @FT_PARAM_TAG_INCREMENTAL as in the following example:+   *+   *     {+   *       FT_Incremental_InterfaceRec  inc_int;+   *       FT_Parameter                 parameter;+   *       FT_Open_Args                 open_args;+   *+   *+   *       // set up incremental descriptor+   *       inc_int.funcs  = my_funcs;+   *       inc_int.object = my_object;+   *+   *       // set up optional parameter+   *       parameter.tag  = FT_PARAM_TAG_INCREMENTAL;+   *       parameter.data = &inc_int;+   *+   *       // set up FT_Open_Args structure+   *       open_args.flags      = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;+   *       open_args.pathname   = my_font_pathname;+   *       open_args.num_params = 1;+   *       open_args.params     = &parameter; // we use one optional argument+   *+   *       // open the font+   *       error = FT_Open_Face( library, &open_args, index, &face );+   *       ...+   *     }+   *+   */+  typedef struct  FT_Incremental_InterfaceRec_+  {+    const FT_Incremental_FuncsRec*  funcs;+    FT_Incremental                  object;++  } FT_Incremental_InterfaceRec;+++  /***************************************************************************+   *+   * @type:+   *   FT_Incremental_Interface+   *+   * @description:+   *   A pointer to an @FT_Incremental_InterfaceRec structure.+   *+   */+  typedef FT_Incremental_InterfaceRec*   FT_Incremental_Interface;+++  /***************************************************************************+   *+   * @constant:+   *   FT_PARAM_TAG_INCREMENTAL+   *+   * @description:+   *   A constant used as the tag of @FT_Parameter structures to indicate+   *   an incremental loading object to be used by FreeType.+   *+   */+#define FT_PARAM_TAG_INCREMENTAL  FT_MAKE_TAG( 'i', 'n', 'c', 'r' )++  /* */++FT_END_HEADER++#endif /* __FTINCREM_H__ */+++/* END */
+ include/freetype/ftlcdfil.h view
@@ -0,0 +1,213 @@+/***************************************************************************/+/*                                                                         */+/*  ftlcdfil.h                                                             */+/*                                                                         */+/*    FreeType API for color filtering of subpixel bitmap glyphs           */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 2006, 2007, 2008, 2010 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FT_LCD_FILTER_H__+#define __FT_LCD_FILTER_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /***************************************************************************+   *+   * @section:+   *   lcd_filtering+   *+   * @title:+   *   LCD Filtering+   *+   * @abstract:+   *   Reduce color fringes of LCD-optimized bitmaps.+   *+   * @description:+   *   The @FT_Library_SetLcdFilter API can be used to specify a low-pass+   *   filter which is then applied to LCD-optimized bitmaps generated+   *   through @FT_Render_Glyph.  This is useful to reduce color fringes+   *   which would occur with unfiltered rendering.+   *+   *   Note that no filter is active by default, and that this function is+   *   *not* implemented in default builds of the library.  You need to+   *   #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file+   *   in order to activate it.+   */+++  /****************************************************************************+   *+   * @enum:+   *   FT_LcdFilter+   *+   * @description:+   *   A list of values to identify various types of LCD filters.+   *+   * @values:+   *   FT_LCD_FILTER_NONE ::+   *     Do not perform filtering.  When used with subpixel rendering, this+   *     results in sometimes severe color fringes.+   *+   *   FT_LCD_FILTER_DEFAULT ::+   *     The default filter reduces color fringes considerably, at the cost+   *     of a slight blurriness in the output.+   *+   *   FT_LCD_FILTER_LIGHT ::+   *     The light filter is a variant that produces less blurriness at the+   *     cost of slightly more color fringes than the default one.  It might+   *     be better, depending on taste, your monitor, or your personal vision.+   *+   *   FT_LCD_FILTER_LEGACY ::+   *     This filter corresponds to the original libXft color filter.  It+   *     provides high contrast output but can exhibit really bad color+   *     fringes if glyphs are not extremely well hinted to the pixel grid.+   *     In other words, it only works well if the TrueType bytecode+   *     interpreter is enabled *and* high-quality hinted fonts are used.+   *+   *     This filter is only provided for comparison purposes, and might be+   *     disabled or stay unsupported in the future.+   *+   * @since:+   *   2.3.0+   */+  typedef enum  FT_LcdFilter_+  {+    FT_LCD_FILTER_NONE    = 0,+    FT_LCD_FILTER_DEFAULT = 1,+    FT_LCD_FILTER_LIGHT   = 2,+    FT_LCD_FILTER_LEGACY  = 16,++    FT_LCD_FILTER_MAX   /* do not remove */++  } FT_LcdFilter;+++  /**************************************************************************+   *+   * @func:+   *   FT_Library_SetLcdFilter+   *+   * @description:+   *   This function is used to apply color filtering to LCD decimated+   *   bitmaps, like the ones used when calling @FT_Render_Glyph with+   *   @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V.+   *+   * @input:+   *   library ::+   *     A handle to the target library instance.+   *+   *   filter ::+   *     The filter type.+   *+   *     You can use @FT_LCD_FILTER_NONE here to disable this feature, or+   *     @FT_LCD_FILTER_DEFAULT to use a default filter that should work+   *     well on most LCD screens.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   This feature is always disabled by default.  Clients must make an+   *   explicit call to this function with a `filter' value other than+   *   @FT_LCD_FILTER_NONE in order to enable it.+   *+   *   Due to *PATENTS* covering subpixel rendering, this function doesn't+   *   do anything except returning `FT_Err_Unimplemented_Feature' if the+   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not+   *   defined in your build of the library, which should correspond to all+   *   default builds of FreeType.+   *+   *   The filter affects glyph bitmaps rendered through @FT_Render_Glyph,+   *   @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char.+   *+   *   It does _not_ affect the output of @FT_Outline_Render and+   *   @FT_Outline_Get_Bitmap.+   *+   *   If this feature is activated, the dimensions of LCD glyph bitmaps are+   *   either larger or taller than the dimensions of the corresponding+   *   outline with regards to the pixel grid.  For example, for+   *   @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and+   *   up to 3~pixels to the right.+   *+   *   The bitmap offset values are adjusted correctly, so clients shouldn't+   *   need to modify their layout and glyph positioning code when enabling+   *   the filter.+   *+   * @since:+   *   2.3.0+   */+  FT_EXPORT( FT_Error )+  FT_Library_SetLcdFilter( FT_Library    library,+                           FT_LcdFilter  filter );+++  /**************************************************************************+   *+   * @func:+   *   FT_Library_SetLcdFilterWeights+   *+   * @description:+   *   Use this function to override the filter weights selected by+   *   @FT_Library_SetLcdFilter.  By default, FreeType uses the quintuple+   *   (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10,+   *   0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and+   *   FT_LCD_FILTER_LEGACY.+   *+   * @input:+   *   library ::+   *     A handle to the target library instance.+   *+   *   weights ::+   *     A pointer to an array; the function copies the first five bytes and+   *     uses them to specify the filter weights.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   Due to *PATENTS* covering subpixel rendering, this function doesn't+   *   do anything except returning `FT_Err_Unimplemented_Feature' if the+   *   configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not+   *   defined in your build of the library, which should correspond to all+   *   default builds of FreeType.+   *+   *   This function must be called after @FT_Library_SetLcdFilter to have+   *   any effect.+   *+   * @since:+   *   2.4.0+   */+  FT_EXPORT( FT_Error )+  FT_Library_SetLcdFilterWeights( FT_Library      library,+                                  unsigned char  *weights );++  /* */+++FT_END_HEADER++#endif /* __FT_LCD_FILTER_H__ */+++/* END */
+ include/freetype/ftlist.h view
@@ -0,0 +1,277 @@+/***************************************************************************/+/*                                                                         */+/*  ftlist.h                                                               */+/*                                                                         */+/*    Generic list support for FreeType (specification).                   */+/*                                                                         */+/*  Copyright 1996-2001, 2003, 2007, 2010 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /*  This file implements functions relative to list processing.  Its     */+  /*  data structures are defined in `freetype.h'.                         */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTLIST_H__+#define __FTLIST_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    list_processing                                                    */+  /*                                                                       */+  /* <Title>                                                               */+  /*    List Processing                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Simple management of lists.                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains various definitions related to list          */+  /*    processing using doubly-linked nodes.                              */+  /*                                                                       */+  /* <Order>                                                               */+  /*    FT_List                                                            */+  /*    FT_ListNode                                                        */+  /*    FT_ListRec                                                         */+  /*    FT_ListNodeRec                                                     */+  /*                                                                       */+  /*    FT_List_Add                                                        */+  /*    FT_List_Insert                                                     */+  /*    FT_List_Find                                                       */+  /*    FT_List_Remove                                                     */+  /*    FT_List_Up                                                         */+  /*    FT_List_Iterate                                                    */+  /*    FT_List_Iterator                                                   */+  /*    FT_List_Finalize                                                   */+  /*    FT_List_Destructor                                                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Find                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Find the list node for a given listed object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    list :: A pointer to the parent list.                              */+  /*    data :: The address of the listed object.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    List node.  NULL if it wasn't found.                               */+  /*                                                                       */+  FT_EXPORT( FT_ListNode )+  FT_List_Find( FT_List  list,+                void*    data );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Add                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Append an element to the end of a list.                            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    list :: A pointer to the parent list.                              */+  /*    node :: The node to append.                                        */+  /*                                                                       */+  FT_EXPORT( void )+  FT_List_Add( FT_List      list,+               FT_ListNode  node );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Insert                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Insert an element at the head of a list.                           */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    list :: A pointer to parent list.                                  */+  /*    node :: The node to insert.                                        */+  /*                                                                       */+  FT_EXPORT( void )+  FT_List_Insert( FT_List      list,+                  FT_ListNode  node );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Remove                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Remove a node from a list.  This function doesn't check whether    */+  /*    the node is in the list!                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    node :: The node to remove.                                        */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    list :: A pointer to the parent list.                              */+  /*                                                                       */+  FT_EXPORT( void )+  FT_List_Remove( FT_List      list,+                  FT_ListNode  node );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Up                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Move a node to the head/top of a list.  Used to maintain LRU       */+  /*    lists.                                                             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    list :: A pointer to the parent list.                              */+  /*    node :: The node to move.                                          */+  /*                                                                       */+  FT_EXPORT( void )+  FT_List_Up( FT_List      list,+              FT_ListNode  node );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_List_Iterator                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An FT_List iterator function which is called during a list parse   */+  /*    by @FT_List_Iterate.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    node :: The current iteration list node.                           */+  /*                                                                       */+  /*    user :: A typeless pointer passed to @FT_List_Iterate.             */+  /*            Can be used to point to the iteration's state.             */+  /*                                                                       */+  typedef FT_Error+  (*FT_List_Iterator)( FT_ListNode  node,+                       void*        user );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Iterate                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parse a list and calls a given iterator function on each element.  */+  /*    Note that parsing is stopped as soon as one of the iterator calls  */+  /*    returns a non-zero value.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    list     :: A handle to the list.                                  */+  /*    iterator :: An iterator function, called on each node of the list. */+  /*    user     :: A user-supplied field which is passed as the second    */+  /*                argument to the iterator.                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result (a FreeType error code) of the last iterator call.      */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_List_Iterate( FT_List           list,+                   FT_List_Iterator  iterator,+                   void*             user );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_List_Destructor                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An @FT_List iterator function which is called during a list        */+  /*    finalization by @FT_List_Finalize to destroy all elements in a     */+  /*    given list.                                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    system :: The current system object.                               */+  /*                                                                       */+  /*    data   :: The current object to destroy.                           */+  /*                                                                       */+  /*    user   :: A typeless pointer passed to @FT_List_Iterate.  It can   */+  /*              be used to point to the iteration's state.               */+  /*                                                                       */+  typedef void+  (*FT_List_Destructor)( FT_Memory  memory,+                         void*      data,+                         void*      user );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_List_Finalize                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy all elements in the list as well as the list itself.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    list    :: A handle to the list.                                   */+  /*                                                                       */+  /*    destroy :: A list destructor that will be applied to each element  */+  /*               of the list.                                            */+  /*                                                                       */+  /*    memory  :: The current memory object which handles deallocation.   */+  /*                                                                       */+  /*    user    :: A user-supplied field which is passed as the last       */+  /*               argument to the destructor.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function expects that all nodes added by @FT_List_Add or      */+  /*    @FT_List_Insert have been dynamically allocated.                   */+  /*                                                                       */+  FT_EXPORT( void )+  FT_List_Finalize( FT_List             list,+                    FT_List_Destructor  destroy,+                    FT_Memory           memory,+                    void*               user );+++  /* */+++FT_END_HEADER++#endif /* __FTLIST_H__ */+++/* END */
+ include/freetype/ftlzw.h view
@@ -0,0 +1,99 @@+/***************************************************************************/+/*                                                                         */+/*  ftlzw.h                                                                */+/*                                                                         */+/*    LZW-compressed stream support.                                       */+/*                                                                         */+/*  Copyright 2004, 2006 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTLZW_H__+#define __FTLZW_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    lzw                                                                */+  /*                                                                       */+  /* <Title>                                                               */+  /*    LZW Streams                                                        */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Using LZW-compressed font files.                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of LZW-specific functions.   */+  /*                                                                       */+  /*************************************************************************/++ /************************************************************************+  *+  * @function:+  *   FT_Stream_OpenLZW+  *+  * @description:+  *   Open a new stream to parse LZW-compressed font files.  This is+  *   mainly used to support the compressed `*.pcf.Z' fonts that come+  *   with XFree86.+  *+  * @input:+  *   stream :: The target embedding stream.+  *+  *   source :: The source stream.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   The source stream must be opened _before_ calling this function.+  *+  *   Calling the internal function `FT_Stream_Close' on the new stream will+  *   *not* call `FT_Stream_Close' on the source stream.  None of the stream+  *   objects will be released to the heap.+  *+  *   The stream implementation is very basic and resets the decompression+  *   process each time seeking backwards is needed within the stream+  *+  *   In certain builds of the library, LZW compression recognition is+  *   automatically handled when calling @FT_New_Face or @FT_Open_Face.+  *   This means that if no font driver is capable of handling the raw+  *   compressed file, the library will try to open a LZW stream from it+  *   and re-open the face with it.+  *+  *   This function may return `FT_Err_Unimplemented_Feature' if your build+  *   of FreeType was not compiled with LZW support.+  */+  FT_EXPORT( FT_Error )+  FT_Stream_OpenLZW( FT_Stream  stream,+                     FT_Stream  source );++ /* */+++FT_END_HEADER++#endif /* __FTLZW_H__ */+++/* END */
+ include/freetype/ftmac.h view
@@ -0,0 +1,274 @@+/***************************************************************************/+/*                                                                         */+/*  ftmac.h                                                                */+/*                                                                         */+/*    Additional Mac-specific API.                                         */+/*                                                                         */+/*  Copyright 1996-2001, 2004, 2006, 2007 by                               */+/*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/* NOTE: Include this file after <freetype/freetype.h> and after any       */+/*       Mac-specific headers (because this header uses Mac types such as  */+/*       Handle, FSSpec, FSRef, etc.)                                      */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTMAC_H__+#define __FTMAC_H__+++#include <ft2build.h>+++FT_BEGIN_HEADER+++/* gcc-3.4.1 and later can warn about functions tagged as deprecated */+#ifndef FT_DEPRECATED_ATTRIBUTE+#if defined(__GNUC__)                                               && \+    ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))+#define FT_DEPRECATED_ATTRIBUTE  __attribute__((deprecated))+#else+#define FT_DEPRECATED_ATTRIBUTE+#endif+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    mac_specific                                                       */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Mac Specific Interface                                             */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Only available on the Macintosh.                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The following definitions are only available if FreeType is        */+  /*    compiled on a Macintosh.                                           */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face_From_FOND                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new face object from a FOND resource.                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    fond       :: A FOND resource.                                     */+  /*                                                                       */+  /*    face_index :: Only supported for the -1 `sanity check' special     */+  /*                  case.                                                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Notes>                                                               */+  /*    This function can be used to create @FT_Face objects from fonts    */+  /*    that are installed in the system as follows.                       */+  /*                                                                       */+  /*    {                                                                  */+  /*      fond = GetResource( 'FOND', fontName );                          */+  /*      error = FT_New_Face_From_FOND( library, fond, 0, &face );        */+  /*    }                                                                  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Face_From_FOND( FT_Library  library,+                         Handle      fond,+                         FT_Long     face_index,+                         FT_Face    *aface )+                       FT_DEPRECATED_ATTRIBUTE;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_GetFile_From_Mac_Name                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return an FSSpec for the disk file containing the named font.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    fontName   :: Mac OS name of the font (e.g., Times New Roman       */+  /*                  Bold).                                               */+  /*                                                                       */+  /* <Output>                                                              */+  /*    pathSpec   :: FSSpec to the file.  For passing to                  */+  /*                  @FT_New_Face_From_FSSpec.                            */+  /*                                                                       */+  /*    face_index :: Index of the face.  For passing to                   */+  /*                  @FT_New_Face_From_FSSpec.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_GetFile_From_Mac_Name( const char*  fontName,+                            FSSpec*      pathSpec,+                            FT_Long*     face_index )+                          FT_DEPRECATED_ATTRIBUTE;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_GetFile_From_Mac_ATS_Name                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return an FSSpec for the disk file containing the named font.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    fontName   :: Mac OS name of the font in ATS framework.            */+  /*                                                                       */+  /* <Output>                                                              */+  /*    pathSpec   :: FSSpec to the file. For passing to                   */+  /*                  @FT_New_Face_From_FSSpec.                            */+  /*                                                                       */+  /*    face_index :: Index of the face. For passing to                    */+  /*                  @FT_New_Face_From_FSSpec.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_GetFile_From_Mac_ATS_Name( const char*  fontName,+                                FSSpec*      pathSpec,+                                FT_Long*     face_index )+                              FT_DEPRECATED_ATTRIBUTE;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_GetFilePath_From_Mac_ATS_Name                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a pathname of the disk file and face index for given font   */+  /*    name which is handled by ATS framework.                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    fontName    :: Mac OS name of the font in ATS framework.           */+  /*                                                                       */+  /* <Output>                                                              */+  /*    path        :: Buffer to store pathname of the file.  For passing  */+  /*                   to @FT_New_Face.  The client must allocate this     */+  /*                   buffer before calling this function.                */+  /*                                                                       */+  /*    maxPathSize :: Lengths of the buffer `path' that client allocated. */+  /*                                                                       */+  /*    face_index  :: Index of the face.  For passing to @FT_New_Face.    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,+                                    UInt8*       path,+                                    UInt32       maxPathSize,+                                    FT_Long*     face_index )+                                  FT_DEPRECATED_ATTRIBUTE;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face_From_FSSpec                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new face object from a given resource and typeface index  */+  /*    using an FSSpec to the font file.                                  */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    spec       :: FSSpec to the font file.                             */+  /*                                                                       */+  /*    face_index :: The index of the face within the resource.  The      */+  /*                  first face has index~0.                              */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    @FT_New_Face_From_FSSpec is identical to @FT_New_Face except       */+  /*    it accepts an FSSpec instead of a path.                            */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Face_From_FSSpec( FT_Library     library,+                           const FSSpec  *spec,+                           FT_Long        face_index,+                           FT_Face       *aface )+                         FT_DEPRECATED_ATTRIBUTE;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face_From_FSRef                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new face object from a given resource and typeface index  */+  /*    using an FSRef to the font file.                                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library resource.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    spec       :: FSRef to the font file.                              */+  /*                                                                       */+  /*    face_index :: The index of the face within the resource.  The      */+  /*                  first face has index~0.                              */+  /* <Output>                                                              */+  /*    aface      :: A handle to a new face object.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    @FT_New_Face_From_FSRef is identical to @FT_New_Face except        */+  /*    it accepts an FSRef instead of a path.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Face_From_FSRef( FT_Library    library,+                          const FSRef  *ref,+                          FT_Long       face_index,+                          FT_Face      *aface )+                        FT_DEPRECATED_ATTRIBUTE;++  /* */+++FT_END_HEADER+++#endif /* __FTMAC_H__ */+++/* END */
+ include/freetype/ftmm.h view
@@ -0,0 +1,378 @@+/***************************************************************************/+/*                                                                         */+/*  ftmm.h                                                                 */+/*                                                                         */+/*    FreeType Multiple Master font interface (specification).             */+/*                                                                         */+/*  Copyright 1996-2001, 2003, 2004, 2006, 2009 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTMM_H__+#define __FTMM_H__+++#include <ft2build.h>+#include FT_TYPE1_TABLES_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    multiple_masters                                                   */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Multiple Masters                                                   */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    How to manage Multiple Masters fonts.                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The following types and functions are used to manage Multiple      */+  /*    Master fonts, i.e., the selection of specific design instances by  */+  /*    setting design axis coordinates.                                   */+  /*                                                                       */+  /*    George Williams has extended this interface to make it work with   */+  /*    both Type~1 Multiple Masters fonts and GX distortable (var)        */+  /*    fonts.  Some of these routines only work with MM fonts, others     */+  /*    will work with both types.  They are similar enough that a         */+  /*    consistent interface makes sense.                                  */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_MM_Axis                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to model a given axis in design space for  */+  /*    Multiple Masters fonts.                                            */+  /*                                                                       */+  /*    This structure can't be used for GX var fonts.                     */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    name    :: The axis's name.                                        */+  /*                                                                       */+  /*    minimum :: The axis's minimum design coordinate.                   */+  /*                                                                       */+  /*    maximum :: The axis's maximum design coordinate.                   */+  /*                                                                       */+  typedef struct  FT_MM_Axis_+  {+    FT_String*  name;+    FT_Long     minimum;+    FT_Long     maximum;++  } FT_MM_Axis;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Multi_Master                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model the axes and space of a Multiple Masters */+  /*    font.                                                              */+  /*                                                                       */+  /*    This structure can't be used for GX var fonts.                     */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_axis    :: Number of axes.  Cannot exceed~4.                   */+  /*                                                                       */+  /*    num_designs :: Number of designs; should be normally 2^num_axis    */+  /*                   even though the Type~1 specification strangely      */+  /*                   allows for intermediate designs to be present. This */+  /*                   number cannot exceed~16.                            */+  /*                                                                       */+  /*    axis        :: A table of axis descriptors.                        */+  /*                                                                       */+  typedef struct  FT_Multi_Master_+  {+    FT_UInt     num_axis;+    FT_UInt     num_designs;+    FT_MM_Axis  axis[T1_MAX_MM_AXIS];++  } FT_Multi_Master;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Var_Axis                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to model a given axis in design space for  */+  /*    Multiple Masters and GX var fonts.                                 */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    name    :: The axis's name.                                        */+  /*               Not always meaningful for GX.                           */+  /*                                                                       */+  /*    minimum :: The axis's minimum design coordinate.                   */+  /*                                                                       */+  /*    def     :: The axis's default design coordinate.                   */+  /*               FreeType computes meaningful default values for MM; it  */+  /*               is then an integer value, not in 16.16 format.          */+  /*                                                                       */+  /*    maximum :: The axis's maximum design coordinate.                   */+  /*                                                                       */+  /*    tag     :: The axis's tag (the GX equivalent to `name').           */+  /*               FreeType provides default values for MM if possible.    */+  /*                                                                       */+  /*    strid   :: The entry in `name' table (another GX version of        */+  /*               `name').                                                */+  /*               Not meaningful for MM.                                  */+  /*                                                                       */+  typedef struct  FT_Var_Axis_+  {+    FT_String*  name;++    FT_Fixed    minimum;+    FT_Fixed    def;+    FT_Fixed    maximum;++    FT_ULong    tag;+    FT_UInt     strid;++  } FT_Var_Axis;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Var_Named_Style                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to model a named style in a GX var font.   */+  /*                                                                       */+  /*    This structure can't be used for MM fonts.                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    coords :: The design coordinates for this style.                   */+  /*              This is an array with one entry for each axis.           */+  /*                                                                       */+  /*    strid  :: The entry in `name' table identifying this style.        */+  /*                                                                       */+  typedef struct  FT_Var_Named_Style_+  {+    FT_Fixed*  coords;+    FT_UInt    strid;++  } FT_Var_Named_Style;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_MM_Var                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model the axes and space of a Multiple Masters */+  /*    or GX var distortable font.                                        */+  /*                                                                       */+  /*    Some fields are specific to one format and not to the other.       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_axis        :: The number of axes.  The maximum value is~4 for */+  /*                       MM; no limit in GX.                             */+  /*                                                                       */+  /*    num_designs     :: The number of designs; should be normally       */+  /*                       2^num_axis for MM fonts.  Not meaningful for GX */+  /*                       (where every glyph could have a different       */+  /*                       number of designs).                             */+  /*                                                                       */+  /*    num_namedstyles :: The number of named styles; only meaningful for */+  /*                       GX which allows certain design coordinates to   */+  /*                       have a string ID (in the `name' table)          */+  /*                       associated with them.  The font can tell the    */+  /*                       user that, for example, Weight=1.5 is `Bold'.   */+  /*                                                                       */+  /*    axis            :: A table of axis descriptors.                    */+  /*                       GX fonts contain slightly more data than MM.    */+  /*                                                                       */+  /*    namedstyles     :: A table of named styles.                        */+  /*                       Only meaningful with GX.                        */+  /*                                                                       */+  typedef struct  FT_MM_Var_+  {+    FT_UInt              num_axis;+    FT_UInt              num_designs;+    FT_UInt              num_namedstyles;+    FT_Var_Axis*         axis;+    FT_Var_Named_Style*  namedstyle;++  } FT_MM_Var;+++  /* */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Multi_Master                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the Multiple Master descriptor of a given font.           */+  /*                                                                       */+  /*    This function can't be used with GX fonts.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face    :: A handle to the source face.                            */+  /*                                                                       */+  /* <Output>                                                              */+  /*    amaster :: The Multiple Masters descriptor.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Multi_Master( FT_Face           face,+                       FT_Multi_Master  *amaster );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_MM_Var                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the Multiple Master/GX var descriptor of a given font.    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face    :: A handle to the source face.                            */+  /*                                                                       */+  /* <Output>                                                              */+  /*    amaster :: The Multiple Masters/GX var descriptor.                 */+  /*               Allocates a data structure, which the user must free    */+  /*               (a single call to FT_FREE will do it).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_MM_Var( FT_Face      face,+                 FT_MM_Var*  *amaster );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_MM_Design_Coordinates                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    For Multiple Masters fonts, choose an interpolated font design     */+  /*    through design coordinates.                                        */+  /*                                                                       */+  /*    This function can't be used with GX fonts.                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: A handle to the source face.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    num_coords :: The number of design coordinates (must be equal to   */+  /*                  the number of axes in the font).                     */+  /*                                                                       */+  /*    coords     :: An array of design coordinates.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_MM_Design_Coordinates( FT_Face   face,+                                FT_UInt   num_coords,+                                FT_Long*  coords );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Var_Design_Coordinates                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    For Multiple Master or GX Var fonts, choose an interpolated font   */+  /*    design through design coordinates.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: A handle to the source face.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    num_coords :: The number of design coordinates (must be equal to   */+  /*                  the number of axes in the font).                     */+  /*                                                                       */+  /*    coords     :: An array of design coordinates.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Var_Design_Coordinates( FT_Face    face,+                                 FT_UInt    num_coords,+                                 FT_Fixed*  coords );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_MM_Blend_Coordinates                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    For Multiple Masters and GX var fonts, choose an interpolated font */+  /*    design through normalized blend coordinates.                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: A handle to the source face.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    num_coords :: The number of design coordinates (must be equal to   */+  /*                  the number of axes in the font).                     */+  /*                                                                       */+  /*    coords     :: The design coordinates array (each element must be   */+  /*                  between 0 and 1.0).                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_MM_Blend_Coordinates( FT_Face    face,+                               FT_UInt    num_coords,+                               FT_Fixed*  coords );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Var_Blend_Coordinates                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This is another name of @FT_Set_MM_Blend_Coordinates.              */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Var_Blend_Coordinates( FT_Face    face,+                                FT_UInt    num_coords,+                                FT_Fixed*  coords );+++  /* */+++FT_END_HEADER++#endif /* __FTMM_H__ */+++/* END */
+ include/freetype/ftmodapi.h view
@@ -0,0 +1,483 @@+/***************************************************************************/+/*                                                                         */+/*  ftmodapi.h                                                             */+/*                                                                         */+/*    FreeType modules public interface (specification).                   */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009, 2010 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTMODAPI_H__+#define __FTMODAPI_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    module_management                                                  */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Module Management                                                  */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    How to add, upgrade, and remove modules from FreeType.             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The definitions below are used to manage modules within FreeType.  */+  /*    Modules can be added, upgraded, and removed at runtime.            */+  /*                                                                       */+  /*************************************************************************/+++  /* module bit flags */+#define FT_MODULE_FONT_DRIVER         1  /* this module is a font driver  */+#define FT_MODULE_RENDERER            2  /* this module is a renderer     */+#define FT_MODULE_HINTER              4  /* this module is a glyph hinter */+#define FT_MODULE_STYLER              8  /* this module is a styler       */++#define FT_MODULE_DRIVER_SCALABLE     0x100   /* the driver supports      */+                                              /* scalable fonts           */+#define FT_MODULE_DRIVER_NO_OUTLINES  0x200   /* the driver does not      */+                                              /* support vector outlines  */+#define FT_MODULE_DRIVER_HAS_HINTER   0x400   /* the driver provides its  */+                                              /* own hinter               */+++  /* deprecated values */+#define ft_module_font_driver         FT_MODULE_FONT_DRIVER+#define ft_module_renderer            FT_MODULE_RENDERER+#define ft_module_hinter              FT_MODULE_HINTER+#define ft_module_styler              FT_MODULE_STYLER++#define ft_module_driver_scalable     FT_MODULE_DRIVER_SCALABLE+#define ft_module_driver_no_outlines  FT_MODULE_DRIVER_NO_OUTLINES+#define ft_module_driver_has_hinter   FT_MODULE_DRIVER_HAS_HINTER+++  typedef FT_Pointer  FT_Module_Interface;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Module_Constructor                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to initialize (not create) a new module object.    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    module :: The module to initialize.                                */+  /*                                                                       */+  typedef FT_Error+  (*FT_Module_Constructor)( FT_Module  module );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Module_Destructor                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to finalize (not destroy) a given module object.   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    module :: The module to finalize.                                  */+  /*                                                                       */+  typedef void+  (*FT_Module_Destructor)( FT_Module  module );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Module_Requester                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to query a given module for a specific interface.  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    module :: The module to finalize.                                  */+  /*                                                                       */+  /*    name ::   The name of the interface in the module.                 */+  /*                                                                       */+  typedef FT_Module_Interface+  (*FT_Module_Requester)( FT_Module    module,+                          const char*  name );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Module_Class                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The module class descriptor.                                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    module_flags    :: Bit flags describing the module.                */+  /*                                                                       */+  /*    module_size     :: The size of one module object/instance in       */+  /*                       bytes.                                          */+  /*                                                                       */+  /*    module_name     :: The name of the module.                         */+  /*                                                                       */+  /*    module_version  :: The version, as a 16.16 fixed number            */+  /*                       (major.minor).                                  */+  /*                                                                       */+  /*    module_requires :: The version of FreeType this module requires,   */+  /*                       as a 16.16 fixed number (major.minor).  Starts  */+  /*                       at version 2.0, i.e., 0x20000.                  */+  /*                                                                       */+  /*    module_init     :: The initializing function.                      */+  /*                                                                       */+  /*    module_done     :: The finalizing function.                        */+  /*                                                                       */+  /*    get_interface   :: The interface requesting function.              */+  /*                                                                       */+  typedef struct  FT_Module_Class_+  {+    FT_ULong               module_flags;+    FT_Long                module_size;+    const FT_String*       module_name;+    FT_Fixed               module_version;+    FT_Fixed               module_requires;++    const void*            module_interface;++    FT_Module_Constructor  module_init;+    FT_Module_Destructor   module_done;+    FT_Module_Requester    get_interface;++  } FT_Module_Class;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Add_Module                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Add a new module to a given library instance.                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library :: A handle to the library object.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    clazz   :: A pointer to class descriptor for the module.           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    An error will be returned if a module already exists by that name, */+  /*    or if the module requires a version of FreeType that is too great. */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Add_Module( FT_Library              library,+                 const FT_Module_Class*  clazz );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Module                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Find a module by its name.                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library     :: A handle to the library object.                     */+  /*                                                                       */+  /*    module_name :: The module's name (as an ASCII string).             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A module handle.  0~if none was found.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    FreeType's internal modules aren't documented very well, and you   */+  /*    should look up the source code for details.                        */+  /*                                                                       */+  FT_EXPORT( FT_Module )+  FT_Get_Module( FT_Library   library,+                 const char*  module_name );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Remove_Module                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Remove a given module from a library instance.                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library :: A handle to a library object.                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    module  :: A handle to a module object.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The module object is destroyed by the function in case of success. */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Remove_Module( FT_Library  library,+                    FT_Module   module );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Reference_Library                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A counter gets initialized to~1 at the time an @FT_Library         */+  /*    structure is created.  This function increments the counter.       */+  /*    @FT_Done_Library then only destroys a library if the counter is~1, */+  /*    otherwise it simply decrements the counter.                        */+  /*                                                                       */+  /*    This function helps in managing life-cycles of structures which    */+  /*    reference @FT_Library objects.                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to a target library object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Since>                                                               */+  /*    2.4.2                                                              */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Reference_Library( FT_Library  library );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Library                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to create a new FreeType library instance    */+  /*    from a given memory object.  It is thus possible to use libraries  */+  /*    with distinct memory allocators within the same program.           */+  /*                                                                       */+  /*    Normally, you would call this function (followed by a call to      */+  /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module)    */+  /*    instead of @FT_Init_FreeType to initialize the FreeType library.   */+  /*                                                                       */+  /*    Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a      */+  /*    library instance.                                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory   :: A handle to the original memory object.                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    alibrary :: A pointer to handle of a new library object.           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    See the discussion of reference counters in the description of     */+  /*    @FT_Reference_Library.                                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Library( FT_Memory    memory,+                  FT_Library  *alibrary );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_Library                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Discard a given library object.  This closes all drivers and       */+  /*    discards all resource objects.                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to the target library.                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    See the discussion of reference counters in the description of     */+  /*    @FT_Reference_Library.                                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Done_Library( FT_Library  library );++/* */++  typedef void+  (*FT_DebugHook_Func)( void*  arg );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Debug_Hook                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Set a debug hook function for debugging the interpreter of a font  */+  /*    format.                                                            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    hook_index :: The index of the debug hook.  You should use the     */+  /*                  values defined in `ftobjs.h', e.g.,                  */+  /*                  `FT_DEBUG_HOOK_TRUETYPE'.                            */+  /*                                                                       */+  /*    debug_hook :: The function used to debug the interpreter.          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Currently, four debug hook slots are available, but only two (for  */+  /*    the TrueType and the Type~1 interpreter) are defined.              */+  /*                                                                       */+  /*    Since the internal headers of FreeType are no longer installed,    */+  /*    the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly.      */+  /*    This is a bug and will be fixed in a forthcoming release.          */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Set_Debug_Hook( FT_Library         library,+                     FT_UInt            hook_index,+                     FT_DebugHook_Func  debug_hook );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Add_Default_Modules                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Add the set of default drivers to a given library object.          */+  /*    This is only useful when you create a library object with          */+  /*    @FT_New_Library (usually to plug a custom memory manager).         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library :: A handle to a new library object.                       */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Add_Default_Modules( FT_Library  library );++++  /**************************************************************************+   *+   * @section:+   *   truetype_engine+   *+   * @title:+   *   The TrueType Engine+   *+   * @abstract:+   *   TrueType bytecode support.+   *+   * @description:+   *   This section contains a function used to query the level of TrueType+   *   bytecode support compiled in this version of the library.+   *+   */+++  /**************************************************************************+   *+   *  @enum:+   *     FT_TrueTypeEngineType+   *+   *  @description:+   *     A list of values describing which kind of TrueType bytecode+   *     engine is implemented in a given FT_Library instance.  It is used+   *     by the @FT_Get_TrueType_Engine_Type function.+   *+   *  @values:+   *     FT_TRUETYPE_ENGINE_TYPE_NONE ::+   *       The library doesn't implement any kind of bytecode interpreter.+   *+   *     FT_TRUETYPE_ENGINE_TYPE_UNPATENTED ::+   *       The library implements a bytecode interpreter that doesn't+   *       support the patented operations of the TrueType virtual machine.+   *+   *       Its main use is to load certain Asian fonts which position and+   *       scale glyph components with bytecode instructions.  It produces+   *       bad output for most other fonts.+   *+   *    FT_TRUETYPE_ENGINE_TYPE_PATENTED ::+   *       The library implements a bytecode interpreter that covers+   *       the full instruction set of the TrueType virtual machine (this+   *       was governed by patents until May 2010, hence the name).+   *+   *  @since:+   *       2.2+   *+   */+  typedef enum  FT_TrueTypeEngineType_+  {+    FT_TRUETYPE_ENGINE_TYPE_NONE = 0,+    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED,+    FT_TRUETYPE_ENGINE_TYPE_PATENTED++  } FT_TrueTypeEngineType;+++  /**************************************************************************+   *+   *  @func:+   *     FT_Get_TrueType_Engine_Type+   *+   *  @description:+   *     Return an @FT_TrueTypeEngineType value to indicate which level of+   *     the TrueType virtual machine a given library instance supports.+   *+   *  @input:+   *     library ::+   *       A library instance.+   *+   *  @return:+   *     A value indicating which level is supported.+   *+   *  @since:+   *     2.2+   *+   */+  FT_EXPORT( FT_TrueTypeEngineType )+  FT_Get_TrueType_Engine_Type( FT_Library  library );+++  /* */+++FT_END_HEADER++#endif /* __FTMODAPI_H__ */+++/* END */
+ include/freetype/ftmoderr.h view
@@ -0,0 +1,155 @@+/***************************************************************************/+/*                                                                         */+/*  ftmoderr.h                                                             */+/*                                                                         */+/*    FreeType module error offsets (specification).                       */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the FreeType module error offsets.        */+  /*                                                                       */+  /* The lower byte gives the error code, the higher byte gives the        */+  /* module.  The base module has error offset 0.  For example, the error  */+  /* `FT_Err_Invalid_File_Format' has value 0x003, the error               */+  /* `TT_Err_Invalid_File_Format' has value 0x1103, the error              */+  /* `T1_Err_Invalid_File_Format' has value 0x1203, etc.                   */+  /*                                                                       */+  /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h   */+  /* to make the higher byte always zero (disabling the module error       */+  /* mechanism).                                                           */+  /*                                                                       */+  /* It can also be used to create a module error message table easily     */+  /* with something like                                                   */+  /*                                                                       */+  /*   {                                                                   */+  /*     #undef __FTMODERR_H__                                             */+  /*     #define FT_MODERRDEF( e, v, s )  { FT_Mod_Err_ ## e, s },         */+  /*     #define FT_MODERR_START_LIST     {                                */+  /*     #define FT_MODERR_END_LIST       { 0, 0 } };                      */+  /*                                                                       */+  /*     const struct                                                      */+  /*     {                                                                 */+  /*       int          mod_err_offset;                                    */+  /*       const char*  mod_err_msg                                        */+  /*     } ft_mod_errors[] =                                               */+  /*                                                                       */+  /*     #include FT_MODULE_ERRORS_H                                       */+  /*   }                                                                   */+  /*                                                                       */+  /* To use such a table, all errors must be ANDed with 0xFF00 to remove   */+  /* the error code.                                                       */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTMODERR_H__+#define __FTMODERR_H__+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****                       SETUP MACROS                      *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/+++#undef  FT_NEED_EXTERN_C++#ifndef FT_MODERRDEF++#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS+#define FT_MODERRDEF( e, v, s )  FT_Mod_Err_ ## e = v,+#else+#define FT_MODERRDEF( e, v, s )  FT_Mod_Err_ ## e = 0,+#endif++#define FT_MODERR_START_LIST  enum {+#define FT_MODERR_END_LIST    FT_Mod_Err_Max };++#ifdef __cplusplus+#define FT_NEED_EXTERN_C+  extern "C" {+#endif++#endif /* !FT_MODERRDEF */+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****               LIST MODULE ERROR BASES                   *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/+++#ifdef FT_MODERR_START_LIST+  FT_MODERR_START_LIST+#endif+++  FT_MODERRDEF( Base,      0x000, "base module" )+  FT_MODERRDEF( Autofit,   0x100, "autofitter module" )+  FT_MODERRDEF( BDF,       0x200, "BDF module" )+  FT_MODERRDEF( Cache,     0x300, "cache module" )+  FT_MODERRDEF( CFF,       0x400, "CFF module" )+  FT_MODERRDEF( CID,       0x500, "CID module" )+  FT_MODERRDEF( Gzip,      0x600, "Gzip module" )+  FT_MODERRDEF( LZW,       0x700, "LZW module" )+  FT_MODERRDEF( OTvalid,   0x800, "OpenType validation module" )+  FT_MODERRDEF( PCF,       0x900, "PCF module" )+  FT_MODERRDEF( PFR,       0xA00, "PFR module" )+  FT_MODERRDEF( PSaux,     0xB00, "PS auxiliary module" )+  FT_MODERRDEF( PShinter,  0xC00, "PS hinter module" )+  FT_MODERRDEF( PSnames,   0xD00, "PS names module" )+  FT_MODERRDEF( Raster,    0xE00, "raster module" )+  FT_MODERRDEF( SFNT,      0xF00, "SFNT module" )+  FT_MODERRDEF( Smooth,   0x1000, "smooth raster module" )+  FT_MODERRDEF( TrueType, 0x1100, "TrueType module" )+  FT_MODERRDEF( Type1,    0x1200, "Type 1 module" )+  FT_MODERRDEF( Type42,   0x1300, "Type 42 module" )+  FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" )+++#ifdef FT_MODERR_END_LIST+  FT_MODERR_END_LIST+#endif+++  /*******************************************************************/+  /*******************************************************************/+  /*****                                                         *****/+  /*****                      CLEANUP                            *****/+  /*****                                                         *****/+  /*******************************************************************/+  /*******************************************************************/+++#ifdef FT_NEED_EXTERN_C+  }+#endif++#undef FT_MODERR_START_LIST+#undef FT_MODERR_END_LIST+#undef FT_MODERRDEF+#undef FT_NEED_EXTERN_C+++#endif /* __FTMODERR_H__ */+++/* END */
+ include/freetype/ftotval.h view
@@ -0,0 +1,203 @@+/***************************************************************************/+/*                                                                         */+/*  ftotval.h                                                              */+/*                                                                         */+/*    FreeType API for validating OpenType tables (specification).         */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2007 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++/***************************************************************************/+/*                                                                         */+/*                                                                         */+/* Warning: This module might be moved to a different library in the       */+/*          future to avoid a tight dependency between FreeType and the    */+/*          OpenType specification.                                        */+/*                                                                         */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTOTVAL_H__+#define __FTOTVAL_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    ot_validation                                                      */+  /*                                                                       */+  /* <Title>                                                               */+  /*    OpenType Validation                                                */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    An API to validate OpenType tables.                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of functions to validate     */+  /*    some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).         */+  /*                                                                       */+  /*************************************************************************/+++ /**********************************************************************+  *+  * @enum:+  *    FT_VALIDATE_OTXXX+  *+  * @description:+  *    A list of bit-field constants used with @FT_OpenType_Validate to+  *    indicate which OpenType tables should be validated.+  *+  * @values:+  *    FT_VALIDATE_BASE ::+  *      Validate BASE table.+  *+  *    FT_VALIDATE_GDEF ::+  *      Validate GDEF table.+  *+  *    FT_VALIDATE_GPOS ::+  *      Validate GPOS table.+  *+  *    FT_VALIDATE_GSUB ::+  *      Validate GSUB table.+  *+  *    FT_VALIDATE_JSTF ::+  *      Validate JSTF table.+  *+  *    FT_VALIDATE_MATH ::+  *      Validate MATH table.+  *+  *    FT_VALIDATE_OT ::+  *      Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).+  *+  */+#define FT_VALIDATE_BASE  0x0100+#define FT_VALIDATE_GDEF  0x0200+#define FT_VALIDATE_GPOS  0x0400+#define FT_VALIDATE_GSUB  0x0800+#define FT_VALIDATE_JSTF  0x1000+#define FT_VALIDATE_MATH  0x2000++#define FT_VALIDATE_OT  FT_VALIDATE_BASE | \+                        FT_VALIDATE_GDEF | \+                        FT_VALIDATE_GPOS | \+                        FT_VALIDATE_GSUB | \+                        FT_VALIDATE_JSTF | \+                        FT_VALIDATE_MATH++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_OpenType_Validate+  *+  * @description:+  *    Validate various OpenType tables to assure that all offsets and+  *    indices are valid.  The idea is that a higher-level library which+  *    actually does the text layout can access those tables without+  *    error checking (which can be quite time consuming).+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    validation_flags ::+  *       A bit field which specifies the tables to be validated.  See+  *       @FT_VALIDATE_OTXXX for possible values.+  *+  * @output:+  *    BASE_table ::+  *       A pointer to the BASE table.+  *+  *    GDEF_table ::+  *       A pointer to the GDEF table.+  *+  *    GPOS_table ::+  *       A pointer to the GPOS table.+  *+  *    GSUB_table ::+  *       A pointer to the GSUB table.+  *+  *    JSTF_table ::+  *       A pointer to the JSTF table.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   This function only works with OpenType fonts, returning an error+  *   otherwise.+  *+  *   After use, the application should deallocate the five tables with+  *   @FT_OpenType_Free.  A NULL value indicates that the table either+  *   doesn't exist in the font, or the application hasn't asked for+  *   validation.+  */+  FT_EXPORT( FT_Error )+  FT_OpenType_Validate( FT_Face    face,+                        FT_UInt    validation_flags,+                        FT_Bytes  *BASE_table,+                        FT_Bytes  *GDEF_table,+                        FT_Bytes  *GPOS_table,+                        FT_Bytes  *GSUB_table,+                        FT_Bytes  *JSTF_table );++  /* */++ /**********************************************************************+  *+  * @function:+  *    FT_OpenType_Free+  *+  * @description:+  *    Free the buffer allocated by OpenType validator.+  *+  * @input:+  *    face ::+  *       A handle to the input face.+  *+  *    table ::+  *       The pointer to the buffer that is allocated by+  *       @FT_OpenType_Validate.+  *+  * @note:+  *   This function must be used to free the buffer allocated by+  *   @FT_OpenType_Validate only.+  */+  FT_EXPORT( void )+  FT_OpenType_Free( FT_Face   face,+                    FT_Bytes  table );+++ /* */+++FT_END_HEADER++#endif /* __FTOTVAL_H__ */+++/* END */
+ include/freetype/ftoutln.h view
@@ -0,0 +1,537 @@+/***************************************************************************/+/*                                                                         */+/*  ftoutln.h                                                              */+/*                                                                         */+/*    Support for the FT_Outline type used to store glyph shapes of        */+/*    most scalable font formats (specification).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTOUTLN_H__+#define __FTOUTLN_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    outline_processing                                                 */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Outline Processing                                                 */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Functions to create, transform, and render vectorial glyph images. */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains routines used to create and destroy scalable */+  /*    glyph images known as `outlines'.  These can also be measured,     */+  /*    transformed, and converted into bitmaps and pixmaps.               */+  /*                                                                       */+  /* <Order>                                                               */+  /*    FT_Outline                                                         */+  /*    FT_OUTLINE_FLAGS                                                   */+  /*    FT_Outline_New                                                     */+  /*    FT_Outline_Done                                                    */+  /*    FT_Outline_Copy                                                    */+  /*    FT_Outline_Translate                                               */+  /*    FT_Outline_Transform                                               */+  /*    FT_Outline_Embolden                                                */+  /*    FT_Outline_Reverse                                                 */+  /*    FT_Outline_Check                                                   */+  /*                                                                       */+  /*    FT_Outline_Get_CBox                                                */+  /*    FT_Outline_Get_BBox                                                */+  /*                                                                       */+  /*    FT_Outline_Get_Bitmap                                              */+  /*    FT_Outline_Render                                                  */+  /*                                                                       */+  /*    FT_Outline_Decompose                                               */+  /*    FT_Outline_Funcs                                                   */+  /*    FT_Outline_MoveTo_Func                                             */+  /*    FT_Outline_LineTo_Func                                             */+  /*    FT_Outline_ConicTo_Func                                            */+  /*    FT_Outline_CubicTo_Func                                            */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Decompose                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Walk over an outline's structure to decompose it into individual   */+  /*    segments and Bézier arcs.  This function also emits `move to'      */+  /*    operations to indicate the start of new contours in the outline.   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    outline        :: A pointer to the source target.                  */+  /*                                                                       */+  /*    func_interface :: A table of `emitters', i.e., function pointers   */+  /*                      called during decomposition to indicate path     */+  /*                      operations.                                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    user           :: A typeless pointer which is passed to each       */+  /*                      emitter during the decomposition.  It can be     */+  /*                      used to store the state during the               */+  /*                      decomposition.                                   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Decompose( FT_Outline*              outline,+                        const FT_Outline_Funcs*  func_interface,+                        void*                    user );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_New                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new outline of a given size.                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library     :: A handle to the library object from where the       */+  /*                   outline is allocated.  Note however that the new    */+  /*                   outline will *not* necessarily be *freed*, when     */+  /*                   destroying the library, by @FT_Done_FreeType.       */+  /*                                                                       */+  /*    numPoints   :: The maximal number of points within the outline.    */+  /*                                                                       */+  /*    numContours :: The maximal number of contours within the outline.  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    anoutline   :: A handle to the new outline.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The reason why this function takes a `library' parameter is simply */+  /*    to use the library's memory allocator.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_New( FT_Library   library,+                  FT_UInt      numPoints,+                  FT_Int       numContours,+                  FT_Outline  *anoutline );+++  FT_EXPORT( FT_Error )+  FT_Outline_New_Internal( FT_Memory    memory,+                           FT_UInt      numPoints,+                           FT_Int       numContours,+                           FT_Outline  *anoutline );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Done                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroy an outline created with @FT_Outline_New.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle of the library object used to allocate the     */+  /*               outline.                                                */+  /*                                                                       */+  /*    outline :: A pointer to the outline object to be discarded.        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If the outline's `owner' field is not set, only the outline        */+  /*    descriptor will be released.                                       */+  /*                                                                       */+  /*    The reason why this function takes an `library' parameter is       */+  /*    simply to use ft_mem_free().                                       */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Done( FT_Library   library,+                   FT_Outline*  outline );+++  FT_EXPORT( FT_Error )+  FT_Outline_Done_Internal( FT_Memory    memory,+                            FT_Outline*  outline );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Check                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Check the contents of an outline descriptor.                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    outline :: A handle to a source outline.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Check( FT_Outline*  outline );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Get_CBox                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return an outline's `control box'.  The control box encloses all   */+  /*    the outline's points, including Bézier control points.  Though it  */+  /*    coincides with the exact bounding box for most glyphs, it can be   */+  /*    slightly larger in some situations (like when rotating an outline  */+  /*    which contains Bézier outside arcs).                               */+  /*                                                                       */+  /*    Computing the control box is very fast, while getting the bounding */+  /*    box can take much more time as it needs to walk over all segments  */+  /*    and arcs in the outline.  To get the latter, you can use the       */+  /*    `ftbbox' component which is dedicated to this single task.         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    outline :: A pointer to the source outline descriptor.             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    acbox   :: The outline's control box.                              */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Outline_Get_CBox( const FT_Outline*  outline,+                       FT_BBox           *acbox );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Translate                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Apply a simple translation to the points of an outline.            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    outline :: A pointer to the target outline descriptor.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    xOffset :: The horizontal offset.                                  */+  /*                                                                       */+  /*    yOffset :: The vertical offset.                                    */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Outline_Translate( const FT_Outline*  outline,+                        FT_Pos             xOffset,+                        FT_Pos             yOffset );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Copy                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Copy an outline into another one.  Both objects must have the      */+  /*    same sizes (number of points & number of contours) when this       */+  /*    function is called.                                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    source :: A handle to the source outline.                          */+  /*                                                                       */+  /* <Output>                                                              */+  /*    target :: A handle to the target outline.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Copy( const FT_Outline*  source,+                   FT_Outline        *target );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Transform                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Apply a simple 2x2 matrix to all of an outline's points.  Useful   */+  /*    for applying rotations, slanting, flipping, etc.                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    outline :: A pointer to the target outline descriptor.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    matrix  :: A pointer to the transformation matrix.                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You can use @FT_Outline_Translate if you need to translate the     */+  /*    outline's points.                                                  */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Outline_Transform( const FT_Outline*  outline,+                        const FT_Matrix*   matrix );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Embolden                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Embolden an outline.  The new outline will be at most 4~times      */+  /*    `strength' pixels wider and higher.  You may think of the left and */+  /*    bottom borders as unchanged.                                       */+  /*                                                                       */+  /*    Negative `strength' values to reduce the outline thickness are     */+  /*    possible also.                                                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    outline  :: A handle to the target outline.                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    strength :: How strong the glyph is emboldened.  Expressed in      */+  /*                26.6 pixel format.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The used algorithm to increase or decrease the thickness of the    */+  /*    glyph doesn't change the number of points; this means that certain */+  /*    situations like acute angles or intersections are sometimes        */+  /*    handled incorrectly.                                               */+  /*                                                                       */+  /*    If you need `better' metrics values you should call                */+  /*    @FT_Outline_Get_CBox ot @FT_Outline_Get_BBox.                      */+  /*                                                                       */+  /*    Example call:                                                      */+  /*                                                                       */+  /*    {                                                                  */+  /*      FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );                   */+  /*      if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE )             */+  /*        FT_Outline_Embolden( &face->slot->outline, strength );         */+  /*    }                                                                  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Embolden( FT_Outline*  outline,+                       FT_Pos       strength );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Reverse                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Reverse the drawing direction of an outline.  This is used to      */+  /*    ensure consistent fill conventions for mirrored glyphs.            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    outline :: A pointer to the target outline descriptor.             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in     */+  /*    the outline's `flags' field.                                       */+  /*                                                                       */+  /*    It shouldn't be used by a normal client application, unless it     */+  /*    knows what it is doing.                                            */+  /*                                                                       */+  FT_EXPORT( void )+  FT_Outline_Reverse( FT_Outline*  outline );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Get_Bitmap                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Render an outline within a bitmap.  The outline's image is simply  */+  /*    OR-ed to the target bitmap.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to a FreeType library object.                  */+  /*                                                                       */+  /*    outline :: A pointer to the source outline descriptor.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    abitmap :: A pointer to the target bitmap descriptor.              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function does NOT CREATE the bitmap, it only renders an       */+  /*    outline image within the one you pass to it!  Consequently, the    */+  /*    various fields in `abitmap' should be set accordingly.             */+  /*                                                                       */+  /*    It will use the raster corresponding to the default glyph format.  */+  /*                                                                       */+  /*    The value of the `num_grays' field in `abitmap' is ignored.  If    */+  /*    you select the gray-level rasterizer, and you want less than 256   */+  /*    gray levels, you have to use @FT_Outline_Render directly.          */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Get_Bitmap( FT_Library        library,+                         FT_Outline*       outline,+                         const FT_Bitmap  *abitmap );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Render                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Render an outline within a bitmap using the current scan-convert.  */+  /*    This function uses an @FT_Raster_Params structure as an argument,  */+  /*    allowing advanced features like direct composition, translucency,  */+  /*    etc.                                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to a FreeType library object.                  */+  /*                                                                       */+  /*    outline :: A pointer to the source outline descriptor.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    params  :: A pointer to an @FT_Raster_Params structure used to     */+  /*               describe the rendering operation.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You should know what you are doing and how @FT_Raster_Params works */+  /*    to use this function.                                              */+  /*                                                                       */+  /*    The field `params.source' will be set to `outline' before the scan */+  /*    converter is called, which means that the value you give to it is  */+  /*    actually ignored.                                                  */+  /*                                                                       */+  /*    The gray-level rasterizer always uses 256 gray levels.  If you     */+  /*    want less gray levels, you have to provide your own span callback. */+  /*    See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the   */+  /*    @FT_Raster_Params structure for more details.                      */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Outline_Render( FT_Library         library,+                     FT_Outline*        outline,+                     FT_Raster_Params*  params );+++ /**************************************************************************+  *+  * @enum:+  *   FT_Orientation+  *+  * @description:+  *   A list of values used to describe an outline's contour orientation.+  *+  *   The TrueType and PostScript specifications use different conventions+  *   to determine whether outline contours should be filled or unfilled.+  *+  * @values:+  *   FT_ORIENTATION_TRUETYPE ::+  *     According to the TrueType specification, clockwise contours must+  *     be filled, and counter-clockwise ones must be unfilled.+  *+  *   FT_ORIENTATION_POSTSCRIPT ::+  *     According to the PostScript specification, counter-clockwise contours+  *     must be filled, and clockwise ones must be unfilled.+  *+  *   FT_ORIENTATION_FILL_RIGHT ::+  *     This is identical to @FT_ORIENTATION_TRUETYPE, but is used to+  *     remember that in TrueType, everything that is to the right of+  *     the drawing direction of a contour must be filled.+  *+  *   FT_ORIENTATION_FILL_LEFT ::+  *     This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to+  *     remember that in PostScript, everything that is to the left of+  *     the drawing direction of a contour must be filled.+  *+  *   FT_ORIENTATION_NONE ::+  *     The orientation cannot be determined.  That is, different parts of+  *     the glyph have different orientation.+  *+  */+  typedef enum  FT_Orientation_+  {+    FT_ORIENTATION_TRUETYPE   = 0,+    FT_ORIENTATION_POSTSCRIPT = 1,+    FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE,+    FT_ORIENTATION_FILL_LEFT  = FT_ORIENTATION_POSTSCRIPT,+    FT_ORIENTATION_NONE++  } FT_Orientation;+++ /**************************************************************************+  *+  * @function:+  *   FT_Outline_Get_Orientation+  *+  * @description:+  *   This function analyzes a glyph outline and tries to compute its+  *   fill orientation (see @FT_Orientation).  This is done by computing+  *   the direction of each global horizontal and/or vertical extrema+  *   within the outline.+  *+  *   Note that this will return @FT_ORIENTATION_TRUETYPE for empty+  *   outlines.+  *+  * @input:+  *   outline ::+  *     A handle to the source outline.+  *+  * @return:+  *   The orientation.+  *+  */+  FT_EXPORT( FT_Orientation )+  FT_Outline_Get_Orientation( FT_Outline*  outline );+++  /* */+++FT_END_HEADER++#endif /* __FTOUTLN_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftpfr.h view
@@ -0,0 +1,172 @@+/***************************************************************************/+/*                                                                         */+/*  ftpfr.h                                                                */+/*                                                                         */+/*    FreeType API for accessing PFR-specific data (specification only).   */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006, 2008, 2009 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTPFR_H__+#define __FTPFR_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    pfr_fonts                                                          */+  /*                                                                       */+  /* <Title>                                                               */+  /*    PFR Fonts                                                          */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    PFR/TrueDoc specific API.                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of PFR-specific functions.   */+  /*                                                                       */+  /*************************************************************************/+++ /**********************************************************************+  *+  * @function:+  *    FT_Get_PFR_Metrics+  *+  * @description:+  *    Return the outline and metrics resolutions of a given PFR face.+  *+  * @input:+  *    face :: Handle to the input face.  It can be a non-PFR face.+  *+  * @output:+  *    aoutline_resolution ::+  *      Outline resolution.  This is equivalent to `face->units_per_EM'+  *      for non-PFR fonts.  Optional (parameter can be NULL).+  *+  *    ametrics_resolution ::+  *      Metrics resolution.  This is equivalent to `outline_resolution'+  *      for non-PFR fonts.  Optional (parameter can be NULL).+  *+  *    ametrics_x_scale ::+  *      A 16.16 fixed-point number used to scale distance expressed+  *      in metrics units to device sub-pixels.  This is equivalent to+  *      `face->size->x_scale', but for metrics only.  Optional (parameter+  *      can be NULL).+  *+  *    ametrics_y_scale ::+  *      Same as `ametrics_x_scale' but for the vertical direction.+  *      optional (parameter can be NULL).+  *+  * @return:+  *    FreeType error code.  0~means success.+  *+  * @note:+  *   If the input face is not a PFR, this function will return an error.+  *   However, in all cases, it will return valid values.+  */+  FT_EXPORT( FT_Error )+  FT_Get_PFR_Metrics( FT_Face    face,+                      FT_UInt   *aoutline_resolution,+                      FT_UInt   *ametrics_resolution,+                      FT_Fixed  *ametrics_x_scale,+                      FT_Fixed  *ametrics_y_scale );+++ /**********************************************************************+  *+  * @function:+  *    FT_Get_PFR_Kerning+  *+  * @description:+  *    Return the kerning pair corresponding to two glyphs in a PFR face.+  *    The distance is expressed in metrics units, unlike the result of+  *    @FT_Get_Kerning.+  *+  * @input:+  *    face  :: A handle to the input face.+  *+  *    left  :: Index of the left glyph.+  *+  *    right :: Index of the right glyph.+  *+  * @output:+  *    avector :: A kerning vector.+  *+  * @return:+  *    FreeType error code.  0~means success.+  *+  * @note:+  *    This function always return distances in original PFR metrics+  *    units.  This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED+  *    mode, which always returns distances converted to outline units.+  *+  *    You can use the value of the `x_scale' and `y_scale' parameters+  *    returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels.+  */+  FT_EXPORT( FT_Error )+  FT_Get_PFR_Kerning( FT_Face     face,+                      FT_UInt     left,+                      FT_UInt     right,+                      FT_Vector  *avector );+++ /**********************************************************************+  *+  * @function:+  *    FT_Get_PFR_Advance+  *+  * @description:+  *    Return a given glyph advance, expressed in original metrics units,+  *    from a PFR font.+  *+  * @input:+  *    face   :: A handle to the input face.+  *+  *    gindex :: The glyph index.+  *+  * @output:+  *    aadvance :: The glyph advance in metrics units.+  *+  * @return:+  *    FreeType error code.  0~means success.+  *+  * @note:+  *    You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics+  *    to convert the advance to device sub-pixels (i.e., 1/64th of pixels).+  */+  FT_EXPORT( FT_Error )+  FT_Get_PFR_Advance( FT_Face   face,+                      FT_UInt   gindex,+                      FT_Pos   *aadvance );++ /* */+++FT_END_HEADER++#endif /* __FTPFR_H__ */+++/* END */
+ include/freetype/ftrender.h view
@@ -0,0 +1,230 @@+/***************************************************************************/+/*                                                                         */+/*  ftrender.h                                                             */+/*                                                                         */+/*    FreeType renderer modules public interface (specification).          */+/*                                                                         */+/*  Copyright 1996-2001, 2005, 2006, 2010 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTRENDER_H__+#define __FTRENDER_H__+++#include <ft2build.h>+#include FT_MODULE_H+#include FT_GLYPH_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    module_management                                                  */+  /*                                                                       */+  /*************************************************************************/+++  /* create a new glyph object */+  typedef FT_Error+  (*FT_Glyph_InitFunc)( FT_Glyph      glyph,+                        FT_GlyphSlot  slot );++  /* destroys a given glyph object */+  typedef void+  (*FT_Glyph_DoneFunc)( FT_Glyph  glyph );++  typedef void+  (*FT_Glyph_TransformFunc)( FT_Glyph          glyph,+                             const FT_Matrix*  matrix,+                             const FT_Vector*  delta );++  typedef void+  (*FT_Glyph_GetBBoxFunc)( FT_Glyph  glyph,+                           FT_BBox*  abbox );++  typedef FT_Error+  (*FT_Glyph_CopyFunc)( FT_Glyph   source,+                        FT_Glyph   target );++  typedef FT_Error+  (*FT_Glyph_PrepareFunc)( FT_Glyph      glyph,+                           FT_GlyphSlot  slot );++/* deprecated */+#define FT_Glyph_Init_Func       FT_Glyph_InitFunc+#define FT_Glyph_Done_Func       FT_Glyph_DoneFunc+#define FT_Glyph_Transform_Func  FT_Glyph_TransformFunc+#define FT_Glyph_BBox_Func       FT_Glyph_GetBBoxFunc+#define FT_Glyph_Copy_Func       FT_Glyph_CopyFunc+#define FT_Glyph_Prepare_Func    FT_Glyph_PrepareFunc+++  struct  FT_Glyph_Class_+  {+    FT_Long                 glyph_size;+    FT_Glyph_Format         glyph_format;+    FT_Glyph_InitFunc       glyph_init;+    FT_Glyph_DoneFunc       glyph_done;+    FT_Glyph_CopyFunc       glyph_copy;+    FT_Glyph_TransformFunc  glyph_transform;+    FT_Glyph_GetBBoxFunc    glyph_bbox;+    FT_Glyph_PrepareFunc    glyph_prepare;+  };+++  typedef FT_Error+  (*FT_Renderer_RenderFunc)( FT_Renderer       renderer,+                             FT_GlyphSlot      slot,+                             FT_UInt           mode,+                             const FT_Vector*  origin );++  typedef FT_Error+  (*FT_Renderer_TransformFunc)( FT_Renderer       renderer,+                                FT_GlyphSlot      slot,+                                const FT_Matrix*  matrix,+                                const FT_Vector*  delta );+++  typedef void+  (*FT_Renderer_GetCBoxFunc)( FT_Renderer   renderer,+                              FT_GlyphSlot  slot,+                              FT_BBox*      cbox );+++  typedef FT_Error+  (*FT_Renderer_SetModeFunc)( FT_Renderer  renderer,+                              FT_ULong     mode_tag,+                              FT_Pointer   mode_ptr );++/* deprecated identifiers */+#define FTRenderer_render  FT_Renderer_RenderFunc+#define FTRenderer_transform  FT_Renderer_TransformFunc+#define FTRenderer_getCBox  FT_Renderer_GetCBoxFunc+#define FTRenderer_setMode  FT_Renderer_SetModeFunc+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Renderer_Class                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The renderer module class descriptor.                              */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root            :: The root @FT_Module_Class fields.               */+  /*                                                                       */+  /*    glyph_format    :: The glyph image format this renderer handles.   */+  /*                                                                       */+  /*    render_glyph    :: A method used to render the image that is in a  */+  /*                       given glyph slot into a bitmap.                 */+  /*                                                                       */+  /*    transform_glyph :: A method used to transform the image that is in */+  /*                       a given glyph slot.                             */+  /*                                                                       */+  /*    get_glyph_cbox  :: A method used to access the glyph's cbox.       */+  /*                                                                       */+  /*    set_mode        :: A method used to pass additional parameters.    */+  /*                                                                       */+  /*    raster_class    :: For @FT_GLYPH_FORMAT_OUTLINE renderers only.    */+  /*                       This is a pointer to its raster's class.        */+  /*                                                                       */+  typedef struct  FT_Renderer_Class_+  {+    FT_Module_Class            root;++    FT_Glyph_Format            glyph_format;++    FT_Renderer_RenderFunc     render_glyph;+    FT_Renderer_TransformFunc  transform_glyph;+    FT_Renderer_GetCBoxFunc    get_glyph_cbox;+    FT_Renderer_SetModeFunc    set_mode;++    FT_Raster_Funcs*           raster_class;++  } FT_Renderer_Class;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Renderer                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the current renderer for a given glyph format.            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library :: A handle to the library object.                         */+  /*                                                                       */+  /*    format  :: The glyph format.                                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A renderer handle.  0~if none found.                               */+  /*                                                                       */+  /* <Note>                                                                */+  /*    An error will be returned if a module already exists by that name, */+  /*    or if the module requires a version of FreeType that is too great. */+  /*                                                                       */+  /*    To add a new renderer, simply use @FT_Add_Module.  To retrieve a   */+  /*    renderer by its name, use @FT_Get_Module.                          */+  /*                                                                       */+  FT_EXPORT( FT_Renderer )+  FT_Get_Renderer( FT_Library       library,+                   FT_Glyph_Format  format );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Set_Renderer                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Set the current renderer to use, and set additional mode.          */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    library    :: A handle to the library object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    renderer   :: A handle to the renderer object.                     */+  /*                                                                       */+  /*    num_params :: The number of additional parameters.                 */+  /*                                                                       */+  /*    parameters :: Additional parameters.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    In case of success, the renderer will be used to convert glyph     */+  /*    images in the renderer's known format into bitmaps.                */+  /*                                                                       */+  /*    This doesn't change the current renderer for other formats.        */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Set_Renderer( FT_Library     library,+                   FT_Renderer    renderer,+                   FT_UInt        num_params,+                   FT_Parameter*  parameters );+++  /* */+++FT_END_HEADER++#endif /* __FTRENDER_H__ */+++/* END */
+ include/freetype/ftsizes.h view
@@ -0,0 +1,159 @@+/***************************************************************************/+/*                                                                         */+/*  ftsizes.h                                                              */+/*                                                                         */+/*    FreeType size objects management (specification).                    */+/*                                                                         */+/*  Copyright 1996-2001, 2003, 2004, 2006, 2009 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Typical application would normally not need to use these functions.   */+  /* However, they have been placed in a public API for the rare cases     */+  /* where they are needed.                                                */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTSIZES_H__+#define __FTSIZES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    sizes_management                                                   */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Size Management                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Managing multiple sizes per face.                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    When creating a new face object (e.g., with @FT_New_Face), an      */+  /*    @FT_Size object is automatically created and used to store all     */+  /*    pixel-size dependent information, available in the `face->size'    */+  /*    field.                                                             */+  /*                                                                       */+  /*    It is however possible to create more sizes for a given face,      */+  /*    mostly in order to manage several character pixel sizes of the     */+  /*    same font family and style.  See @FT_New_Size and @FT_Done_Size.   */+  /*                                                                       */+  /*    Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only           */+  /*    modify the contents of the current `active' size; you thus need    */+  /*    to use @FT_Activate_Size to change it.                             */+  /*                                                                       */+  /*    99% of applications won't need the functions provided here,        */+  /*    especially if they use the caching sub-system, so be cautious      */+  /*    when using these.                                                  */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Size                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new size object from a given face object.                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to a parent face object.                          */+  /*                                                                       */+  /* <Output>                                                              */+  /*    asize :: A handle to a new size object.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You need to call @FT_Activate_Size in order to select the new size */+  /*    for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size,      */+  /*    @FT_Load_Glyph, @FT_Load_Char, etc.                                */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_New_Size( FT_Face   face,+               FT_Size*  size );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_Size                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Discard a given size object.  Note that @FT_Done_Face              */+  /*    automatically discards all size objects allocated with             */+  /*    @FT_New_Size.                                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to a target size object.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Done_Size( FT_Size  size );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Activate_Size                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Even though it is possible to create several size objects for a    */+  /*    given face (see @FT_New_Size for details), functions like          */+  /*    @FT_Load_Glyph or @FT_Load_Char only use the one which has been    */+  /*    activated last to determine the `current character pixel size'.    */+  /*                                                                       */+  /*    This function can be used to `activate' a previously created size  */+  /*    object.                                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to a target size object.                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    If `face' is the size's parent face object, this function changes  */+  /*    the value of `face->size' to the input size handle.                */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Activate_Size( FT_Size  size );++  /* */+++FT_END_HEADER++#endif /* __FTSIZES_H__ */+++/* END */
+ include/freetype/ftsnames.h view
@@ -0,0 +1,200 @@+/***************************************************************************/+/*                                                                         */+/*  ftsnames.h                                                             */+/*                                                                         */+/*    Simple interface to access SFNT name tables (which are used          */+/*    to hold font names, copyright info, notices, etc.) (specification).  */+/*                                                                         */+/*    This is _not_ used to retrieve glyph names!                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FT_SFNT_NAMES_H__+#define __FT_SFNT_NAMES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    sfnt_names                                                         */+  /*                                                                       */+  /* <Title>                                                               */+  /*    SFNT Names                                                         */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Access the names embedded in TrueType and OpenType files.          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The TrueType and OpenType specifications allow the inclusion of    */+  /*    a special `names table' in font files.  This table contains        */+  /*    textual (and internationalized) information regarding the font,    */+  /*    like family name, copyright, version, etc.                         */+  /*                                                                       */+  /*    The definitions below are used to access them if available.        */+  /*                                                                       */+  /*    Note that this has nothing to do with glyph names!                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_SfntName                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model an SFNT `name' table entry.              */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    platform_id :: The platform ID for `string'.                       */+  /*                                                                       */+  /*    encoding_id :: The encoding ID for `string'.                       */+  /*                                                                       */+  /*    language_id :: The language ID for `string'.                       */+  /*                                                                       */+  /*    name_id     :: An identifier for `string'.                         */+  /*                                                                       */+  /*    string      :: The `name' string.  Note that its format differs    */+  /*                   depending on the (platform,encoding) pair.  It can  */+  /*                   be a Pascal String, a UTF-16 one, etc.              */+  /*                                                                       */+  /*                   Generally speaking, the string is not               */+  /*                   zero-terminated.  Please refer to the TrueType      */+  /*                   specification for details.                          */+  /*                                                                       */+  /*    string_len  :: The length of `string' in bytes.                    */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Possible values for `platform_id', `encoding_id', `language_id',   */+  /*    and `name_id' are given in the file `ttnameid.h'.  For details     */+  /*    please refer to the TrueType or OpenType specification.            */+  /*                                                                       */+  /*    See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,       */+  /*    @TT_ISO_ID_XXX, and @TT_MS_ID_XXX.                                 */+  /*                                                                       */+  typedef struct  FT_SfntName_+  {+    FT_UShort  platform_id;+    FT_UShort  encoding_id;+    FT_UShort  language_id;+    FT_UShort  name_id;++    FT_Byte*   string;      /* this string is *not* null-terminated! */+    FT_UInt    string_len;  /* in bytes */++  } FT_SfntName;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Sfnt_Name_Count                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve the number of name strings in the SFNT `name' table.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source face.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The number of strings in the `name' table.                         */+  /*                                                                       */+  FT_EXPORT( FT_UInt )+  FT_Get_Sfnt_Name_Count( FT_Face  face );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Sfnt_Name                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieve a string of the SFNT `name' table for a given index.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face  :: A handle to the source face.                              */+  /*                                                                       */+  /*    idx   :: The index of the `name' string.                           */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aname :: The indexed @FT_SfntName structure.                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0~means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The `string' array returned in the `aname' structure is not        */+  /*    null-terminated.  The application should deallocate it if it is no */+  /*    longer in use.                                                     */+  /*                                                                       */+  /*    Use @FT_Get_Sfnt_Name_Count to get the total number of available   */+  /*    `name' table entries, then do a loop until you get the right       */+  /*    platform, encoding, and name ID.                                   */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  FT_Get_Sfnt_Name( FT_Face       face,+                    FT_UInt       idx,+                    FT_SfntName  *aname );+++  /***************************************************************************+   *+   * @constant:+   *   FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY+   *+   * @description:+   *   A constant used as the tag of @FT_Parameter structures to make+   *   FT_Open_Face() ignore preferred family subfamily names in `name'+   *   table since OpenType version 1.4.  For backwards compatibility with+   *   legacy systems which has 4-face-per-family restriction.+   *+   */+#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 'f' )+++  /***************************************************************************+   *+   * @constant:+   *   FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY+   *+   * @description:+   *   A constant used as the tag of @FT_Parameter structures to make+   *   FT_Open_Face() ignore preferred subfamily names in `name' table since+   *   OpenType version 1.4.  For backwards compatibility with legacy+   *   systems which has 4-face-per-family restriction.+   *+   */+#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 's' )++  /* */+++FT_END_HEADER++#endif /* __FT_SFNT_NAMES_H__ */+++/* END */
+ include/freetype/ftstroke.h view
@@ -0,0 +1,716 @@+/***************************************************************************/+/*                                                                         */+/*  ftstroke.h                                                             */+/*                                                                         */+/*    FreeType path stroker (specification).                               */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FT_STROKE_H__+#define __FT_STROKE_H__++#include <ft2build.h>+#include FT_OUTLINE_H+#include FT_GLYPH_H+++FT_BEGIN_HEADER+++ /************************************************************************+  *+  * @section:+  *    glyph_stroker+  *+  * @title:+  *    Glyph Stroker+  *+  * @abstract:+  *    Generating bordered and stroked glyphs.+  *+  * @description:+  *    This component generates stroked outlines of a given vectorial+  *    glyph.  It also allows you to retrieve the `outside' and/or the+  *    `inside' borders of the stroke.+  *+  *    This can be useful to generate `bordered' glyph, i.e., glyphs+  *    displayed with a coloured (and anti-aliased) border around their+  *    shape.+  */+++ /**************************************************************+  *+  * @type:+  *   FT_Stroker+  *+  * @description:+  *   Opaque handler to a path stroker object.+  */+  typedef struct FT_StrokerRec_*  FT_Stroker;+++  /**************************************************************+   *+   * @enum:+   *   FT_Stroker_LineJoin+   *+   * @description:+   *   These values determine how two joining lines are rendered+   *   in a stroker.+   *+   * @values:+   *   FT_STROKER_LINEJOIN_ROUND ::+   *     Used to render rounded line joins.  Circular arcs are used+   *     to join two lines smoothly.+   *+   *   FT_STROKER_LINEJOIN_BEVEL ::+   *     Used to render beveled line joins; i.e., the two joining lines+   *     are extended until they intersect.+   *+   *   FT_STROKER_LINEJOIN_MITER ::+   *     Same as beveled rendering, except that an additional line+   *     break is added if the angle between the two joining lines+   *     is too closed (this is useful to avoid unpleasant spikes+   *     in beveled rendering).+   */+  typedef enum  FT_Stroker_LineJoin_+  {+    FT_STROKER_LINEJOIN_ROUND = 0,+    FT_STROKER_LINEJOIN_BEVEL,+    FT_STROKER_LINEJOIN_MITER++  } FT_Stroker_LineJoin;+++  /**************************************************************+   *+   * @enum:+   *   FT_Stroker_LineCap+   *+   * @description:+   *   These values determine how the end of opened sub-paths are+   *   rendered in a stroke.+   *+   * @values:+   *   FT_STROKER_LINECAP_BUTT ::+   *     The end of lines is rendered as a full stop on the last+   *     point itself.+   *+   *   FT_STROKER_LINECAP_ROUND ::+   *     The end of lines is rendered as a half-circle around the+   *     last point.+   *+   *   FT_STROKER_LINECAP_SQUARE ::+   *     The end of lines is rendered as a square around the+   *     last point.+   */+  typedef enum  FT_Stroker_LineCap_+  {+    FT_STROKER_LINECAP_BUTT = 0,+    FT_STROKER_LINECAP_ROUND,+    FT_STROKER_LINECAP_SQUARE++  } FT_Stroker_LineCap;+++  /**************************************************************+   *+   * @enum:+   *   FT_StrokerBorder+   *+   * @description:+   *   These values are used to select a given stroke border+   *   in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder.+   *+   * @values:+   *   FT_STROKER_BORDER_LEFT ::+   *     Select the left border, relative to the drawing direction.+   *+   *   FT_STROKER_BORDER_RIGHT ::+   *     Select the right border, relative to the drawing direction.+   *+   * @note:+   *   Applications are generally interested in the `inside' and `outside'+   *   borders.  However, there is no direct mapping between these and the+   *   `left' and `right' ones, since this really depends on the glyph's+   *   drawing orientation, which varies between font formats.+   *+   *   You can however use @FT_Outline_GetInsideBorder and+   *   @FT_Outline_GetOutsideBorder to get these.+   */+  typedef enum  FT_StrokerBorder_+  {+    FT_STROKER_BORDER_LEFT = 0,+    FT_STROKER_BORDER_RIGHT++  } FT_StrokerBorder;+++  /**************************************************************+   *+   * @function:+   *   FT_Outline_GetInsideBorder+   *+   * @description:+   *   Retrieve the @FT_StrokerBorder value corresponding to the+   *   `inside' borders of a given outline.+   *+   * @input:+   *   outline ::+   *     The source outline handle.+   *+   * @return:+   *   The border index.  @FT_STROKER_BORDER_RIGHT for empty or invalid+   *   outlines.+   */+  FT_EXPORT( FT_StrokerBorder )+  FT_Outline_GetInsideBorder( FT_Outline*  outline );+++  /**************************************************************+   *+   * @function:+   *   FT_Outline_GetOutsideBorder+   *+   * @description:+   *   Retrieve the @FT_StrokerBorder value corresponding to the+   *   `outside' borders of a given outline.+   *+   * @input:+   *   outline ::+   *     The source outline handle.+   *+   * @return:+   *   The border index.  @FT_STROKER_BORDER_LEFT for empty or invalid+   *   outlines.+   */+  FT_EXPORT( FT_StrokerBorder )+  FT_Outline_GetOutsideBorder( FT_Outline*  outline );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_New+   *+   * @description:+   *   Create a new stroker object.+   *+   * @input:+   *   library ::+   *     FreeType library handle.+   *+   * @output:+   *   astroker ::+   *     A new stroker object handle.  NULL in case of error.+   *+   * @return:+   *    FreeType error code.  0~means success.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_New( FT_Library   library,+                  FT_Stroker  *astroker );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_Set+   *+   * @description:+   *   Reset a stroker object's attributes.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   radius ::+   *     The border radius.+   *+   *   line_cap ::+   *     The line cap style.+   *+   *   line_join ::+   *     The line join style.+   *+   *   miter_limit ::+   *     The miter limit for the FT_STROKER_LINEJOIN_MITER style,+   *     expressed as 16.16 fixed point value.+   *+   * @note:+   *   The radius is expressed in the same units as the outline+   *   coordinates.+   */+  FT_EXPORT( void )+  FT_Stroker_Set( FT_Stroker           stroker,+                  FT_Fixed             radius,+                  FT_Stroker_LineCap   line_cap,+                  FT_Stroker_LineJoin  line_join,+                  FT_Fixed             miter_limit );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_Rewind+   *+   * @description:+   *   Reset a stroker object without changing its attributes.+   *   You should call this function before beginning a new+   *   series of calls to @FT_Stroker_BeginSubPath or+   *   @FT_Stroker_EndSubPath.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   */+  FT_EXPORT( void )+  FT_Stroker_Rewind( FT_Stroker  stroker );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_ParseOutline+   *+   * @description:+   *   A convenience function used to parse a whole outline with+   *   the stroker.  The resulting outline(s) can be retrieved+   *   later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   outline ::+   *     The source outline.+   *+   *   opened ::+   *     A boolean.  If~1, the outline is treated as an open path instead+   *     of a closed one.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   If `opened' is~0 (the default), the outline is treated as a closed+   *   path, and the stroker generates two distinct `border' outlines.+   *+   *   If `opened' is~1, the outline is processed as an open path, and the+   *   stroker generates a single `stroke' outline.+   *+   *   This function calls @FT_Stroker_Rewind automatically.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_ParseOutline( FT_Stroker   stroker,+                           FT_Outline*  outline,+                           FT_Bool      opened );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_BeginSubPath+   *+   * @description:+   *   Start a new sub-path in the stroker.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   to ::+   *     A pointer to the start vector.+   *+   *   open ::+   *     A boolean.  If~1, the sub-path is treated as an open one.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   This function is useful when you need to stroke a path that is+   *   not stored as an @FT_Outline object.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_BeginSubPath( FT_Stroker  stroker,+                           FT_Vector*  to,+                           FT_Bool     open );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_EndSubPath+   *+   * @description:+   *   Close the current sub-path in the stroker.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   You should call this function after @FT_Stroker_BeginSubPath.+   *   If the subpath was not `opened', this function `draws' a+   *   single line segment to the start position when needed.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_EndSubPath( FT_Stroker  stroker );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_LineTo+   *+   * @description:+   *   `Draw' a single line segment in the stroker's current sub-path,+   *   from the last position.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   to ::+   *     A pointer to the destination point.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   You should call this function between @FT_Stroker_BeginSubPath and+   *   @FT_Stroker_EndSubPath.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_LineTo( FT_Stroker  stroker,+                     FT_Vector*  to );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_ConicTo+   *+   * @description:+   *   `Draw' a single quadratic Bézier in the stroker's current sub-path,+   *   from the last position.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   control ::+   *     A pointer to a Bézier control point.+   *+   *   to ::+   *     A pointer to the destination point.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   You should call this function between @FT_Stroker_BeginSubPath and+   *   @FT_Stroker_EndSubPath.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_ConicTo( FT_Stroker  stroker,+                      FT_Vector*  control,+                      FT_Vector*  to );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_CubicTo+   *+   * @description:+   *   `Draw' a single cubic Bézier in the stroker's current sub-path,+   *   from the last position.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   control1 ::+   *     A pointer to the first Bézier control point.+   *+   *   control2 ::+   *     A pointer to second Bézier control point.+   *+   *   to ::+   *     A pointer to the destination point.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   You should call this function between @FT_Stroker_BeginSubPath and+   *   @FT_Stroker_EndSubPath.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_CubicTo( FT_Stroker  stroker,+                      FT_Vector*  control1,+                      FT_Vector*  control2,+                      FT_Vector*  to );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_GetBorderCounts+   *+   * @description:+   *   Call this function once you have finished parsing your paths+   *   with the stroker.  It returns the number of points and+   *   contours necessary to export one of the `border' or `stroke'+   *   outlines generated by the stroker.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   border ::+   *     The border index.+   *+   * @output:+   *   anum_points ::+   *     The number of points.+   *+   *   anum_contours ::+   *     The number of contours.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   When an outline, or a sub-path, is `closed', the stroker generates+   *   two independent `border' outlines, named `left' and `right'.+   *+   *   When the outline, or a sub-path, is `opened', the stroker merges+   *   the `border' outlines with caps.  The `left' border receives all+   *   points, while the `right' border becomes empty.+   *+   *   Use the function @FT_Stroker_GetCounts instead if you want to+   *   retrieve the counts associated to both borders.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_GetBorderCounts( FT_Stroker        stroker,+                              FT_StrokerBorder  border,+                              FT_UInt          *anum_points,+                              FT_UInt          *anum_contours );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_ExportBorder+   *+   * @description:+   *   Call this function after @FT_Stroker_GetBorderCounts to+   *   export the corresponding border to your own @FT_Outline+   *   structure.+   *+   *   Note that this function appends the border points and+   *   contours to your outline, but does not try to resize its+   *   arrays.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   border ::+   *     The border index.+   *+   *   outline ::+   *     The target outline handle.+   *+   * @note:+   *   Always call this function after @FT_Stroker_GetBorderCounts to+   *   get sure that there is enough room in your @FT_Outline object to+   *   receive all new data.+   *+   *   When an outline, or a sub-path, is `closed', the stroker generates+   *   two independent `border' outlines, named `left' and `right'+   *+   *   When the outline, or a sub-path, is `opened', the stroker merges+   *   the `border' outlines with caps. The `left' border receives all+   *   points, while the `right' border becomes empty.+   *+   *   Use the function @FT_Stroker_Export instead if you want to+   *   retrieve all borders at once.+   */+  FT_EXPORT( void )+  FT_Stroker_ExportBorder( FT_Stroker        stroker,+                           FT_StrokerBorder  border,+                           FT_Outline*       outline );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_GetCounts+   *+   * @description:+   *   Call this function once you have finished parsing your paths+   *   with the stroker.  It returns the number of points and+   *   contours necessary to export all points/borders from the stroked+   *   outline/path.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   * @output:+   *   anum_points ::+   *     The number of points.+   *+   *   anum_contours ::+   *     The number of contours.+   *+   * @return:+   *   FreeType error code.  0~means success.+   */+  FT_EXPORT( FT_Error )+  FT_Stroker_GetCounts( FT_Stroker  stroker,+                        FT_UInt    *anum_points,+                        FT_UInt    *anum_contours );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_Export+   *+   * @description:+   *   Call this function after @FT_Stroker_GetBorderCounts to+   *   export all borders to your own @FT_Outline structure.+   *+   *   Note that this function appends the border points and+   *   contours to your outline, but does not try to resize its+   *   arrays.+   *+   * @input:+   *   stroker ::+   *     The target stroker handle.+   *+   *   outline ::+   *     The target outline handle.+   */+  FT_EXPORT( void )+  FT_Stroker_Export( FT_Stroker   stroker,+                     FT_Outline*  outline );+++  /**************************************************************+   *+   * @function:+   *   FT_Stroker_Done+   *+   * @description:+   *   Destroy a stroker object.+   *+   * @input:+   *   stroker ::+   *     A stroker handle.  Can be NULL.+   */+  FT_EXPORT( void )+  FT_Stroker_Done( FT_Stroker  stroker );+++  /**************************************************************+   *+   * @function:+   *   FT_Glyph_Stroke+   *+   * @description:+   *   Stroke a given outline glyph object with a given stroker.+   *+   * @inout:+   *   pglyph ::+   *     Source glyph handle on input, new glyph handle on output.+   *+   * @input:+   *   stroker ::+   *     A stroker handle.+   *+   *   destroy ::+   *     A Boolean.  If~1, the source glyph object is destroyed+   *     on success.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *   The source glyph is untouched in case of error.+   */+  FT_EXPORT( FT_Error )+  FT_Glyph_Stroke( FT_Glyph    *pglyph,+                   FT_Stroker   stroker,+                   FT_Bool      destroy );+++  /**************************************************************+   *+   * @function:+   *   FT_Glyph_StrokeBorder+   *+   * @description:+   *   Stroke a given outline glyph object with a given stroker, but+   *   only return either its inside or outside border.+   *+   * @inout:+   *   pglyph ::+   *     Source glyph handle on input, new glyph handle on output.+   *+   * @input:+   *   stroker ::+   *     A stroker handle.+   *+   *   inside ::+   *     A Boolean.  If~1, return the inside border, otherwise+   *     the outside border.+   *+   *   destroy ::+   *     A Boolean.  If~1, the source glyph object is destroyed+   *     on success.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *   The source glyph is untouched in case of error.+   */+  FT_EXPORT( FT_Error )+  FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,+                         FT_Stroker   stroker,+                         FT_Bool      inside,+                         FT_Bool      destroy );++ /* */++FT_END_HEADER++#endif /* __FT_STROKE_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftsynth.h view
@@ -0,0 +1,80 @@+/***************************************************************************/+/*                                                                         */+/*  ftsynth.h                                                              */+/*                                                                         */+/*    FreeType synthesizing code for emboldening and slanting              */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2006, 2008 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*********                                                       *********/+  /*********        WARNING, THIS IS ALPHA CODE!  THIS API         *********/+  /*********    IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE    *********/+  /*********            FREETYPE DEVELOPMENT TEAM                  *********/+  /*********                                                       *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* Main reason for not lifting the functions in this module to a  */+  /* `standard' API is that the used parameters for emboldening and */+  /* slanting are not configurable.  Consider the functions as a    */+  /* code resource which should be copied into the application and  */+  /* adapted to the particular needs.                               */+++#ifndef __FTSYNTH_H__+#define __FTSYNTH_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /* Embolden a glyph by a `reasonable' value (which is highly a matter of */+  /* taste).  This function is actually a convenience function, providing  */+  /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden.           */+  /*                                                                       */+  /* For emboldened outlines the metrics are estimates only; if you need   */+  /* precise values you should call @FT_Outline_Get_CBox.                  */+  FT_EXPORT( void )+  FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );++  /* Slant an outline glyph to the right by about 12 degrees. */+  FT_EXPORT( void )+  FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );++  /* */++FT_END_HEADER++#endif /* __FTSYNTH_H__ */+++/* END */
+ include/freetype/ftsystem.h view
@@ -0,0 +1,347 @@+/***************************************************************************/+/*                                                                         */+/*  ftsystem.h                                                             */+/*                                                                         */+/*    FreeType low-level system interface definition (specification).      */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2005, 2010 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTSYSTEM_H__+#define __FTSYSTEM_H__+++#include <ft2build.h>+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*   system_interface                                                    */+  /*                                                                       */+  /* <Title>                                                               */+  /*   System Interface                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*   How FreeType manages memory and i/o.                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*   This section contains various definitions related to memory         */+  /*   management and i/o access.  You need to understand this             */+  /*   information if you want to use a custom memory manager or you own   */+  /*   i/o streams.                                                        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /*                  M E M O R Y   M A N A G E M E N T                    */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************+   *+   * @type:+   *   FT_Memory+   *+   * @description:+   *   A handle to a given memory manager object, defined with an+   *   @FT_MemoryRec structure.+   *+   */+  typedef struct FT_MemoryRec_*  FT_Memory;+++  /*************************************************************************+   *+   * @functype:+   *   FT_Alloc_Func+   *+   * @description:+   *   A function used to allocate `size' bytes from `memory'.+   *+   * @input:+   *   memory ::+   *     A handle to the source memory manager.+   *+   *   size ::+   *     The size in bytes to allocate.+   *+   * @return:+   *   Address of new memory block.  0~in case of failure.+   *+   */+  typedef void*+  (*FT_Alloc_Func)( FT_Memory  memory,+                    long       size );+++  /*************************************************************************+   *+   * @functype:+   *   FT_Free_Func+   *+   * @description:+   *   A function used to release a given block of memory.+   *+   * @input:+   *   memory ::+   *     A handle to the source memory manager.+   *+   *   block ::+   *     The address of the target memory block.+   *+   */+  typedef void+  (*FT_Free_Func)( FT_Memory  memory,+                   void*      block );+++  /*************************************************************************+   *+   * @functype:+   *   FT_Realloc_Func+   *+   * @description:+   *   A function used to re-allocate a given block of memory.+   *+   * @input:+   *   memory ::+   *     A handle to the source memory manager.+   *+   *   cur_size ::+   *     The block's current size in bytes.+   *+   *   new_size ::+   *     The block's requested new size.+   *+   *   block ::+   *     The block's current address.+   *+   * @return:+   *   New block address.  0~in case of memory shortage.+   *+   * @note:+   *   In case of error, the old block must still be available.+   *+   */+  typedef void*+  (*FT_Realloc_Func)( FT_Memory  memory,+                      long       cur_size,+                      long       new_size,+                      void*      block );+++  /*************************************************************************+   *+   * @struct:+   *   FT_MemoryRec+   *+   * @description:+   *   A structure used to describe a given memory manager to FreeType~2.+   *+   * @fields:+   *   user ::+   *     A generic typeless pointer for user data.+   *+   *   alloc ::+   *     A pointer type to an allocation function.+   *+   *   free ::+   *     A pointer type to an memory freeing function.+   *+   *   realloc ::+   *     A pointer type to a reallocation function.+   *+   */+  struct  FT_MemoryRec_+  {+    void*            user;+    FT_Alloc_Func    alloc;+    FT_Free_Func     free;+    FT_Realloc_Func  realloc;+  };+++  /*************************************************************************/+  /*                                                                       */+  /*                       I / O   M A N A G E M E N T                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************+   *+   * @type:+   *   FT_Stream+   *+   * @description:+   *   A handle to an input stream.+   *+   */+  typedef struct FT_StreamRec_*  FT_Stream;+++  /*************************************************************************+   *+   * @struct:+   *   FT_StreamDesc+   *+   * @description:+   *   A union type used to store either a long or a pointer.  This is used+   *   to store a file descriptor or a `FILE*' in an input stream.+   *+   */+  typedef union  FT_StreamDesc_+  {+    long   value;+    void*  pointer;++  } FT_StreamDesc;+++  /*************************************************************************+   *+   * @functype:+   *   FT_Stream_IoFunc+   *+   * @description:+   *   A function used to seek and read data from a given input stream.+   *+   * @input:+   *   stream ::+   *     A handle to the source stream.+   *+   *   offset ::+   *     The offset of read in stream (always from start).+   *+   *   buffer ::+   *     The address of the read buffer.+   *+   *   count ::+   *     The number of bytes to read from the stream.+   *+   * @return:+   *   The number of bytes effectively read by the stream.+   *+   * @note:+   *   This function might be called to perform a seek or skip operation+   *   with a `count' of~0.  A non-zero return value then indicates an+   *   error.+   *+   */+  typedef unsigned long+  (*FT_Stream_IoFunc)( FT_Stream       stream,+                       unsigned long   offset,+                       unsigned char*  buffer,+                       unsigned long   count );+++  /*************************************************************************+   *+   * @functype:+   *   FT_Stream_CloseFunc+   *+   * @description:+   *   A function used to close a given input stream.+   *+   * @input:+   *  stream ::+   *     A handle to the target stream.+   *+   */+  typedef void+  (*FT_Stream_CloseFunc)( FT_Stream  stream );+++  /*************************************************************************+   *+   * @struct:+   *   FT_StreamRec+   *+   * @description:+   *   A structure used to describe an input stream.+   *+   * @input:+   *   base ::+   *     For memory-based streams, this is the address of the first stream+   *     byte in memory.  This field should always be set to NULL for+   *     disk-based streams.+   *+   *   size ::+   *     The stream size in bytes.+   *+   *   pos ::+   *     The current position within the stream.+   *+   *   descriptor ::+   *     This field is a union that can hold an integer or a pointer.  It is+   *     used by stream implementations to store file descriptors or `FILE*'+   *     pointers.+   *+   *   pathname ::+   *     This field is completely ignored by FreeType.  However, it is often+   *     useful during debugging to use it to store the stream's filename+   *     (where available).+   *+   *   read ::+   *     The stream's input function.+   *+   *   close ::+   *     The stream's close function.+   *+   *   memory ::+   *     The memory manager to use to preload frames.  This is set+   *     internally by FreeType and shouldn't be touched by stream+   *     implementations.+   *+   *   cursor ::+   *     This field is set and used internally by FreeType when parsing+   *     frames.+   *+   *   limit ::+   *     This field is set and used internally by FreeType when parsing+   *     frames.+   *+   */+  typedef struct  FT_StreamRec_+  {+    unsigned char*       base;+    unsigned long        size;+    unsigned long        pos;++    FT_StreamDesc        descriptor;+    FT_StreamDesc        pathname;+    FT_Stream_IoFunc     read;+    FT_Stream_CloseFunc  close;++    FT_Memory            memory;+    unsigned char*       cursor;+    unsigned char*       limit;++  } FT_StreamRec;+++  /* */+++FT_END_HEADER++#endif /* __FTSYSTEM_H__ */+++/* END */
+ include/freetype/fttrigon.h view
@@ -0,0 +1,350 @@+/***************************************************************************/+/*                                                                         */+/*  fttrigon.h                                                             */+/*                                                                         */+/*    FreeType trigonometric functions (specification).                    */+/*                                                                         */+/*  Copyright 2001, 2003, 2005, 2007 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTTRIGON_H__+#define __FTTRIGON_H__++#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*   computations                                                        */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************+   *+   * @type:+   *   FT_Angle+   *+   * @description:+   *   This type is used to model angle values in FreeType.  Note that the+   *   angle is a 16.16 fixed float value expressed in degrees.+   *+   */+  typedef FT_Fixed  FT_Angle;+++  /*************************************************************************+   *+   * @macro:+   *   FT_ANGLE_PI+   *+   * @description:+   *   The angle pi expressed in @FT_Angle units.+   *+   */+#define FT_ANGLE_PI  ( 180L << 16 )+++  /*************************************************************************+   *+   * @macro:+   *   FT_ANGLE_2PI+   *+   * @description:+   *   The angle 2*pi expressed in @FT_Angle units.+   *+   */+#define FT_ANGLE_2PI  ( FT_ANGLE_PI * 2 )+++  /*************************************************************************+   *+   * @macro:+   *   FT_ANGLE_PI2+   *+   * @description:+   *   The angle pi/2 expressed in @FT_Angle units.+   *+   */+#define FT_ANGLE_PI2  ( FT_ANGLE_PI / 2 )+++  /*************************************************************************+   *+   * @macro:+   *   FT_ANGLE_PI4+   *+   * @description:+   *   The angle pi/4 expressed in @FT_Angle units.+   *+   */+#define FT_ANGLE_PI4  ( FT_ANGLE_PI / 4 )+++  /*************************************************************************+   *+   * @function:+   *   FT_Sin+   *+   * @description:+   *   Return the sinus of a given angle in fixed point format.+   *+   * @input:+   *   angle ::+   *     The input angle.+   *+   * @return:+   *   The sinus value.+   *+   * @note:+   *   If you need both the sinus and cosinus for a given angle, use the+   *   function @FT_Vector_Unit.+   *+   */+  FT_EXPORT( FT_Fixed )+  FT_Sin( FT_Angle  angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Cos+   *+   * @description:+   *   Return the cosinus of a given angle in fixed point format.+   *+   * @input:+   *   angle ::+   *     The input angle.+   *+   * @return:+   *   The cosinus value.+   *+   * @note:+   *   If you need both the sinus and cosinus for a given angle, use the+   *   function @FT_Vector_Unit.+   *+   */+  FT_EXPORT( FT_Fixed )+  FT_Cos( FT_Angle  angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Tan+   *+   * @description:+   *   Return the tangent of a given angle in fixed point format.+   *+   * @input:+   *   angle ::+   *     The input angle.+   *+   * @return:+   *   The tangent value.+   *+   */+  FT_EXPORT( FT_Fixed )+  FT_Tan( FT_Angle  angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Atan2+   *+   * @description:+   *   Return the arc-tangent corresponding to a given vector (x,y) in+   *   the 2d plane.+   *+   * @input:+   *   x ::+   *     The horizontal vector coordinate.+   *+   *   y ::+   *     The vertical vector coordinate.+   *+   * @return:+   *   The arc-tangent value (i.e. angle).+   *+   */+  FT_EXPORT( FT_Angle )+  FT_Atan2( FT_Fixed  x,+            FT_Fixed  y );+++  /*************************************************************************+   *+   * @function:+   *   FT_Angle_Diff+   *+   * @description:+   *   Return the difference between two angles.  The result is always+   *   constrained to the ]-PI..PI] interval.+   *+   * @input:+   *   angle1 ::+   *     First angle.+   *+   *   angle2 ::+   *     Second angle.+   *+   * @return:+   *   Constrained value of `value2-value1'.+   *+   */+  FT_EXPORT( FT_Angle )+  FT_Angle_Diff( FT_Angle  angle1,+                 FT_Angle  angle2 );+++  /*************************************************************************+   *+   * @function:+   *   FT_Vector_Unit+   *+   * @description:+   *   Return the unit vector corresponding to a given angle.  After the+   *   call, the value of `vec.x' will be `sin(angle)', and the value of+   *   `vec.y' will be `cos(angle)'.+   *+   *   This function is useful to retrieve both the sinus and cosinus of a+   *   given angle quickly.+   *+   * @output:+   *   vec ::+   *     The address of target vector.+   *+   * @input:+   *   angle ::+   *     The address of angle.+   *+   */+  FT_EXPORT( void )+  FT_Vector_Unit( FT_Vector*  vec,+                  FT_Angle    angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Vector_Rotate+   *+   * @description:+   *   Rotate a vector by a given angle.+   *+   * @inout:+   *   vec ::+   *     The address of target vector.+   *+   * @input:+   *   angle ::+   *     The address of angle.+   *+   */+  FT_EXPORT( void )+  FT_Vector_Rotate( FT_Vector*  vec,+                    FT_Angle    angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Vector_Length+   *+   * @description:+   *   Return the length of a given vector.+   *+   * @input:+   *   vec ::+   *     The address of target vector.+   *+   * @return:+   *   The vector length, expressed in the same units that the original+   *   vector coordinates.+   *+   */+  FT_EXPORT( FT_Fixed )+  FT_Vector_Length( FT_Vector*  vec );+++  /*************************************************************************+   *+   * @function:+   *   FT_Vector_Polarize+   *+   * @description:+   *   Compute both the length and angle of a given vector.+   *+   * @input:+   *   vec ::+   *     The address of source vector.+   *+   * @output:+   *   length ::+   *     The vector length.+   *+   *   angle ::+   *     The vector angle.+   *+   */+  FT_EXPORT( void )+  FT_Vector_Polarize( FT_Vector*  vec,+                      FT_Fixed   *length,+                      FT_Angle   *angle );+++  /*************************************************************************+   *+   * @function:+   *   FT_Vector_From_Polar+   *+   * @description:+   *   Compute vector coordinates from a length and angle.+   *+   * @output:+   *   vec ::+   *     The address of source vector.+   *+   * @input:+   *   length ::+   *     The vector length.+   *+   *   angle ::+   *     The vector angle.+   *+   */+  FT_EXPORT( void )+  FT_Vector_From_Polar( FT_Vector*  vec,+                        FT_Fixed    length,+                        FT_Angle    angle );++  /* */+++FT_END_HEADER++#endif /* __FTTRIGON_H__ */+++/* END */
+ include/freetype/fttypes.h view
@@ -0,0 +1,588 @@+/***************************************************************************/+/*                                                                         */+/*  fttypes.h                                                              */+/*                                                                         */+/*    FreeType simple types definitions (specification only).              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTTYPES_H__+#define __FTTYPES_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_SYSTEM_H+#include FT_IMAGE_H++#include <stddef.h>+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    basic_types                                                        */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Basic Data Types                                                   */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    The basic data types defined by the library.                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the basic data types defined by FreeType~2,  */+  /*    ranging from simple scalar types to bitmap descriptors.  More      */+  /*    font-specific structures are defined in a different section.       */+  /*                                                                       */+  /* <Order>                                                               */+  /*    FT_Byte                                                            */+  /*    FT_Bytes                                                           */+  /*    FT_Char                                                            */+  /*    FT_Int                                                             */+  /*    FT_UInt                                                            */+  /*    FT_Int16                                                           */+  /*    FT_UInt16                                                          */+  /*    FT_Int32                                                           */+  /*    FT_UInt32                                                          */+  /*    FT_Short                                                           */+  /*    FT_UShort                                                          */+  /*    FT_Long                                                            */+  /*    FT_ULong                                                           */+  /*    FT_Bool                                                            */+  /*    FT_Offset                                                          */+  /*    FT_PtrDist                                                         */+  /*    FT_String                                                          */+  /*    FT_Tag                                                             */+  /*    FT_Error                                                           */+  /*    FT_Fixed                                                           */+  /*    FT_Pointer                                                         */+  /*    FT_Pos                                                             */+  /*    FT_Vector                                                          */+  /*    FT_BBox                                                            */+  /*    FT_Matrix                                                          */+  /*    FT_FWord                                                           */+  /*    FT_UFWord                                                          */+  /*    FT_F2Dot14                                                         */+  /*    FT_UnitVector                                                      */+  /*    FT_F26Dot6                                                         */+  /*                                                                       */+  /*                                                                       */+  /*    FT_Generic                                                         */+  /*    FT_Generic_Finalizer                                               */+  /*                                                                       */+  /*    FT_Bitmap                                                          */+  /*    FT_Pixel_Mode                                                      */+  /*    FT_Palette_Mode                                                    */+  /*    FT_Glyph_Format                                                    */+  /*    FT_IMAGE_TAG                                                       */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Bool                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef of unsigned char, used for simple booleans.  As usual,   */+  /*    values 1 and~0 represent true and false, respectively.             */+  /*                                                                       */+  typedef unsigned char  FT_Bool;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_FWord                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A signed 16-bit integer used to store a distance in original font  */+  /*    units.                                                             */+  /*                                                                       */+  typedef signed short  FT_FWord;   /* distance in FUnits */+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_UFWord                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An unsigned 16-bit integer used to store a distance in original    */+  /*    font units.                                                        */+  /*                                                                       */+  typedef unsigned short  FT_UFWord;  /* unsigned distance */+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Char                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple typedef for the _signed_ char type.                       */+  /*                                                                       */+  typedef signed char  FT_Char;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Byte                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple typedef for the _unsigned_ char type.                     */+  /*                                                                       */+  typedef unsigned char  FT_Byte;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Bytes                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for constant memory areas.                               */+  /*                                                                       */+  typedef const FT_Byte*  FT_Bytes;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Tag                                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for 32-bit tags (as used in the SFNT format).            */+  /*                                                                       */+  typedef FT_UInt32  FT_Tag;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_String                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple typedef for the char type, usually used for strings.      */+  /*                                                                       */+  typedef char  FT_String;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Short                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for signed short.                                        */+  /*                                                                       */+  typedef signed short  FT_Short;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_UShort                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for unsigned short.                                      */+  /*                                                                       */+  typedef unsigned short  FT_UShort;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Int                                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for the int type.                                        */+  /*                                                                       */+  typedef signed int  FT_Int;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_UInt                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for the unsigned int type.                               */+  /*                                                                       */+  typedef unsigned int  FT_UInt;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Long                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for signed long.                                         */+  /*                                                                       */+  typedef signed long  FT_Long;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_ULong                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A typedef for unsigned long.                                       */+  /*                                                                       */+  typedef unsigned long  FT_ULong;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_F2Dot14                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A signed 2.14 fixed float type used for unit vectors.              */+  /*                                                                       */+  typedef signed short  FT_F2Dot14;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_F26Dot6                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A signed 26.6 fixed float type used for vectorial pixel            */+  /*    coordinates.                                                       */+  /*                                                                       */+  typedef signed long  FT_F26Dot6;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Fixed                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This type is used to store 16.16 fixed float values, like scaling  */+  /*    values or matrix coefficients.                                     */+  /*                                                                       */+  typedef signed long  FT_Fixed;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Error                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The FreeType error code type.  A value of~0 is always interpreted  */+  /*    as a successful operation.                                         */+  /*                                                                       */+  typedef int  FT_Error;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Pointer                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple typedef for a typeless pointer.                           */+  /*                                                                       */+  typedef void*  FT_Pointer;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_Offset                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This is equivalent to the ANSI~C `size_t' type, i.e., the largest  */+  /*    _unsigned_ integer type used to express a file size or position,   */+  /*    or a memory block size.                                            */+  /*                                                                       */+  typedef size_t  FT_Offset;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_PtrDist                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the       */+  /*    largest _signed_ integer type used to express the distance         */+  /*    between two pointers.                                              */+  /*                                                                       */+  typedef ft_ptrdiff_t  FT_PtrDist;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_UnitVector                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to store a 2D vector unit vector.  Uses    */+  /*    FT_F2Dot14 types.                                                  */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    x :: Horizontal coordinate.                                        */+  /*                                                                       */+  /*    y :: Vertical coordinate.                                          */+  /*                                                                       */+  typedef struct  FT_UnitVector_+  {+    FT_F2Dot14  x;+    FT_F2Dot14  y;++  } FT_UnitVector;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Matrix                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */+  /*    in 16.16 fixed float format.  The computation performed is:        */+  /*                                                                       */+  /*       {                                                               */+  /*          x' = x*xx + y*xy                                             */+  /*          y' = x*yx + y*yy                                             */+  /*       }                                                               */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    xx :: Matrix coefficient.                                          */+  /*                                                                       */+  /*    xy :: Matrix coefficient.                                          */+  /*                                                                       */+  /*    yx :: Matrix coefficient.                                          */+  /*                                                                       */+  /*    yy :: Matrix coefficient.                                          */+  /*                                                                       */+  typedef struct  FT_Matrix_+  {+    FT_Fixed  xx, xy;+    FT_Fixed  yx, yy;++  } FT_Matrix;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Data                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Read-only binary data represented as a pointer and a length.       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    pointer :: The data.                                               */+  /*                                                                       */+  /*    length  :: The length of the data in bytes.                        */+  /*                                                                       */+  typedef struct  FT_Data_+  {+    const FT_Byte*  pointer;+    FT_Int          length;++  } FT_Data;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Generic_Finalizer                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Describe a function used to destroy the `client' data of any       */+  /*    FreeType object.  See the description of the @FT_Generic type for  */+  /*    details of usage.                                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    The address of the FreeType object which is under finalization.    */+  /*    Its client data is accessed through its `generic' field.           */+  /*                                                                       */+  typedef void  (*FT_Generic_Finalizer)(void*  object);+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Generic                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Client applications often need to associate their own data to a    */+  /*    variety of FreeType core objects.  For example, a text layout API  */+  /*    might want to associate a glyph cache to a given size object.      */+  /*                                                                       */+  /*    Most FreeType object contains a `generic' field, of type           */+  /*    FT_Generic, which usage is left to client applications and font    */+  /*    servers.                                                           */+  /*                                                                       */+  /*    It can be used to store a pointer to client-specific data, as well */+  /*    as the address of a `finalizer' function, which will be called by  */+  /*    FreeType when the object is destroyed (for example, the previous   */+  /*    client example would put the address of the glyph cache destructor */+  /*    in the `finalizer' field).                                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    data      :: A typeless pointer to any client-specified data. This */+  /*                 field is completely ignored by the FreeType library.  */+  /*                                                                       */+  /*    finalizer :: A pointer to a `generic finalizer' function, which    */+  /*                 will be called when the object is destroyed.  If this */+  /*                 field is set to NULL, no code will be called.         */+  /*                                                                       */+  typedef struct  FT_Generic_+  {+    void*                 data;+    FT_Generic_Finalizer  finalizer;++  } FT_Generic;+++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_MAKE_TAG                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro converts four-letter tags which are used to label       */+  /*    TrueType tables into an unsigned long to be used within FreeType.  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The produced values *must* be 32-bit integers.  Don't redefine     */+  /*    this macro.                                                        */+  /*                                                                       */+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \+          (FT_Tag)                        \+          ( ( (FT_ULong)_x1 << 24 ) |     \+            ( (FT_ULong)_x2 << 16 ) |     \+            ( (FT_ULong)_x3 <<  8 ) |     \+              (FT_ULong)_x4         )+++  /*************************************************************************/+  /*************************************************************************/+  /*                                                                       */+  /*                    L I S T   M A N A G E M E N T                      */+  /*                                                                       */+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    list_processing                                                    */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_ListNode                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*     Many elements and objects in FreeType are listed through an       */+  /*     @FT_List record (see @FT_ListRec).  As its name suggests, an      */+  /*     FT_ListNode is a handle to a single list element.                 */+  /*                                                                       */+  typedef struct FT_ListNodeRec_*  FT_ListNode;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    FT_List                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a list record (see @FT_ListRec).                       */+  /*                                                                       */+  typedef struct FT_ListRec_*  FT_List;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_ListNodeRec                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to hold a single list element.                    */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    prev :: The previous element in the list.  NULL if first.          */+  /*                                                                       */+  /*    next :: The next element in the list.  NULL if last.               */+  /*                                                                       */+  /*    data :: A typeless pointer to the listed object.                   */+  /*                                                                       */+  typedef struct  FT_ListNodeRec_+  {+    FT_ListNode  prev;+    FT_ListNode  next;+    void*        data;++  } FT_ListNodeRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_ListRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to hold a simple doubly-linked list.  These are   */+  /*    used in many parts of FreeType.                                    */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    head :: The head (first element) of doubly-linked list.            */+  /*                                                                       */+  /*    tail :: The tail (last element) of doubly-linked list.             */+  /*                                                                       */+  typedef struct  FT_ListRec_+  {+    FT_ListNode  head;+    FT_ListNode  tail;++  } FT_ListRec;+++  /* */++#define FT_IS_EMPTY( list )  ( (list).head == 0 )++  /* return base error code (without module-specific prefix) */+#define FT_ERROR_BASE( x )    ( (x) & 0xFF )++  /* return module error code */+#define FT_ERROR_MODULE( x )  ( (x) & 0xFF00U )++#define FT_BOOL( x )  ( (FT_Bool)( x ) )++FT_END_HEADER++#endif /* __FTTYPES_H__ */+++/* END */
+ include/freetype/ftwinfnt.h view
@@ -0,0 +1,274 @@+/***************************************************************************/+/*                                                                         */+/*  ftwinfnt.h                                                             */+/*                                                                         */+/*    FreeType API for accessing Windows fnt-specific data.                */+/*                                                                         */+/*  Copyright 2003, 2004, 2008 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTWINFNT_H__+#define __FTWINFNT_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    winfnt_fonts                                                       */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Window FNT Files                                                   */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Windows FNT specific API.                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the declaration of Windows FNT specific      */+  /*    functions.                                                         */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************+   *+   * @enum:+   *   FT_WinFNT_ID_XXX+   *+   * @description:+   *   A list of valid values for the `charset' byte in+   *   @FT_WinFNT_HeaderRec.  Exact mapping tables for the various cpXXXX+   *   encodings (except for cp1361) can be found at ftp://ftp.unicode.org+   *   in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory.  cp1361 is+   *   roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT.+   *+   * @values:+   *   FT_WinFNT_ID_DEFAULT ::+   *     This is used for font enumeration and font creation as a+   *     `don't care' value.  Valid font files don't contain this value.+   *     When querying for information about the character set of the font+   *     that is currently selected into a specified device context, this+   *     return value (of the related Windows API) simply denotes failure.+   *+   *   FT_WinFNT_ID_SYMBOL ::+   *     There is no known mapping table available.+   *+   *   FT_WinFNT_ID_MAC ::+   *     Mac Roman encoding.+   *+   *   FT_WinFNT_ID_OEM ::+   *     From Michael Pöttgen <michael@poettgen.de>:+   *+   *       The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM+   *       is used for the charset of vector fonts, like `modern.fon',+   *       `roman.fon', and `script.fon' on Windows.+   *+   *       The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value+   *       specifies a character set that is operating-system dependent.+   *+   *       The `IFIMETRICS' documentation from the `Windows Driver+   *       Development Kit' says: This font supports an OEM-specific+   *       character set.  The OEM character set is system dependent.+   *+   *       In general OEM, as opposed to ANSI (i.e., cp1252), denotes the+   *       second default codepage that most international versions of+   *       Windows have.  It is one of the OEM codepages from+   *+   *         http://www.microsoft.com/globaldev/reference/cphome.mspx,+   *+   *       and is used for the `DOS boxes', to support legacy applications.+   *       A German Windows version for example usually uses ANSI codepage+   *       1252 and OEM codepage 850.+   *+   *   FT_WinFNT_ID_CP874 ::+   *     A superset of Thai TIS 620 and ISO 8859-11.+   *+   *   FT_WinFNT_ID_CP932 ::+   *     A superset of Japanese Shift-JIS (with minor deviations).+   *+   *   FT_WinFNT_ID_CP936 ::+   *     A superset of simplified Chinese GB 2312-1980 (with different+   *     ordering and minor deviations).+   *+   *   FT_WinFNT_ID_CP949 ::+   *     A superset of Korean Hangul KS~C 5601-1987 (with different+   *     ordering and minor deviations).+   *+   *   FT_WinFNT_ID_CP950 ::+   *     A superset of traditional Chinese Big~5 ETen (with different+   *     ordering and minor deviations).+   *+   *   FT_WinFNT_ID_CP1250 ::+   *     A superset of East European ISO 8859-2 (with slightly different+   *     ordering).+   *+   *   FT_WinFNT_ID_CP1251 ::+   *     A superset of Russian ISO 8859-5 (with different ordering).+   *+   *   FT_WinFNT_ID_CP1252 ::+   *     ANSI encoding.  A superset of ISO 8859-1.+   *+   *   FT_WinFNT_ID_CP1253 ::+   *     A superset of Greek ISO 8859-7 (with minor modifications).+   *+   *   FT_WinFNT_ID_CP1254 ::+   *     A superset of Turkish ISO 8859-9.+   *+   *   FT_WinFNT_ID_CP1255 ::+   *     A superset of Hebrew ISO 8859-8 (with some modifications).+   *+   *   FT_WinFNT_ID_CP1256 ::+   *     A superset of Arabic ISO 8859-6 (with different ordering).+   *+   *   FT_WinFNT_ID_CP1257 ::+   *     A superset of Baltic ISO 8859-13 (with some deviations).+   *+   *   FT_WinFNT_ID_CP1258 ::+   *     For Vietnamese.  This encoding doesn't cover all necessary+   *     characters.+   *+   *   FT_WinFNT_ID_CP1361 ::+   *     Korean (Johab).+   */++#define FT_WinFNT_ID_CP1252    0+#define FT_WinFNT_ID_DEFAULT   1+#define FT_WinFNT_ID_SYMBOL    2+#define FT_WinFNT_ID_MAC      77+#define FT_WinFNT_ID_CP932   128+#define FT_WinFNT_ID_CP949   129+#define FT_WinFNT_ID_CP1361  130+#define FT_WinFNT_ID_CP936   134+#define FT_WinFNT_ID_CP950   136+#define FT_WinFNT_ID_CP1253  161+#define FT_WinFNT_ID_CP1254  162+#define FT_WinFNT_ID_CP1258  163+#define FT_WinFNT_ID_CP1255  177+#define FT_WinFNT_ID_CP1256  178+#define FT_WinFNT_ID_CP1257  186+#define FT_WinFNT_ID_CP1251  204+#define FT_WinFNT_ID_CP874   222+#define FT_WinFNT_ID_CP1250  238+#define FT_WinFNT_ID_OEM     255+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_WinFNT_HeaderRec                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Windows FNT Header info.                                           */+  /*                                                                       */+  typedef struct  FT_WinFNT_HeaderRec_+  {+    FT_UShort  version;+    FT_ULong   file_size;+    FT_Byte    copyright[60];+    FT_UShort  file_type;+    FT_UShort  nominal_point_size;+    FT_UShort  vertical_resolution;+    FT_UShort  horizontal_resolution;+    FT_UShort  ascent;+    FT_UShort  internal_leading;+    FT_UShort  external_leading;+    FT_Byte    italic;+    FT_Byte    underline;+    FT_Byte    strike_out;+    FT_UShort  weight;+    FT_Byte    charset;+    FT_UShort  pixel_width;+    FT_UShort  pixel_height;+    FT_Byte    pitch_and_family;+    FT_UShort  avg_width;+    FT_UShort  max_width;+    FT_Byte    first_char;+    FT_Byte    last_char;+    FT_Byte    default_char;+    FT_Byte    break_char;+    FT_UShort  bytes_per_row;+    FT_ULong   device_offset;+    FT_ULong   face_name_offset;+    FT_ULong   bits_pointer;+    FT_ULong   bits_offset;+    FT_Byte    reserved;+    FT_ULong   flags;+    FT_UShort  A_space;+    FT_UShort  B_space;+    FT_UShort  C_space;+    FT_UShort  color_table_offset;+    FT_ULong   reserved1[4];++  } FT_WinFNT_HeaderRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_WinFNT_Header                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an @FT_WinFNT_HeaderRec structure.                     */+  /*                                                                       */+  typedef struct FT_WinFNT_HeaderRec_*  FT_WinFNT_Header;+++  /**********************************************************************+   *+   * @function:+   *    FT_Get_WinFNT_Header+   *+   * @description:+   *    Retrieve a Windows FNT font info header.+   *+   * @input:+   *    face    :: A handle to the input face.+   *+   * @output:+   *    aheader :: The WinFNT header.+   *+   * @return:+   *   FreeType error code.  0~means success.+   *+   * @note:+   *   This function only works with Windows FNT faces, returning an error+   *   otherwise.+   */+  FT_EXPORT( FT_Error )+  FT_Get_WinFNT_Header( FT_Face               face,+                        FT_WinFNT_HeaderRec  *aheader );+++  /* */++FT_END_HEADER++#endif /* __FTWINFNT_H__ */+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ include/freetype/ftxf86.h view
@@ -0,0 +1,83 @@+/***************************************************************************/+/*                                                                         */+/*  ftxf86.h                                                               */+/*                                                                         */+/*    Support functions for X11.                                           */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTXF86_H__+#define __FTXF86_H__++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*   font_formats                                                        */+  /*                                                                       */+  /* <Title>                                                               */+  /*   Font Formats                                                        */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*   Getting the font format.                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*   The single function in this section can be used to get the font     */+  /*   format.  Note that this information is not needed normally;         */+  /*   however, there are special cases (like in PDF devices) where it is  */+  /*   important to differentiate, in spite of FreeType's uniform API.     */+  /*                                                                       */+  /*   This function is in the X11/xf86 namespace for historical reasons   */+  /*   and in no way depends on that windowing system.                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*   FT_Get_X11_Font_Format                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*   Return a string describing the format of a given face, using values */+  /*   which can be used as an X11 FONT_PROPERTY.  Possible values are     */+  /*   `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */+  /*   `PFR', and `Windows~FNT'.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*   face ::                                                             */+  /*     Input face handle.                                                */+  /*                                                                       */+  /* <Return>                                                              */+  /*   Font format string.  NULL in case of error.                         */+  /*                                                                       */+  FT_EXPORT( const char* )+  FT_Get_X11_Font_Format( FT_Face  face );++ /* */++FT_END_HEADER++#endif /* __FTXF86_H__ */
+ include/freetype/internal/autohint.h view
@@ -0,0 +1,231 @@+/***************************************************************************/+/*                                                                         */+/*  autohint.h                                                             */+/*                                                                         */+/*    High-level `autohint' module-specific interface (specification).     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2007 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* The auto-hinter is used to load and automatically hint glyphs if a    */+  /* format-specific hinter isn't available.                               */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __AUTOHINT_H__+#define __AUTOHINT_H__+++  /*************************************************************************/+  /*                                                                       */+  /* A small technical note regarding automatic hinting in order to        */+  /* clarify this module interface.                                        */+  /*                                                                       */+  /* An automatic hinter might compute two kinds of data for a given face: */+  /*                                                                       */+  /* - global hints: Usually some metrics that describe global properties  */+  /*                 of the face.  It is computed by scanning more or less */+  /*                 aggressively the glyphs in the face, and thus can be  */+  /*                 very slow to compute (even if the size of global      */+  /*                 hints is really small).                               */+  /*                                                                       */+  /* - glyph hints:  These describe some important features of the glyph   */+  /*                 outline, as well as how to align them.  They are      */+  /*                 generally much faster to compute than global hints.   */+  /*                                                                       */+  /* The current FreeType auto-hinter does a pretty good job while         */+  /* performing fast computations for both global and glyph hints.         */+  /* However, we might be interested in introducing more complex and       */+  /* powerful algorithms in the future, like the one described in the John */+  /* D. Hobby paper, which unfortunately requires a lot more horsepower.   */+  /*                                                                       */+  /* Because a sufficiently sophisticated font management system would     */+  /* typically implement an LRU cache of opened face objects to reduce     */+  /* memory usage, it is a good idea to be able to avoid recomputing       */+  /* global hints every time the same face is re-opened.                   */+  /*                                                                       */+  /* We thus provide the ability to cache global hints outside of the face */+  /* object, in order to speed up font re-opening time.  Of course, this   */+  /* feature is purely optional, so most client programs won't even notice */+  /* it.                                                                   */+  /*                                                                       */+  /* I initially thought that it would be a good idea to cache the glyph   */+  /* hints too.  However, my general idea now is that if you really need   */+  /* to cache these too, you are simply in need of a new font format,      */+  /* where all this information could be stored within the font file and   */+  /* decoded on the fly.                                                   */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+++FT_BEGIN_HEADER+++  typedef struct FT_AutoHinterRec_  *FT_AutoHinter;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_AutoHinter_GlobalGetFunc                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Retrieves the global hints computed for a given face object the    */+  /*    resulting data is dissociated from the face and will survive a     */+  /*    call to FT_Done_Face().  It must be discarded through the API      */+  /*    FT_AutoHinter_GlobalDoneFunc().                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    hinter        :: A handle to the source auto-hinter.               */+  /*                                                                       */+  /*    face          :: A handle to the source face object.               */+  /*                                                                       */+  /* <Output>                                                              */+  /*    global_hints  :: A typeless pointer to the global hints.           */+  /*                                                                       */+  /*    global_len    :: The size in bytes of the global hints.            */+  /*                                                                       */+  typedef void+  (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter  hinter,+                                  FT_Face        face,+                                  void**         global_hints,+                                  long*          global_len );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_AutoHinter_GlobalDoneFunc                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Discards the global hints retrieved through                        */+  /*    FT_AutoHinter_GlobalGetFunc().  This is the only way these hints   */+  /*    are freed from memory.                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    hinter :: A handle to the auto-hinter module.                      */+  /*                                                                       */+  /*    global :: A pointer to retrieved global hints to discard.          */+  /*                                                                       */+  typedef void+  (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter  hinter,+                                   void*          global );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_AutoHinter_GlobalResetFunc                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to recompute the global metrics in a given   */+  /*    font.  This is useful when global font data changes (e.g. Multiple */+  /*    Masters fonts where blend coordinates change).                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    hinter :: A handle to the source auto-hinter.                      */+  /*                                                                       */+  /*    face   :: A handle to the face.                                    */+  /*                                                                       */+  typedef void+  (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter  hinter,+                                    FT_Face        face );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_AutoHinter_GlyphLoadFunc                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to load, scale, and automatically hint a     */+  /*    glyph from a given face.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to the face.                               */+  /*                                                                       */+  /*    glyph_index :: The glyph index.                                    */+  /*                                                                       */+  /*    load_flags  :: The load flags.                                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function is capable of loading composite glyphs by hinting    */+  /*    each sub-glyph independently (which improves quality).             */+  /*                                                                       */+  /*    It will call the font driver with FT_Load_Glyph(), with            */+  /*    FT_LOAD_NO_SCALE set.                                              */+  /*                                                                       */+  typedef FT_Error+  (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter  hinter,+                                  FT_GlyphSlot   slot,+                                  FT_Size        size,+                                  FT_UInt        glyph_index,+                                  FT_Int32       load_flags );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_AutoHinter_ServiceRec                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The auto-hinter module's interface.                                */+  /*                                                                       */+  typedef struct  FT_AutoHinter_ServiceRec_+  {+    FT_AutoHinter_GlobalResetFunc  reset_face;+    FT_AutoHinter_GlobalGetFunc    get_global_hints;+    FT_AutoHinter_GlobalDoneFunc   done_global_hints;+    FT_AutoHinter_GlyphLoadFunc    load_glyph;++  } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service;++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \+                                     done_global_hints_, load_glyph_)        \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_AutoHinter_ServiceRec class_ =                                    \+  {                                                                          \+    reset_face_, get_global_hints_, done_global_hints_, load_glyph_          \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \+                                     done_global_hints_, load_glyph_)        \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library,                                \+                          FT_AutoHinter_ServiceRec* clazz)                   \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    clazz->reset_face = reset_face_;                                         \+    clazz->get_global_hints = get_global_hints_;                             \+    clazz->done_global_hints = done_global_hints_;                           \+    clazz->load_glyph = load_glyph_;                                         \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++FT_END_HEADER++#endif /* __AUTOHINT_H__ */+++/* END */
+ include/freetype/internal/ftcalc.h view
@@ -0,0 +1,179 @@+/***************************************************************************/+/*                                                                         */+/*  ftcalc.h                                                               */+/*                                                                         */+/*    Arithmetic computations (specification).                             */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTCALC_H__+#define __FTCALC_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_FixedSqrt                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the square root of a 16.16 fixed point value.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    x :: The value to compute the root for.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `sqrt(x)'.                                           */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function is not very fast.                                    */+  /*                                                                       */+  FT_BASE( FT_Int32 )+  FT_SqrtFixed( FT_Int32  x );+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Sqrt32                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the square root of an Int32 integer (which will be        */+  /*    handled as an unsigned long value).                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    x :: The value to compute the root for.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `sqrt(x)'.                                           */+  /*                                                                       */+  FT_EXPORT( FT_Int32 )+  FT_Sqrt32( FT_Int32  x );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* FT_MulDiv() and FT_MulFix() are declared in freetype.h.               */+  /*                                                                       */+  /*************************************************************************/+++#ifdef TT_USE_BYTECODE_INTERPRETER++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_MulDiv_No_Round                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A very simple function used to perform the computation `(a*b)/c'   */+  /*    (without rounding) with maximal accuracy (it uses a 64-bit         */+  /*    intermediate integer whenever necessary).                          */+  /*                                                                       */+  /*    This function isn't necessarily as fast as some processor specific */+  /*    operations, but is at least completely portable.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    a :: The first multiplier.                                         */+  /*    b :: The second multiplier.                                        */+  /*    c :: The divisor.                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The result of `(a*b)/c'.  This function never traps when trying to */+  /*    divide by zero; it simply returns `MaxInt' or `MinInt' depending   */+  /*    on the signs of `a' and `b'.                                       */+  /*                                                                       */+  FT_BASE( FT_Long )+  FT_MulDiv_No_Round( FT_Long  a,+                      FT_Long  b,+                      FT_Long  c );++#endif /* TT_USE_BYTECODE_INTERPRETER */+++  /*+   *  A variant of FT_Matrix_Multiply which scales its result afterwards.+   *  The idea is that both `a' and `b' are scaled by factors of 10 so that+   *  the values are as precise as possible to get a correct result during+   *  the 64bit multiplication.  Let `sa' and `sb' be the scaling factors of+   *  `a' and `b', respectively, then the scaling factor of the result is+   *  `sa*sb'.+   */+  FT_BASE( void )+  FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,+                             FT_Matrix        *b,+                             FT_Long           scaling );+++  /*+   *  A variant of FT_Vector_Transform.  See comments for+   *  FT_Matrix_Multiply_Scaled.+   */++  FT_BASE( void )+  FT_Vector_Transform_Scaled( FT_Vector*        vector,+                              const FT_Matrix*  matrix,+                              FT_Long           scaling );+++  /*+   *  Return -1, 0, or +1, depending on the orientation of a given corner.+   *  We use the Cartesian coordinate system, with positive vertical values+   *  going upwards.  The function returns +1 if the corner turns to the+   *  left, -1 to the right, and 0 for undecidable cases.+   */+  FT_BASE( FT_Int )+  ft_corner_orientation( FT_Pos  in_x,+                         FT_Pos  in_y,+                         FT_Pos  out_x,+                         FT_Pos  out_y );++  /*+   *  Return TRUE if a corner is flat or nearly flat.  This is equivalent to+   *  saying that the angle difference between the `in' and `out' vectors is+   *  very small.+   */+  FT_BASE( FT_Int )+  ft_corner_is_flat( FT_Pos  in_x,+                     FT_Pos  in_y,+                     FT_Pos  out_x,+                     FT_Pos  out_y );+++#define INT_TO_F26DOT6( x )    ( (FT_Long)(x) << 6  )+#define INT_TO_F2DOT14( x )    ( (FT_Long)(x) << 14 )+#define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )+#define F2DOT14_TO_FIXED( x )  ( (FT_Long)(x) << 2  )+#define FLOAT_TO_FIXED( x )    ( (FT_Long)( x * 65536.0 ) )+#define FIXED_TO_INT( x )      ( FT_RoundFix( x ) >> 16 )++#define ROUND_F26DOT6( x )     ( x >= 0 ? (    ( (x) + 32 ) & -64 )     \+                                        : ( -( ( 32 - (x) ) & -64 ) ) )+++FT_END_HEADER++#endif /* __FTCALC_H__ */+++/* END */
+ include/freetype/internal/ftdebug.h view
@@ -0,0 +1,250 @@+/***************************************************************************/+/*                                                                         */+/*  ftdebug.h                                                              */+/*                                                                         */+/*    Debugging and logging component (specification).                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/*                                                                         */+/*  IMPORTANT: A description of FreeType's debugging support can be        */+/*             found in `docs/DEBUG.TXT'.  Read it if you need to use or   */+/*             understand this code.                                       */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTDEBUG_H__+#define __FTDEBUG_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_FREETYPE_H+++FT_BEGIN_HEADER+++  /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */+  /* is already defined; this simplifies the following #ifdefs            */+  /*                                                                      */+#ifdef FT_DEBUG_LEVEL_TRACE+#undef  FT_DEBUG_LEVEL_ERROR+#define FT_DEBUG_LEVEL_ERROR+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* Define the trace enums as well as the trace levels array when they    */+  /* are needed.                                                           */+  /*                                                                       */+  /*************************************************************************/++#ifdef FT_DEBUG_LEVEL_TRACE++#define FT_TRACE_DEF( x )  trace_ ## x ,++  /* defining the enumeration */+  typedef enum  FT_Trace_+  {+#include FT_INTERNAL_TRACE_H+    trace_count++  } FT_Trace;+++  /* defining the array of trace levels, provided by `src/base/ftdebug.c' */+  extern int  ft_trace_levels[trace_count];++#undef FT_TRACE_DEF++#endif /* FT_DEBUG_LEVEL_TRACE */+++  /*************************************************************************/+  /*                                                                       */+  /* Define the FT_TRACE macro                                             */+  /*                                                                       */+  /* IMPORTANT!                                                            */+  /*                                                                       */+  /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */+  /* value before using any TRACE macro.                                   */+  /*                                                                       */+  /*************************************************************************/++#ifdef FT_DEBUG_LEVEL_TRACE++#define FT_TRACE( level, varformat )                      \+          do                                              \+          {                                               \+            if ( ft_trace_levels[FT_COMPONENT] >= level ) \+              FT_Message varformat;                       \+          } while ( 0 )++#else /* !FT_DEBUG_LEVEL_TRACE */++#define FT_TRACE( level, varformat )  do { } while ( 0 )      /* nothing */++#endif /* !FT_DEBUG_LEVEL_TRACE */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Trace_Get_Count                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the number of available trace components.                   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The number of trace components.  0 if FreeType 2 is not built with */+  /*    FT_DEBUG_LEVEL_TRACE definition.                                   */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function may be useful if you want to access elements of      */+  /*    the internal `ft_trace_levels' array by an index.                  */+  /*                                                                       */+  FT_BASE( FT_Int )+  FT_Trace_Get_Count( void );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Trace_Get_Name                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return the name of a trace component.                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    The index of the trace component.                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The name of the trace component.  This is a statically allocated   */+  /*    C string, so do not free it after use.  NULL if FreeType 2 is not  */+  /*    built with FT_DEBUG_LEVEL_TRACE definition.                        */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Use @FT_Trace_Get_Count to get the number of available trace       */+  /*    components.                                                        */+  /*                                                                       */+  /*    This function may be useful if you want to control FreeType 2's    */+  /*    debug level in your application.                                   */+  /*                                                                       */+  FT_BASE( const char * )+  FT_Trace_Get_Name( FT_Int  idx );+++  /*************************************************************************/+  /*                                                                       */+  /* You need two opening and closing parentheses!                         */+  /*                                                                       */+  /* Example: FT_TRACE0(( "Value is %i", foo ))                            */+  /*                                                                       */+  /* Output of the FT_TRACEX macros is sent to stderr.                     */+  /*                                                                       */+  /*************************************************************************/++#define FT_TRACE0( varformat )  FT_TRACE( 0, varformat )+#define FT_TRACE1( varformat )  FT_TRACE( 1, varformat )+#define FT_TRACE2( varformat )  FT_TRACE( 2, varformat )+#define FT_TRACE3( varformat )  FT_TRACE( 3, varformat )+#define FT_TRACE4( varformat )  FT_TRACE( 4, varformat )+#define FT_TRACE5( varformat )  FT_TRACE( 5, varformat )+#define FT_TRACE6( varformat )  FT_TRACE( 6, varformat )+#define FT_TRACE7( varformat )  FT_TRACE( 7, varformat )+++  /*************************************************************************/+  /*                                                                       */+  /* Define the FT_ERROR macro.                                            */+  /*                                                                       */+  /* Output of this macro is sent to stderr.                               */+  /*                                                                       */+  /*************************************************************************/++#ifdef FT_DEBUG_LEVEL_ERROR++#define FT_ERROR( varformat )  FT_Message  varformat++#else  /* !FT_DEBUG_LEVEL_ERROR */++#define FT_ERROR( varformat )  do { } while ( 0 )      /* nothing */++#endif /* !FT_DEBUG_LEVEL_ERROR */+++  /*************************************************************************/+  /*                                                                       */+  /* Define the FT_ASSERT macro.                                           */+  /*                                                                       */+  /*************************************************************************/++#ifdef FT_DEBUG_LEVEL_ERROR++#define FT_ASSERT( condition )                                      \+          do                                                        \+          {                                                         \+            if ( !( condition ) )                                   \+              FT_Panic( "assertion failed on line %d of file %s\n", \+                        __LINE__, __FILE__ );                       \+          } while ( 0 )++#else /* !FT_DEBUG_LEVEL_ERROR */++#define FT_ASSERT( condition )  do { } while ( 0 )++#endif /* !FT_DEBUG_LEVEL_ERROR */+++  /*************************************************************************/+  /*                                                                       */+  /* Define `FT_Message' and `FT_Panic' when needed.                       */+  /*                                                                       */+  /*************************************************************************/++#ifdef FT_DEBUG_LEVEL_ERROR++#include "stdio.h"  /* for vfprintf() */++  /* print a message */+  FT_BASE( void )+  FT_Message( const char*  fmt,+              ... );++  /* print a message and exit */+  FT_BASE( void )+  FT_Panic( const char*  fmt,+            ... );++#endif /* FT_DEBUG_LEVEL_ERROR */+++  FT_BASE( void )+  ft_debug_init( void );+++#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */++  /* We disable the warning `conditional expression is constant' here */+  /* in order to compile cleanly with the maximum level of warnings.  */+#pragma warning( disable : 4127 )++#endif /* _MSC_VER */+++FT_END_HEADER++#endif /* __FTDEBUG_H__ */+++/* END */
+ include/freetype/internal/ftdriver.h view
@@ -0,0 +1,422 @@+/***************************************************************************/+/*                                                                         */+/*  ftdriver.h                                                             */+/*                                                                         */+/*    FreeType font driver interface (specification).                      */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2008 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTDRIVER_H__+#define __FTDRIVER_H__+++#include <ft2build.h>+#include FT_MODULE_H+++FT_BEGIN_HEADER+++  typedef FT_Error+  (*FT_Face_InitFunc)( FT_Stream      stream,+                       FT_Face        face,+                       FT_Int         typeface_index,+                       FT_Int         num_params,+                       FT_Parameter*  parameters );++  typedef void+  (*FT_Face_DoneFunc)( FT_Face  face );+++  typedef FT_Error+  (*FT_Size_InitFunc)( FT_Size  size );++  typedef void+  (*FT_Size_DoneFunc)( FT_Size  size );+++  typedef FT_Error+  (*FT_Slot_InitFunc)( FT_GlyphSlot  slot );++  typedef void+  (*FT_Slot_DoneFunc)( FT_GlyphSlot  slot );+++  typedef FT_Error+  (*FT_Size_RequestFunc)( FT_Size          size,+                          FT_Size_Request  req );++  typedef FT_Error+  (*FT_Size_SelectFunc)( FT_Size   size,+                         FT_ULong  size_index );++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  typedef FT_Error+  (*FT_Size_ResetPointsFunc)( FT_Size     size,+                              FT_F26Dot6  char_width,+                              FT_F26Dot6  char_height,+                              FT_UInt     horz_resolution,+                              FT_UInt     vert_resolution );++  typedef FT_Error+  (*FT_Size_ResetPixelsFunc)( FT_Size  size,+                              FT_UInt  pixel_width,+                              FT_UInt  pixel_height );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++  typedef FT_Error+  (*FT_Slot_LoadFunc)( FT_GlyphSlot  slot,+                       FT_Size       size,+                       FT_UInt       glyph_index,+                       FT_Int32      load_flags );+++  typedef FT_UInt+  (*FT_CharMap_CharIndexFunc)( FT_CharMap  charmap,+                               FT_Long     charcode );++  typedef FT_Long+  (*FT_CharMap_CharNextFunc)( FT_CharMap  charmap,+                              FT_Long     charcode );+++  typedef FT_Error+  (*FT_Face_GetKerningFunc)( FT_Face     face,+                             FT_UInt     left_glyph,+                             FT_UInt     right_glyph,+                             FT_Vector*  kerning );+++  typedef FT_Error+  (*FT_Face_AttachFunc)( FT_Face    face,+                         FT_Stream  stream );+++  typedef FT_Error+  (*FT_Face_GetAdvancesFunc)( FT_Face    face,+                              FT_UInt    first,+                              FT_UInt    count,+                              FT_Int32   flags,+                              FT_Fixed*  advances );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Driver_ClassRec                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The font driver class.  This structure mostly contains pointers to */+  /*    driver methods.                                                    */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root             :: The parent module.                             */+  /*                                                                       */+  /*    face_object_size :: The size of a face object in bytes.            */+  /*                                                                       */+  /*    size_object_size :: The size of a size object in bytes.            */+  /*                                                                       */+  /*    slot_object_size :: The size of a glyph object in bytes.           */+  /*                                                                       */+  /*    init_face        :: The format-specific face constructor.          */+  /*                                                                       */+  /*    done_face        :: The format-specific face destructor.           */+  /*                                                                       */+  /*    init_size        :: The format-specific size constructor.          */+  /*                                                                       */+  /*    done_size        :: The format-specific size destructor.           */+  /*                                                                       */+  /*    init_slot        :: The format-specific slot constructor.          */+  /*                                                                       */+  /*    done_slot        :: The format-specific slot destructor.           */+  /*                                                                       */+  /*                                                                       */+  /*    load_glyph       :: A function handle to load a glyph to a slot.   */+  /*                        This field is mandatory!                       */+  /*                                                                       */+  /*    get_kerning      :: A function handle to return the unscaled       */+  /*                        kerning for a given pair of glyphs.  Can be    */+  /*                        set to 0 if the format doesn't support         */+  /*                        kerning.                                       */+  /*                                                                       */+  /*    attach_file      :: This function handle is used to read           */+  /*                        additional data for a face from another        */+  /*                        file/stream.  For example, this can be used to */+  /*                        add data from AFM or PFM files on a Type 1     */+  /*                        face, or a CIDMap on a CID-keyed face.         */+  /*                                                                       */+  /*    get_advances     :: A function handle used to return advance       */+  /*                        widths of `count' glyphs (in font units),      */+  /*                        starting at `first'.  The `vertical' flag must */+  /*                        be set to get vertical advance heights.  The   */+  /*                        `advances' buffer is caller-allocated.         */+  /*                        Currently not implemented.  The idea of this   */+  /*                        function is to be able to perform              */+  /*                        device-independent text layout without loading */+  /*                        a single glyph image.                          */+  /*                                                                       */+  /*    request_size     :: A handle to a function used to request the new */+  /*                        character size.  Can be set to 0 if the        */+  /*                        scaling done in the base layer suffices.       */+  /*                                                                       */+  /*    select_size      :: A handle to a function used to select a new    */+  /*                        fixed size.  It is used only if                */+  /*                        @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set  */+  /*                        to 0 if the scaling done in the base layer     */+  /*                        suffices.                                      */+  /* <Note>                                                                */+  /*    Most function pointers, with the exception of `load_glyph', can be */+  /*    set to 0 to indicate a default behaviour.                          */+  /*                                                                       */+  typedef struct  FT_Driver_ClassRec_+  {+    FT_Module_Class           root;++    FT_Long                   face_object_size;+    FT_Long                   size_object_size;+    FT_Long                   slot_object_size;++    FT_Face_InitFunc          init_face;+    FT_Face_DoneFunc          done_face;++    FT_Size_InitFunc          init_size;+    FT_Size_DoneFunc          done_size;++    FT_Slot_InitFunc          init_slot;+    FT_Slot_DoneFunc          done_slot;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++    FT_Size_ResetPointsFunc   set_char_sizes;+    FT_Size_ResetPixelsFunc   set_pixel_sizes;++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++    FT_Slot_LoadFunc          load_glyph;++    FT_Face_GetKerningFunc    get_kerning;+    FT_Face_AttachFunc        attach_file;+    FT_Face_GetAdvancesFunc   get_advances;++    /* since version 2.2 */+    FT_Size_RequestFunc       request_size;+    FT_Size_SelectFunc        select_size;++  } FT_Driver_ClassRec, *FT_Driver_Class;+++  /*+   *  The following functions are used as stubs for `set_char_sizes' and+   *  `set_pixel_sizes'; the code uses `request_size' and `select_size'+   *  functions instead.+   *+   *  Implementation is in `src/base/ftobjs.c'.+   */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_BASE( FT_Error )+  ft_stub_set_char_sizes( FT_Size     size,+                          FT_F26Dot6  width,+                          FT_F26Dot6  height,+                          FT_UInt     horz_res,+                          FT_UInt     vert_res );++  FT_BASE( FT_Error )+  ft_stub_set_pixel_sizes( FT_Size  size,+                           FT_UInt  width,+                           FT_UInt  height );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DECLARE_DRIVER                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to create a forward declaration of a                          */+  /*    FT_Driver_ClassRec stract instance.                                */+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_DRIVER                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Driver_ClassRec struct.       */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */+  /*    to called with a pointer where the allocated stracture is returned.*/+  /*    And when it is no longer needed a Destroy function needs           */+  /*    to be called to release that allocation.                           */+  /*    fcinit.c (ft_create_default_module_classes) already contains       */+  /*    a mechanism to call these functions for the default modules        */+  /*    described in ftmodule.h                                            */+  /*                                                                       */+  /*    Notice that the created Create and Destroy functions call          */+  /*    pic_init and pic_free function to allow you to manually allocate   */+  /*    and initialize any additional global data, like module specific    */+  /*    interface, and put them in the global pic container defined in     */+  /*    ftpic.h. if you don't need them just implement the functions as    */+  /*    empty to resolve the link error.                                   */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \+  a_, b_,+#else+  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)+#endif++#define FT_DECLARE_DRIVER(class_)    \+  FT_CALLBACK_TABLE                  \+  const FT_Driver_ClassRec  class_;  ++#define FT_DEFINE_DRIVER(class_,                                             \+                         flags_, size_, name_, version_, requires_,          \+                         interface_, init_, done_, get_interface_,           \+                         face_object_size_, size_object_size_,               \+                         slot_object_size_, init_face_, done_face_,          \+                         init_size_, done_size_, init_slot_, done_slot_,     \+                         old_set_char_sizes_, old_set_pixel_sizes_,          \+                         load_glyph_, get_kerning_, attach_file_,            \+                         get_advances_, request_size_, select_size_ )        \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_Driver_ClassRec class_ =                                          \+  {                                                                          \+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \+                          init_,done_,get_interface_)                        \+                                                                             \+    face_object_size_,                                                       \+    size_object_size_,                                                       \+    slot_object_size_,                                                       \+                                                                             \+    init_face_,                                                              \+    done_face_,                                                              \+                                                                             \+    init_size_,                                                              \+    done_size_,                                                              \+                                                                             \+    init_slot_,                                                              \+    done_slot_,                                                              \+                                                                             \+    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \+                                                                             \+    load_glyph_,                                                             \+                                                                             \+    get_kerning_,                                                            \+    attach_file_,                                                            \+    get_advances_,                                                           \+                                                                             \+    request_size_,                                                           \+    select_size_                                                             \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \+  clazz->set_char_sizes = a_; \+  clazz->set_pixel_sizes = b_;+#else+  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)+#endif++#define FT_DECLARE_DRIVER(class_)    FT_DECLARE_MODULE(class_)++#define FT_DEFINE_DRIVER(class_,                                             \+                         flags_, size_, name_, version_, requires_,          \+                         interface_, init_, done_, get_interface_,           \+                         face_object_size_, size_object_size_,               \+                         slot_object_size_, init_face_, done_face_,          \+                         init_size_, done_size_, init_slot_, done_slot_,     \+                         old_set_char_sizes_, old_set_pixel_sizes_,          \+                         load_glyph_, get_kerning_, attach_file_,            \+                         get_advances_, request_size_, select_size_ )        \+  void class_##_pic_free( FT_Library library );                              \+  FT_Error class_##_pic_init( FT_Library library );                          \+                                                                             \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library        library,                      \+                             FT_Module_Class*  clazz )                       \+  {                                                                          \+    FT_Memory       memory = library->memory;                                \+    FT_Driver_Class dclazz = (FT_Driver_Class)clazz;                         \+    class_##_pic_free( library );                                            \+    if ( dclazz )                                                            \+      FT_FREE( dclazz );                                                     \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library        library,                       \+                            FT_Module_Class**  output_class )                \+  {                                                                          \+    FT_Driver_Class  clazz;                                                  \+    FT_Error         error;                                                  \+    FT_Memory        memory = library->memory;                               \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \+      return error;                                                          \+                                                                             \+    error = class_##_pic_init( library );                                    \+    if(error)                                                                \+    {                                                                        \+      FT_FREE( clazz );                                                      \+      return error;                                                          \+    }                                                                        \+                                                                             \+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \+                          init_,done_,get_interface_)                        \+                                                                             \+    clazz->face_object_size    = face_object_size_;                          \+    clazz->size_object_size    = size_object_size_;                          \+    clazz->slot_object_size    = slot_object_size_;                          \+                                                                             \+    clazz->init_face           = init_face_;                                 \+    clazz->done_face           = done_face_;                                 \+                                                                             \+    clazz->init_size           = init_size_;                                 \+    clazz->done_size           = done_size_;                                 \+                                                                             \+    clazz->init_slot           = init_slot_;                                 \+    clazz->done_slot           = done_slot_;                                 \+                                                                             \+    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \+                                                                             \+    clazz->load_glyph          = load_glyph_;                                \+                                                                             \+    clazz->get_kerning         = get_kerning_;                               \+    clazz->attach_file         = attach_file_;                               \+    clazz->get_advances        = get_advances_;                              \+                                                                             \+    clazz->request_size        = request_size_;                              \+    clazz->select_size         = select_size_;                               \+                                                                             \+    *output_class = (FT_Module_Class*)clazz;                                 \+    return FT_Err_Ok;                                                        \+  }                +++#endif /* FT_CONFIG_OPTION_PIC */++FT_END_HEADER++#endif /* __FTDRIVER_H__ */+++/* END */
+ include/freetype/internal/ftgloadr.h view
@@ -0,0 +1,168 @@+/***************************************************************************/+/*                                                                         */+/*  ftgloadr.h                                                             */+/*                                                                         */+/*    The FreeType glyph loader (specification).                           */+/*                                                                         */+/*  Copyright 2002, 2003, 2005, 2006 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTGLOADR_H__+#define __FTGLOADR_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_GlyphLoader                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The glyph loader is an internal object used to load several glyphs */+  /*    together (for example, in the case of composites).                 */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The glyph loader implementation is not part of the high-level API, */+  /*    hence the forward structure declaration.                           */+  /*                                                                       */+  typedef struct FT_GlyphLoaderRec_*  FT_GlyphLoader ;+++#if 0  /* moved to freetype.h in version 2.2 */+#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS          1+#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES      2+#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID        4+#define FT_SUBGLYPH_FLAG_SCALE                   8+#define FT_SUBGLYPH_FLAG_XY_SCALE             0x40+#define FT_SUBGLYPH_FLAG_2X2                  0x80+#define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200+#endif+++  typedef struct  FT_SubGlyphRec_+  {+    FT_Int     index;+    FT_UShort  flags;+    FT_Int     arg1;+    FT_Int     arg2;+    FT_Matrix  transform;++  } FT_SubGlyphRec;+++  typedef struct  FT_GlyphLoadRec_+  {+    FT_Outline   outline;       /* outline                   */+    FT_Vector*   extra_points;  /* extra points table        */+    FT_Vector*   extra_points2; /* second extra points table */+    FT_UInt      num_subglyphs; /* number of subglyphs       */+    FT_SubGlyph  subglyphs;     /* subglyphs                 */++  } FT_GlyphLoadRec, *FT_GlyphLoad;+++  typedef struct  FT_GlyphLoaderRec_+  {+    FT_Memory        memory;+    FT_UInt          max_points;+    FT_UInt          max_contours;+    FT_UInt          max_subglyphs;+    FT_Bool          use_extra;++    FT_GlyphLoadRec  base;+    FT_GlyphLoadRec  current;++    void*            other;            /* for possible future extension? */++  } FT_GlyphLoaderRec;+++  /* create new empty glyph loader */+  FT_BASE( FT_Error )+  FT_GlyphLoader_New( FT_Memory        memory,+                      FT_GlyphLoader  *aloader );++  /* add an extra points table to a glyph loader */+  FT_BASE( FT_Error )+  FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader );++  /* destroy a glyph loader */+  FT_BASE( void )+  FT_GlyphLoader_Done( FT_GlyphLoader  loader );++  /* reset a glyph loader (frees everything int it) */+  FT_BASE( void )+  FT_GlyphLoader_Reset( FT_GlyphLoader  loader );++  /* rewind a glyph loader */+  FT_BASE( void )+  FT_GlyphLoader_Rewind( FT_GlyphLoader  loader );++  /* check that there is enough space to add `n_points' and `n_contours' */+  /* to the glyph loader                                                 */+  FT_BASE( FT_Error )+  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,+                              FT_UInt         n_points,+                              FT_UInt         n_contours );+++#define FT_GLYPHLOADER_CHECK_P( _loader, _count )                         \+   ( (_count) == 0 || ((_loader)->base.outline.n_points    +              \+                       (_loader)->current.outline.n_points +              \+                       (unsigned long)(_count)) <= (_loader)->max_points )++#define FT_GLYPHLOADER_CHECK_C( _loader, _count )                          \+  ( (_count) == 0 || ((_loader)->base.outline.n_contours    +              \+                      (_loader)->current.outline.n_contours +              \+                      (unsigned long)(_count)) <= (_loader)->max_contours )++#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours )      \+  ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points )   &&                  \+      FT_GLYPHLOADER_CHECK_C( _loader, _contours ) )                   \+    ? 0                                                                \+    : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) )+++  /* check that there is enough space to add `n_subs' sub-glyphs to */+  /* a glyph loader                                                 */+  FT_BASE( FT_Error )+  FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,+                                 FT_UInt         n_subs );++  /* prepare a glyph loader, i.e. empty the current glyph */+  FT_BASE( void )+  FT_GlyphLoader_Prepare( FT_GlyphLoader  loader );++  /* add the current glyph to the base glyph */+  FT_BASE( void )+  FT_GlyphLoader_Add( FT_GlyphLoader  loader );++  /* copy points from one glyph loader to another */+  FT_BASE( FT_Error )+  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,+                             FT_GlyphLoader  source );++ /* */+++FT_END_HEADER++#endif /* __FTGLOADR_H__ */+++/* END */
+ include/freetype/internal/ftmemory.h view
@@ -0,0 +1,380 @@+/***************************************************************************/+/*                                                                         */+/*  ftmemory.h                                                             */+/*                                                                         */+/*    The FreeType memory management macros (specification).               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2010 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTMEMORY_H__+#define __FTMEMORY_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_TYPES_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_SET_ERROR                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This macro is used to set an implicit `error' variable to a given  */+  /*    expression's value (usually a function call), and convert it to a  */+  /*    boolean which is set whenever the value is != 0.                   */+  /*                                                                       */+#undef  FT_SET_ERROR+#define FT_SET_ERROR( expression ) \+          ( ( error = (expression) ) != 0 )++++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                           M E M O R Y                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*+   *  C++ refuses to handle statements like p = (void*)anything, with `p' a+   *  typed pointer.  Since we don't have a `typeof' operator in standard+   *  C++, we have to use a template to emulate it.+   */++#ifdef __cplusplus++  extern "C++"+  template <typename T> inline T*+  cplusplus_typeof(        T*,+                    void  *v )+  {+    return static_cast <T*> ( v );+  }++#define FT_ASSIGNP( p, val )  (p) = cplusplus_typeof( (p), (val) )++#else++#define FT_ASSIGNP( p, val )  (p) = (val)++#endif++++#ifdef FT_DEBUG_MEMORY++  FT_BASE( const char* )  _ft_debug_file;+  FT_BASE( long )         _ft_debug_lineno;++#define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \+                                 _ft_debug_lineno = __LINE__, \+                                 (exp) )++#define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \+                                      _ft_debug_lineno = __LINE__, \+                                      FT_ASSIGNP( p, exp ) )++#else /* !FT_DEBUG_MEMORY */++#define FT_DEBUG_INNER( exp )       (exp)+#define FT_ASSIGNP_INNER( p, exp )  FT_ASSIGNP( p, exp )++#endif /* !FT_DEBUG_MEMORY */+++  /*+   *  The allocation functions return a pointer, and the error code+   *  is written to through the `p_error' parameter.  See below for+   *  for documentation.+   */++  FT_BASE( FT_Pointer )+  ft_mem_alloc( FT_Memory  memory,+                FT_Long    size,+                FT_Error  *p_error );++  FT_BASE( FT_Pointer )+  ft_mem_qalloc( FT_Memory  memory,+                 FT_Long    size,+                 FT_Error  *p_error );++  FT_BASE( FT_Pointer )+  ft_mem_realloc( FT_Memory  memory,+                  FT_Long    item_size,+                  FT_Long    cur_count,+                  FT_Long    new_count,+                  void*      block,+                  FT_Error  *p_error );++  FT_BASE( FT_Pointer )+  ft_mem_qrealloc( FT_Memory  memory,+                   FT_Long    item_size,+                   FT_Long    cur_count,+                   FT_Long    new_count,+                   void*      block,+                   FT_Error  *p_error );++  FT_BASE( void )+  ft_mem_free( FT_Memory    memory,+               const void*  P );+++#define FT_MEM_ALLOC( ptr, size )                                         \+          FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) )++#define FT_MEM_FREE( ptr )                \+          FT_BEGIN_STMNT                  \+            ft_mem_free( memory, (ptr) ); \+            (ptr) = NULL;                 \+          FT_END_STMNT++#define FT_MEM_NEW( ptr )                        \+          FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) )++#define FT_MEM_REALLOC( ptr, cursz, newsz )                        \+          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1,        \+                                                 (cursz), (newsz), \+                                                 (ptr), &error ) )++#define FT_MEM_QALLOC( ptr, size )                                         \+          FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) )++#define FT_MEM_QNEW( ptr )                        \+          FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) )++#define FT_MEM_QREALLOC( ptr, cursz, newsz )                         \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1,        \+                                                  (cursz), (newsz), \+                                                  (ptr), &error ) )++#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \+                                                  (cursz), (newsz),          \+                                                  (ptr), &error ) )++#define FT_MEM_ALLOC_MULT( ptr, count, item_size )                    \+          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \+                                                 0, (count),          \+                                                 NULL, &error ) )++#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )            \+          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz),    \+                                                 (oldcnt), (newcnt), \+                                                 (ptr), &error ) )++#define FT_MEM_QALLOC_MULT( ptr, count, item_size )                    \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \+                                                  0, (count),          \+                                                  NULL, &error ) )++#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz)             \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz),    \+                                                  (oldcnt), (newcnt), \+                                                  (ptr), &error ) )+++#define FT_MEM_SET_ERROR( cond )  ( (cond), error != 0 )+++#define FT_MEM_SET( dest, byte, count )     ft_memset( dest, byte, count )++#define FT_MEM_COPY( dest, source, count )  ft_memcpy( dest, source, count )++#define FT_MEM_MOVE( dest, source, count )  ft_memmove( dest, source, count )+++#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )++#define FT_ZERO( p )                FT_MEM_ZERO( p, sizeof ( *(p) ) )+++#define FT_ARRAY_ZERO( dest, count )                        \+          FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )++#define FT_ARRAY_COPY( dest, source, count )                        \+          FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )++#define FT_ARRAY_MOVE( dest, source, count )                        \+          FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )+++  /*+   *  Return the maximum number of addressable elements in an array.+   *  We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid+   *  any problems.+   */+#define FT_ARRAY_MAX( ptr )           ( FT_INT_MAX / sizeof ( *(ptr) ) )++#define FT_ARRAY_CHECK( ptr, count )  ( (count) <= FT_ARRAY_MAX( ptr ) )+++  /*************************************************************************/+  /*                                                                       */+  /* The following functions macros expect that their pointer argument is  */+  /* _typed_ in order to automatically compute array element sizes.        */+  /*                                                                       */++#define FT_MEM_NEW_ARRAY( ptr, count )                                      \+          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \+                                                 0, (count),                \+                                                 NULL, &error ) )++#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz )                             \+          FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \+                                                 (cursz), (newsz),          \+                                                 (ptr), &error ) )++#define FT_MEM_QNEW_ARRAY( ptr, count )                                      \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \+                                                  0, (count),                \+                                                  NULL, &error ) )++#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                             \+          FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \+                                                  (cursz), (newsz),          \+                                                  (ptr), &error ) )+++#define FT_ALLOC( ptr, size )                           \+          FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) )++#define FT_REALLOC( ptr, cursz, newsz )                           \+          FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) )++#define FT_ALLOC_MULT( ptr, count, item_size )                           \+          FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) )++#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \+          FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt,      \+                                                 newcnt, itmsz ) )++#define FT_QALLOC( ptr, size )                           \+          FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) )++#define FT_QREALLOC( ptr, cursz, newsz )                           \+          FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) )++#define FT_QALLOC_MULT( ptr, count, item_size )                           \+          FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) )++#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \+          FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt,      \+                                                  newcnt, itmsz ) )++#define FT_FREE( ptr )  FT_MEM_FREE( ptr )++#define FT_NEW( ptr )  FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) )++#define FT_NEW_ARRAY( ptr, count )                           \+          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )++#define FT_RENEW_ARRAY( ptr, curcnt, newcnt )                           \+          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )++#define FT_QNEW( ptr )                           \+          FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )++#define FT_QNEW_ARRAY( ptr, count )                          \+          FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )++#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                          \+          FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_BASE( FT_Error )+  FT_Alloc( FT_Memory  memory,+            FT_Long    size,+            void*     *P );++  FT_BASE( FT_Error )+  FT_QAlloc( FT_Memory  memory,+             FT_Long    size,+             void*     *p );++  FT_BASE( FT_Error )+  FT_Realloc( FT_Memory  memory,+              FT_Long    current,+              FT_Long    size,+              void*     *P );++  FT_BASE( FT_Error )+  FT_QRealloc( FT_Memory  memory,+               FT_Long    current,+               FT_Long    size,+               void*     *p );++  FT_BASE( void )+  FT_Free( FT_Memory  memory,+           void*     *P );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  FT_BASE( FT_Pointer )+  ft_mem_strdup( FT_Memory    memory,+                 const char*  str,+                 FT_Error    *p_error );++  FT_BASE( FT_Pointer )+  ft_mem_dup( FT_Memory    memory,+              const void*  address,+              FT_ULong     size,+              FT_Error    *p_error );++#define FT_MEM_STRDUP( dst, str )                                            \+          (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error )++#define FT_STRDUP( dst, str )                           \+          FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) )++#define FT_MEM_DUP( dst, address, size )                                    \+          (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error )++#define FT_DUP( dst, address, size )                           \+          FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) )+++  /* Return >= 1 if a truncation occurs.            */+  /* Return 0 if the source string fits the buffer. */+  /* This is *not* the same as strlcpy().           */+  FT_BASE( FT_Int )+  ft_mem_strcpyn( char*        dst,+                  const char*  src,+                  FT_ULong     size );++#define FT_STRCPYN( dst, src, size )                                         \+          ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) )++ /* */+++FT_END_HEADER++#endif /* __FTMEMORY_H__ */+++/* END */
+ include/freetype/internal/ftobjs.h view
@@ -0,0 +1,1428 @@+/***************************************************************************/+/*                                                                         */+/*  ftobjs.h                                                               */+/*                                                                         */+/*    The FreeType private base classes (specification).                   */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /*  This file contains the definition of all internal FreeType classes.  */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTOBJS_H__+#define __FTOBJS_H__++#include <ft2build.h>+#include FT_RENDER_H+#include FT_SIZES_H+#include FT_LCD_FILTER_H+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_GLYPH_LOADER_H+#include FT_INTERNAL_DRIVER_H+#include FT_INTERNAL_AUTOHINT_H+#include FT_INTERNAL_SERVICE_H+#include FT_INTERNAL_PIC_H++#ifdef FT_CONFIG_OPTION_INCREMENTAL+#include FT_INCREMENTAL_H+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* Some generic definitions.                                             */+  /*                                                                       */+#ifndef TRUE+#define TRUE  1+#endif++#ifndef FALSE+#define FALSE  0+#endif++#ifndef NULL+#define NULL  (void*)0+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* The min and max functions missing in C.  As usual, be careful not to  */+  /* write things like FT_MIN( a++, b++ ) to avoid side effects.           */+  /*                                                                       */+#define FT_MIN( a, b )  ( (a) < (b) ? (a) : (b) )+#define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )++#define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )+++#define FT_PAD_FLOOR( x, n )  ( (x) & ~((n)-1) )+#define FT_PAD_ROUND( x, n )  FT_PAD_FLOOR( (x) + ((n)/2), n )+#define FT_PAD_CEIL( x, n )   FT_PAD_FLOOR( (x) + ((n)-1), n )++#define FT_PIX_FLOOR( x )     ( (x) & ~63 )+#define FT_PIX_ROUND( x )     FT_PIX_FLOOR( (x) + 32 )+#define FT_PIX_CEIL( x )      FT_PIX_FLOOR( (x) + 63 )+++  /*+   *  Return the highest power of 2 that is <= value; this correspond to+   *  the highest bit in a given 32-bit value.+   */+  FT_BASE( FT_UInt32 )+  ft_highpow2( FT_UInt32  value );+++  /*+   *  character classification functions -- since these are used to parse+   *  font files, we must not use those in <ctypes.h> which are+   *  locale-dependent+   */+#define  ft_isdigit( x )   ( ( (unsigned)(x) - '0' ) < 10U )++#define  ft_isxdigit( x )  ( ( (unsigned)(x) - '0' ) < 10U || \+                             ( (unsigned)(x) - 'a' ) < 6U  || \+                             ( (unsigned)(x) - 'A' ) < 6U  )++  /* the next two macros assume ASCII representation */+#define  ft_isupper( x )  ( ( (unsigned)(x) - 'A' ) < 26U )+#define  ft_islower( x )  ( ( (unsigned)(x) - 'a' ) < 26U )++#define  ft_isalpha( x )  ( ft_isupper( x ) || ft_islower( x ) )+#define  ft_isalnum( x )  ( ft_isdigit( x ) || ft_isalpha( x ) )+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                       C H A R M A P S                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /* handle to internal charmap object */+  typedef struct FT_CMapRec_*              FT_CMap;++  /* handle to charmap class structure */+  typedef const struct FT_CMap_ClassRec_*  FT_CMap_Class;++  /* internal charmap object structure */+  typedef struct  FT_CMapRec_+  {+    FT_CharMapRec  charmap;+    FT_CMap_Class  clazz;++  } FT_CMapRec;++  /* typecase any pointer to a charmap handle */+#define FT_CMAP( x )              ((FT_CMap)( x ))++  /* obvious macros */+#define FT_CMAP_PLATFORM_ID( x )  FT_CMAP( x )->charmap.platform_id+#define FT_CMAP_ENCODING_ID( x )  FT_CMAP( x )->charmap.encoding_id+#define FT_CMAP_ENCODING( x )     FT_CMAP( x )->charmap.encoding+#define FT_CMAP_FACE( x )         FT_CMAP( x )->charmap.face+++  /* class method definitions */+  typedef FT_Error+  (*FT_CMap_InitFunc)( FT_CMap     cmap,+                       FT_Pointer  init_data );++  typedef void+  (*FT_CMap_DoneFunc)( FT_CMap  cmap );++  typedef FT_UInt+  (*FT_CMap_CharIndexFunc)( FT_CMap    cmap,+                            FT_UInt32  char_code );++  typedef FT_UInt+  (*FT_CMap_CharNextFunc)( FT_CMap     cmap,+                           FT_UInt32  *achar_code );++  typedef FT_UInt+  (*FT_CMap_CharVarIndexFunc)( FT_CMap    cmap,+                               FT_CMap    unicode_cmap,+                               FT_UInt32  char_code,+                               FT_UInt32  variant_selector );++  typedef FT_Bool+  (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap    cmap,+                                   FT_UInt32  char_code,+                                   FT_UInt32  variant_selector );++  typedef FT_UInt32 *+  (*FT_CMap_VariantListFunc)( FT_CMap    cmap,+                              FT_Memory  mem );++  typedef FT_UInt32 *+  (*FT_CMap_CharVariantListFunc)( FT_CMap    cmap,+                                  FT_Memory  mem,+                                  FT_UInt32  char_code );++  typedef FT_UInt32 *+  (*FT_CMap_VariantCharListFunc)( FT_CMap    cmap,+                                  FT_Memory  mem,+                                  FT_UInt32  variant_selector );+++  typedef struct  FT_CMap_ClassRec_+  {+    FT_ULong               size;+    FT_CMap_InitFunc       init;+    FT_CMap_DoneFunc       done;+    FT_CMap_CharIndexFunc  char_index;+    FT_CMap_CharNextFunc   char_next;++    /* Subsequent entries are special ones for format 14 -- the variant */+    /* selector subtable which behaves like no other                    */++    FT_CMap_CharVarIndexFunc      char_var_index;+    FT_CMap_CharVarIsDefaultFunc  char_var_default;+    FT_CMap_VariantListFunc       variant_list;+    FT_CMap_CharVariantListFunc   charvariant_list;+    FT_CMap_VariantCharListFunc   variantchar_list;++  } FT_CMap_ClassRec;++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DECLARE_CMAP_CLASS(class_) \+    FT_CALLBACK_TABLE const FT_CMap_ClassRec class_;++#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \+        char_next_, char_var_index_, char_var_default_, variant_list_,       \+        charvariant_list_, variantchar_list_)                                \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_CMap_ClassRec class_ =                                            \+  {                                                                          \+    size_, init_, done_, char_index_, char_next_, char_var_index_,           \+    char_var_default_, variant_list_, charvariant_list_, variantchar_list_   \+  };+#else /* FT_CONFIG_OPTION_PIC */++#define FT_DECLARE_CMAP_CLASS(class_) \+    void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec*  clazz);++#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \+        char_next_, char_var_index_, char_var_default_, variant_list_,       \+        charvariant_list_, variantchar_list_)                                \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library,                                \+                          FT_CMap_ClassRec*  clazz)                          \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    clazz->size = size_;                                                     \+    clazz->init = init_;                                                     \+    clazz->done = done_;                                                     \+    clazz->char_index = char_index_;                                         \+    clazz->char_next = char_next_;                                           \+    clazz->char_var_index = char_var_index_;                                 \+    clazz->char_var_default = char_var_default_;                             \+    clazz->variant_list = variant_list_;                                     \+    clazz->charvariant_list = charvariant_list_;                             \+    clazz->variantchar_list = variantchar_list_;                             \+  } +#endif /* FT_CONFIG_OPTION_PIC */++  /* create a new charmap and add it to charmap->face */+  FT_BASE( FT_Error )+  FT_CMap_New( FT_CMap_Class  clazz,+               FT_Pointer     init_data,+               FT_CharMap     charmap,+               FT_CMap       *acmap );++  /* destroy a charmap and remove it from face's list */+  FT_BASE( void )+  FT_CMap_Done( FT_CMap  cmap );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Face_InternalRec                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure contains the internal fields of each FT_Face        */+  /*    object.  These fields may change between different releases of     */+  /*    FreeType.                                                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    max_points ::                                                      */+  /*      The maximal number of points used to store the vectorial outline */+  /*      of any glyph in this face.  If this value cannot be known in     */+  /*      advance, or if the face isn't scalable, this should be set to 0. */+  /*      Only relevant for scalable formats.                              */+  /*                                                                       */+  /*    max_contours ::                                                    */+  /*      The maximal number of contours used to store the vectorial       */+  /*      outline of any glyph in this face.  If this value cannot be      */+  /*      known in advance, or if the face isn't scalable, this should be  */+  /*      set to 0.  Only relevant for scalable formats.                   */+  /*                                                                       */+  /*    transform_matrix ::                                                */+  /*      A 2x2 matrix of 16.16 coefficients used to transform glyph       */+  /*      outlines after they are loaded from the font.  Only used by the  */+  /*      convenience functions.                                           */+  /*                                                                       */+  /*    transform_delta ::                                                 */+  /*      A translation vector used to transform glyph outlines after they */+  /*      are loaded from the font.  Only used by the convenience          */+  /*      functions.                                                       */+  /*                                                                       */+  /*    transform_flags ::                                                 */+  /*      Some flags used to classify the transform.  Only used by the     */+  /*      convenience functions.                                           */+  /*                                                                       */+  /*    services ::                                                        */+  /*      A cache for frequently used services.  It should be only         */+  /*      accessed with the macro `FT_FACE_LOOKUP_SERVICE'.                */+  /*                                                                       */+  /*    incremental_interface ::                                           */+  /*      If non-null, the interface through which glyph data and metrics  */+  /*      are loaded incrementally for faces that do not provide all of    */+  /*      this data when first opened.  This field exists only if          */+  /*      @FT_CONFIG_OPTION_INCREMENTAL is defined.                        */+  /*                                                                       */+  /*    ignore_unpatented_hinter ::                                        */+  /*      This boolean flag instructs the glyph loader to ignore the       */+  /*      native font hinter, if one is found.  This is exclusively used   */+  /*      in the case when the unpatented hinter is compiled within the    */+  /*      library.                                                         */+  /*                                                                       */+  /*    refcount ::                                                        */+  /*      A counter initialized to~1 at the time an @FT_Face structure is  */+  /*      created.  @FT_Reference_Face increments this counter, and        */+  /*      @FT_Done_Face only destroys a face if the counter is~1,          */+  /*      otherwise it simply decrements it.                               */+  /*                                                                       */+  typedef struct  FT_Face_InternalRec_+  {+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    FT_UShort           reserved1;+    FT_Short            reserved2;+#endif+    FT_Matrix           transform_matrix;+    FT_Vector           transform_delta;+    FT_Int              transform_flags;++    FT_ServiceCacheRec  services;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    FT_Incremental_InterfaceRec*  incremental_interface;+#endif++    FT_Bool             ignore_unpatented_hinter;+    FT_UInt             refcount;++  } FT_Face_InternalRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Slot_InternalRec                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure contains the internal fields of each FT_GlyphSlot   */+  /*    object.  These fields may change between different releases of     */+  /*    FreeType.                                                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    loader            :: The glyph loader object used to load outlines */+  /*                         into the glyph slot.                          */+  /*                                                                       */+  /*    flags             :: Possible values are zero or                   */+  /*                         FT_GLYPH_OWN_BITMAP.  The latter indicates    */+  /*                         that the FT_GlyphSlot structure owns the      */+  /*                         bitmap buffer.                                */+  /*                                                                       */+  /*    glyph_transformed :: Boolean.  Set to TRUE when the loaded glyph   */+  /*                         must be transformed through a specific        */+  /*                         font transformation.  This is _not_ the same  */+  /*                         as the face transform set through             */+  /*                         FT_Set_Transform().                           */+  /*                                                                       */+  /*    glyph_matrix      :: The 2x2 matrix corresponding to the glyph     */+  /*                         transformation, if necessary.                 */+  /*                                                                       */+  /*    glyph_delta       :: The 2d translation vector corresponding to    */+  /*                         the glyph transformation, if necessary.       */+  /*                                                                       */+  /*    glyph_hints       :: Format-specific glyph hints management.       */+  /*                                                                       */++#define FT_GLYPH_OWN_BITMAP  0x1++  typedef struct  FT_Slot_InternalRec_+  {+    FT_GlyphLoader  loader;+    FT_UInt         flags;+    FT_Bool         glyph_transformed;+    FT_Matrix       glyph_matrix;+    FT_Vector       glyph_delta;+    void*           glyph_hints;++  } FT_GlyphSlot_InternalRec;+++#if 0++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_Size_InternalRec                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure contains the internal fields of each FT_Size        */+  /*    object.  Currently, it's empty.                                    */+  /*                                                                       */+  /*************************************************************************/++  typedef struct  FT_Size_InternalRec_+  {+    /* empty */++  } FT_Size_InternalRec;++#endif+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                         M O D U L E S                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_ModuleRec                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A module object instance.                                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    clazz   :: A pointer to the module's class.                        */+  /*                                                                       */+  /*    library :: A handle to the parent library object.                  */+  /*                                                                       */+  /*    memory  :: A handle to the memory manager.                         */+  /*                                                                       */+  /*    generic :: A generic structure for user-level extensibility (?).   */+  /*                                                                       */+  typedef struct  FT_ModuleRec_+  {+    FT_Module_Class*  clazz;+    FT_Library        library;+    FT_Memory         memory;+    FT_Generic        generic;++  } FT_ModuleRec;+++  /* typecast an object to a FT_Module */+#define FT_MODULE( x )          ((FT_Module)( x ))+#define FT_MODULE_CLASS( x )    FT_MODULE( x )->clazz+#define FT_MODULE_LIBRARY( x )  FT_MODULE( x )->library+#define FT_MODULE_MEMORY( x )   FT_MODULE( x )->memory+++#define FT_MODULE_IS_DRIVER( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                    FT_MODULE_FONT_DRIVER )++#define FT_MODULE_IS_RENDERER( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                      FT_MODULE_RENDERER )++#define FT_MODULE_IS_HINTER( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                    FT_MODULE_HINTER )++#define FT_MODULE_IS_STYLER( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                    FT_MODULE_STYLER )++#define FT_DRIVER_IS_SCALABLE( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                      FT_MODULE_DRIVER_SCALABLE )++#define FT_DRIVER_USES_OUTLINES( x )  !( FT_MODULE_CLASS( x )->module_flags & \+                                         FT_MODULE_DRIVER_NO_OUTLINES )++#define FT_DRIVER_HAS_HINTER( x )  ( FT_MODULE_CLASS( x )->module_flags & \+                                     FT_MODULE_DRIVER_HAS_HINTER )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Module_Interface                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finds a module and returns its specific interface as a typeless    */+  /*    pointer.                                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library     :: A handle to the library object.                     */+  /*                                                                       */+  /*    module_name :: The module's name (as an ASCII string).             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A module-specific interface if available, 0 otherwise.             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    You should better be familiar with FreeType internals to know      */+  /*    which module to look for, and what its interface is :-)            */+  /*                                                                       */+  FT_BASE( const void* )+  FT_Get_Module_Interface( FT_Library   library,+                           const char*  mod_name );++  FT_BASE( FT_Pointer )+  ft_module_get_service( FT_Module    module,+                         const char*  service_id );++ /* */+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /* a few macros used to perform easy typecasts with minimal brain damage */++#define FT_FACE( x )          ((FT_Face)(x))+#define FT_SIZE( x )          ((FT_Size)(x))+#define FT_SLOT( x )          ((FT_GlyphSlot)(x))++#define FT_FACE_DRIVER( x )   FT_FACE( x )->driver+#define FT_FACE_LIBRARY( x )  FT_FACE_DRIVER( x )->root.library+#define FT_FACE_MEMORY( x )   FT_FACE( x )->memory+#define FT_FACE_STREAM( x )   FT_FACE( x )->stream++#define FT_SIZE_FACE( x )     FT_SIZE( x )->face+#define FT_SLOT_FACE( x )     FT_SLOT( x )->face++#define FT_FACE_SLOT( x )     FT_FACE( x )->glyph+#define FT_FACE_SIZE( x )     FT_FACE( x )->size+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_GlyphSlot                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    It is sometimes useful to have more than one glyph slot for a      */+  /*    given face object.  This function is used to create additional     */+  /*    slots.  All of them are automatically discarded when the face is   */+  /*    destroyed.                                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face  :: A handle to a parent face object.                         */+  /*                                                                       */+  /* <Output>                                                              */+  /*    aslot :: A handle to a new glyph slot object.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_BASE( FT_Error )+  FT_New_GlyphSlot( FT_Face        face,+                    FT_GlyphSlot  *aslot );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_GlyphSlot                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroys a given glyph slot.  Remember however that all slots are  */+  /*    automatically destroyed with its parent.  Using this function is   */+  /*    not always mandatory.                                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    slot :: A handle to a target glyph slot.                           */+  /*                                                                       */+  FT_BASE( void )+  FT_Done_GlyphSlot( FT_GlyphSlot  slot );++ /* */++#define FT_REQUEST_WIDTH( req )                                            \+          ( (req)->horiResolution                                          \+              ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \+              : (req)->width )++#define FT_REQUEST_HEIGHT( req )                                            \+          ( (req)->vertResolution                                           \+              ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \+              : (req)->height )+++  /* Set the metrics according to a bitmap strike. */+  FT_BASE( void )+  FT_Select_Metrics( FT_Face   face,+                     FT_ULong  strike_index );+++  /* Set the metrics according to a size request. */+  FT_BASE( void )+  FT_Request_Metrics( FT_Face          face,+                      FT_Size_Request  req );+++  /* Match a size request against `available_sizes'. */+  FT_BASE( FT_Error )+  FT_Match_Size( FT_Face          face,+                 FT_Size_Request  req,+                 FT_Bool          ignore_width,+                 FT_ULong*        size_index );+++  /* Use the horizontal metrics to synthesize the vertical metrics. */+  /* If `advance' is zero, it is also synthesized.                  */+  FT_BASE( void )+  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,+                                  FT_Pos             advance );+++  /* Free the bitmap of a given glyphslot when needed (i.e., only when it */+  /* was allocated with ft_glyphslot_alloc_bitmap).                       */+  FT_BASE( void )+  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot );+++  /* Allocate a new bitmap buffer in a glyph slot. */+  FT_BASE( FT_Error )+  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,+                             FT_ULong      size );+++  /* Set the bitmap buffer in a glyph slot to a given pointer.  The buffer */+  /* will not be freed by a later call to ft_glyphslot_free_bitmap.        */+  FT_BASE( void )+  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,+                           FT_Byte*      buffer );+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                        R E N D E R E R S                        ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#define FT_RENDERER( x )      ((FT_Renderer)( x ))+#define FT_GLYPH( x )         ((FT_Glyph)( x ))+#define FT_BITMAP_GLYPH( x )  ((FT_BitmapGlyph)( x ))+#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x ))+++  typedef struct  FT_RendererRec_+  {+    FT_ModuleRec            root;+    FT_Renderer_Class*      clazz;+    FT_Glyph_Format         glyph_format;+    FT_Glyph_Class          glyph_class;++    FT_Raster               raster;+    FT_Raster_Render_Func   raster_render;+    FT_Renderer_RenderFunc  render;++  } FT_RendererRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                    F O N T   D R I V E R S                      ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* typecast a module into a driver easily */+#define FT_DRIVER( x )        ((FT_Driver)(x))++  /* typecast a module as a driver, and get its driver class */+#define FT_DRIVER_CLASS( x )  FT_DRIVER( x )->clazz+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_DriverRec                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The root font driver class.  A font driver is responsible for      */+  /*    managing and loading font files of a given format.                 */+  /*                                                                       */+  /*  <Fields>                                                             */+  /*     root         :: Contains the fields of the root module class.     */+  /*                                                                       */+  /*     clazz        :: A pointer to the font driver's class.  Note that  */+  /*                     this is NOT root.clazz.  `class' wasn't used      */+  /*                     as it is a reserved word in C++.                  */+  /*                                                                       */+  /*     faces_list   :: The list of faces currently opened by this        */+  /*                     driver.                                           */+  /*                                                                       */+  /*     extensions   :: A typeless pointer to the driver's extensions     */+  /*                     registry, if they are supported through the       */+  /*                     configuration macro FT_CONFIG_OPTION_EXTENSIONS.  */+  /*                                                                       */+  /*     glyph_loader :: The glyph loader for all faces managed by this    */+  /*                     driver.  This object isn't defined for unscalable */+  /*                     formats.                                          */+  /*                                                                       */+  typedef struct  FT_DriverRec_+  {+    FT_ModuleRec     root;+    FT_Driver_Class  clazz;++    FT_ListRec       faces_list;+    void*            extensions;++    FT_GlyphLoader   glyph_loader;++  } FT_DriverRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                       L I B R A R I E S                         ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* This hook is used by the TrueType debugger.  It must be set to an */+  /* alternate truetype bytecode interpreter function.                 */+#define FT_DEBUG_HOOK_TRUETYPE            0+++  /* Set this debug hook to a non-null pointer to force unpatented hinting */+  /* for all faces when both TT_USE_BYTECODE_INTERPRETER and               */+  /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined.  This is only used   */+  /* during debugging.                                                     */+#define FT_DEBUG_HOOK_UNPATENTED_HINTING  1+++  typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,+                                            FT_Render_Mode  render_mode,+                                            FT_Library      library );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    FT_LibraryRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The FreeType library class.  This is the root of all FreeType      */+  /*    data.  Use FT_New_Library() to create a library object, and        */+  /*    FT_Done_Library() to discard it and all child objects.             */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    memory           :: The library's memory object.  Manages memory   */+  /*                        allocation.                                    */+  /*                                                                       */+  /*    generic          :: Client data variable.  Used to extend the      */+  /*                        Library class by higher levels and clients.    */+  /*                                                                       */+  /*    version_major    :: The major version number of the library.       */+  /*                                                                       */+  /*    version_minor    :: The minor version number of the library.       */+  /*                                                                       */+  /*    version_patch    :: The current patch level of the library.        */+  /*                                                                       */+  /*    num_modules      :: The number of modules currently registered     */+  /*                        within this library.  This is set to 0 for new */+  /*                        libraries.  New modules are added through the  */+  /*                        FT_Add_Module() API function.                  */+  /*                                                                       */+  /*    modules          :: A table used to store handles to the currently */+  /*                        registered modules. Note that each font driver */+  /*                        contains a list of its opened faces.           */+  /*                                                                       */+  /*    renderers        :: The list of renderers currently registered     */+  /*                        within the library.                            */+  /*                                                                       */+  /*    cur_renderer     :: The current outline renderer.  This is a       */+  /*                        shortcut used to avoid parsing the list on     */+  /*                        each call to FT_Outline_Render().  It is a     */+  /*                        handle to the current renderer for the         */+  /*                        FT_GLYPH_FORMAT_OUTLINE format.                */+  /*                                                                       */+  /*    auto_hinter      :: XXX                                            */+  /*                                                                       */+  /*    raster_pool      :: The raster object's render pool.  This can     */+  /*                        ideally be changed dynamically at run-time.    */+  /*                                                                       */+  /*    raster_pool_size :: The size of the render pool in bytes.          */+  /*                                                                       */+  /*    debug_hooks      :: XXX                                            */+  /*                                                                       */+  /*    lcd_filter       :: If subpixel rendering is activated, the        */+  /*                        selected LCD filter mode.                      */+  /*                                                                       */+  /*    lcd_extra        :: If subpixel rendering is activated, the number */+  /*                        of extra pixels needed for the LCD filter.     */+  /*                                                                       */+  /*    lcd_weights      :: If subpixel rendering is activated, the LCD    */+  /*                        filter weights, if any.                        */+  /*                                                                       */+  /*    lcd_filter_func  :: If subpixel rendering is activated, the LCD    */+  /*                        filtering callback function.                   */+  /*                                                                       */+  /*    pic_container    :: Contains global structs and tables, instead    */+  /*                        of defining them globallly.                    */+  /*                                                                       */+  /*    refcount         :: A counter initialized to~1 at the time an      */+  /*                        @FT_Library structure is created.              */+  /*                        @FT_Reference_Library increments this counter, */+  /*                        and @FT_Done_Library only destroys a library   */+  /*                        if the counter is~1, otherwise it simply       */+  /*                        decrements it.                                 */+  /*                                                                       */+  typedef struct  FT_LibraryRec_+  {+    FT_Memory          memory;           /* library's memory manager */++    FT_Generic         generic;++    FT_Int             version_major;+    FT_Int             version_minor;+    FT_Int             version_patch;++    FT_UInt            num_modules;+    FT_Module          modules[FT_MAX_MODULES];  /* module objects  */++    FT_ListRec         renderers;        /* list of renderers        */+    FT_Renderer        cur_renderer;     /* current outline renderer */+    FT_Module          auto_hinter;++    FT_Byte*           raster_pool;      /* scan-line conversion */+                                         /* render pool          */+    FT_ULong           raster_pool_size; /* size of render pool in bytes */++    FT_DebugHook_Func  debug_hooks[4];++#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING+    FT_LcdFilter             lcd_filter;+    FT_Int                   lcd_extra;        /* number of extra pixels */+    FT_Byte                  lcd_weights[7];   /* filter weights, if any */+    FT_Bitmap_LcdFilterFunc  lcd_filter_func;  /* filtering callback     */+#endif++#ifdef FT_CONFIG_OPTION_PIC+    FT_PIC_Container   pic_container;+#endif++    FT_UInt            refcount;++  } FT_LibraryRec;+++  FT_BASE( FT_Renderer )+  FT_Lookup_Renderer( FT_Library       library,+                      FT_Glyph_Format  format,+                      FT_ListNode*     node );++  FT_BASE( FT_Error )+  FT_Render_Glyph_Internal( FT_Library      library,+                            FT_GlyphSlot    slot,+                            FT_Render_Mode  render_mode );++  typedef const char*+  (*FT_Face_GetPostscriptNameFunc)( FT_Face  face );++  typedef FT_Error+  (*FT_Face_GetGlyphNameFunc)( FT_Face     face,+                               FT_UInt     glyph_index,+                               FT_Pointer  buffer,+                               FT_UInt     buffer_max );++  typedef FT_UInt+  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face     face,+                                    FT_String*  glyph_name );+++#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Memory                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Creates a new memory object.                                       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A pointer to the new memory object.  0 in case of error.           */+  /*                                                                       */+  FT_BASE( FT_Memory )+  FT_New_Memory( void );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Done_Memory                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Discards memory manager.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory :: A handle to the memory manager.                          */+  /*                                                                       */+  FT_BASE( void )+  FT_Done_Memory( FT_Memory  memory );++#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */+++  /* Define default raster's interface.  The default raster is located in  */+  /* `src/base/ftraster.c'.                                                */+  /*                                                                       */+  /* Client applications can register new rasters through the              */+  /* FT_Set_Raster() API.                                                  */++#ifndef FT_NO_DEFAULT_RASTER+  FT_EXPORT_VAR( FT_Raster_Funcs )  ft_default_raster;+#endif++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****              PIC-Support Macros for ftimage.h                   ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_OUTLINE_FUNCS                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Outline_Funcs struct.         */+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */+  /*    called with a pre-allocated stracture to be filled.                */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \+                                cubic_to_, shift_, delta_)                   \+  static const FT_Outline_Funcs class_ =                                     \+  {                                                                          \+    move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_                 \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \+                                cubic_to_, shift_, delta_)                   \+  static FT_Error                                                            \+  Init_Class_##class_( FT_Outline_Funcs*  clazz )                            \+  {                                                                          \+    clazz->move_to = move_to_;                                               \+    clazz->line_to = line_to_;                                               \+    clazz->conic_to = conic_to_;                                             \+    clazz->cubic_to = cubic_to_;                                             \+    clazz->shift = shift_;                                                   \+    clazz->delta = delta_;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_RASTER_FUNCS                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Raster_Funcs struct.          */+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */+  /*    called with a pre-allocated stracture to be filled.                */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \+                               raster_reset_, raster_set_mode_,              \+                               raster_render_, raster_done_)                 \+  const FT_Raster_Funcs class_ =                                      \+  {                                                                          \+    glyph_format_, raster_new_, raster_reset_,                               \+    raster_set_mode_, raster_render_, raster_done_                           \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \+    raster_reset_, raster_set_mode_, raster_render_, raster_done_)           \+  void                                                                       \+  FT_Init_Class_##class_( FT_Raster_Funcs*  clazz )                          \+  {                                                                          \+    clazz->glyph_format = glyph_format_;                                     \+    clazz->raster_new = raster_new_;                                         \+    clazz->raster_reset = raster_reset_;                                     \+    clazz->raster_set_mode = raster_set_mode_;                               \+    clazz->raster_render = raster_render_;                                   \+    clazz->raster_done = raster_done_;                                       \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****              PIC-Support Macros for ftrender.h                  ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_GLYPH                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Glyph_Class struct.           */+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */+  /*    called with a pre-allocated stracture to be filled.                */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \+                        transform_, bbox_, prepare_)                         \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_Glyph_Class class_ =                                              \+  {                                                                          \+    size_, format_, init_, done_, copy_, transform_, bbox_, prepare_         \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \+                        transform_, bbox_, prepare_)                         \+  void                                                                       \+  FT_Init_Class_##class_( FT_Glyph_Class*  clazz )                           \+  {                                                                          \+    clazz->glyph_size = size_;                                               \+    clazz->glyph_format = format_;                                           \+    clazz->glyph_init = init_;                                               \+    clazz->glyph_done = done_;                                               \+    clazz->glyph_copy = copy_;                                               \+    clazz->glyph_transform = transform_;                                     \+    clazz->glyph_bbox = bbox_;                                               \+    clazz->glyph_prepare = prepare_;                                         \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DECLARE_RENDERER                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to create a forward declaration of a                          */+  /*    FT_Renderer_Class stract instance.                                 */+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_RENDERER                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Renderer_Class struct.        */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */+  /*    to called with a pointer where the allocated stracture is returned.*/+  /*    And when it is no longer needed a Destroy function needs           */+  /*    to be called to release that allocation.                           */+  /*    fcinit.c (ft_create_default_module_classes) already contains       */+  /*    a mechanism to call these functions for the default modules        */+  /*    described in ftmodule.h                                            */+  /*                                                                       */+  /*    Notice that the created Create and Destroy functions call          */+  /*    pic_init and pic_free function to allow you to manually allocate   */+  /*    and initialize any additional global data, like module specific    */+  /*    interface, and put them in the global pic container defined in     */+  /*    ftpic.h. if you don't need them just implement the functions as    */+  /*    empty to resolve the link error.                                   */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DECLARE_RENDERER(class_)                                          \+    FT_EXPORT_VAR( const FT_Renderer_Class ) class_;++#define FT_DEFINE_RENDERER(class_,                                           \+                           flags_, size_, name_, version_, requires_,        \+                           interface_, init_, done_, get_interface_,         \+                           glyph_format_, render_glyph_, transform_glyph_,   \+                           get_glyph_cbox_, set_mode_, raster_class_ )       \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_Renderer_Class  class_ =                                          \+  {                                                                          \+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \+                          interface_,init_,done_,get_interface_)             \+    glyph_format_,                                                           \+                                                                             \+    render_glyph_,                                                           \+    transform_glyph_,                                                        \+    get_glyph_cbox_,                                                         \+    set_mode_,                                                               \+                                                                             \+    raster_class_                                                            \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DECLARE_RENDERER(class_)  FT_DECLARE_MODULE(class_)++#define FT_DEFINE_RENDERER(class_, \+                           flags_, size_, name_, version_, requires_,        \+                           interface_, init_, done_, get_interface_,         \+                           glyph_format_, render_glyph_, transform_glyph_,   \+                           get_glyph_cbox_, set_mode_, raster_class_ )       \+  void class_##_pic_free( FT_Library library );                              \+  FT_Error class_##_pic_init( FT_Library library );                          \+                                                                             \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library        library,                      \+                        FT_Module_Class*  clazz )                            \+  {                                                                          \+    FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz;                   \+    FT_Memory         memory = library->memory;                              \+    class_##_pic_free( library );                                            \+    if ( rclazz )                                                            \+      FT_FREE( rclazz );                                                     \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library         library,                      \+                            FT_Module_Class**  output_class )                \+  {                                                                          \+    FT_Renderer_Class*  clazz;                                               \+    FT_Error            error;                                               \+    FT_Memory           memory = library->memory;                            \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \+      return error;                                                          \+                                                                             \+    error = class_##_pic_init( library );                                    \+    if(error)                                                                \+    {                                                                        \+      FT_FREE( clazz );                                                      \+      return error;                                                          \+    }                                                                        \+                                                                             \+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \+                          interface_,init_,done_,get_interface_)             \+                                                                             \+    clazz->glyph_format       = glyph_format_;                               \+                                                                             \+    clazz->render_glyph       = render_glyph_;                               \+    clazz->transform_glyph    = transform_glyph_;                            \+    clazz->get_glyph_cbox     = get_glyph_cbox_;                             \+    clazz->set_mode           = set_mode_;                                   \+                                                                             \+    clazz->raster_class       = raster_class_;                               \+                                                                             \+    *output_class = (FT_Module_Class*)clazz;                                 \+    return FT_Err_Ok;                                                        \+  } ++++#endif /* FT_CONFIG_OPTION_PIC */ ++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****              PIC-Support Macros for ftmodapi.h                  ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#ifdef FT_CONFIG_OPTION_PIC++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Module_Creator                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to create (allocate) a new module class object.    */+  /*    The object's members are initialized, but the module itself is     */+  /*    not.                                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory       :: A handle to the memory manager.                    */+  /*    output_class :: Initialized with the newly allocated class.        */+  /*                                                                       */+  typedef FT_Error+  (*FT_Module_Creator)( FT_Memory          memory,+                        FT_Module_Class**  output_class );++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    FT_Module_Destroyer                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to destroy (deallocate) a module class object.     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory :: A handle to the memory manager.                          */+  /*    clazz  :: Module class to destroy.                                 */+  /*                                                                       */+  typedef void+  (*FT_Module_Destroyer)( FT_Memory         memory,+                          FT_Module_Class*  clazz );++#endif++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DECLARE_MODULE                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to create a forward declaration of a                          */+  /*    FT_Module_Class stract instance.                                   */+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_MODULE                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Module_Class struct.          */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */+  /*    to called with a pointer where the allocated stracture is returned.*/+  /*    And when it is no longer needed a Destroy function needs           */+  /*    to be called to release that allocation.                           */+  /*    fcinit.c (ft_create_default_module_classes) already contains       */+  /*    a mechanism to call these functions for the default modules        */+  /*    described in ftmodule.h                                            */+  /*                                                                       */+  /*    Notice that the created Create and Destroy functions call          */+  /*    pic_init and pic_free function to allow you to manually allocate   */+  /*    and initialize any additional global data, like module specific    */+  /*    interface, and put them in the global pic container defined in     */+  /*    ftpic.h. if you don't need them just implement the functions as    */+  /*    empty to resolve the link error.                                   */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_ROOT_MODULE                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an instance of FT_Module_Class struct inside    */+  /*    another stract that contains it or in a function that initializes  */+  /*    that containing stract                                             */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DECLARE_MODULE(class_)                                            \+  FT_CALLBACK_TABLE                                                          \+  const FT_Module_Class  class_;                                             \++#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \+                              interface_, init_, done_, get_interface_)      \+  {                                                                          \+    flags_,                                                                  \+    size_,                                                                   \+                                                                             \+    name_,                                                                   \+    version_,                                                                \+    requires_,                                                               \+                                                                             \+    interface_,                                                              \+                                                                             \+    init_,                                                                   \+    done_,                                                                   \+    get_interface_,                                                          \+  },++#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \+                         interface_, init_, done_, get_interface_)           \+  FT_CALLBACK_TABLE_DEF                                                      \+  const FT_Module_Class class_ =                                             \+  {                                                                          \+    flags_,                                                                  \+    size_,                                                                   \+                                                                             \+    name_,                                                                   \+    version_,                                                                \+    requires_,                                                               \+                                                                             \+    interface_,                                                              \+                                                                             \+    init_,                                                                   \+    done_,                                                                   \+    get_interface_,                                                          \+  };+++#else /* FT_CONFIG_OPTION_PIC */++#define FT_DECLARE_MODULE(class_)                                            \+  FT_Error FT_Create_Class_##class_( FT_Library library,                     \+                                     FT_Module_Class** output_class );       \+  void     FT_Destroy_Class_##class_( FT_Library library,                    \+                                      FT_Module_Class*  clazz );++#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \+                              interface_, init_, done_, get_interface_)      \+    clazz->root.module_flags       = flags_;                                 \+    clazz->root.module_size        = size_;                                  \+    clazz->root.module_name        = name_;                                  \+    clazz->root.module_version     = version_;                               \+    clazz->root.module_requires    = requires_;                              \+                                                                             \+    clazz->root.module_interface   = interface_;                             \+                                                                             \+    clazz->root.module_init        = init_;                                  \+    clazz->root.module_done        = done_;                                  \+    clazz->root.get_interface      = get_interface_;               ++#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \+                         interface_, init_, done_, get_interface_)           \+  void class_##_pic_free( FT_Library library );                              \+  FT_Error class_##_pic_init( FT_Library library );                          \+                                                                             \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_Module_Class*  clazz )                       \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    class_##_pic_free( library );                                            \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_Module_Class**  output_class )                \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    FT_Module_Class*  clazz;                                                 \+    FT_Error          error;                                                 \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \+      return error;                                                          \+    error = class_##_pic_init( library );                                    \+    if(error)                                                                \+    {                                                                        \+      FT_FREE( clazz );                                                      \+      return error;                                                          \+    }                                                                        \+                                                                             \+    clazz->module_flags       = flags_;                                      \+    clazz->module_size        = size_;                                       \+    clazz->module_name        = name_;                                       \+    clazz->module_version     = version_;                                    \+    clazz->module_requires    = requires_;                                   \+                                                                             \+    clazz->module_interface   = interface_;                                  \+                                                                             \+    clazz->module_init        = init_;                                       \+    clazz->module_done        = done_;                                       \+    clazz->get_interface      = get_interface_;                              \+                                                                             \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#endif /* FT_CONFIG_OPTION_PIC */+++FT_END_HEADER++#endif /* __FTOBJS_H__ */+++/* END */
+ include/freetype/internal/ftpic.h view
@@ -0,0 +1,67 @@+/***************************************************************************/+/*                                                                         */+/*  ftpic.h                                                                */+/*                                                                         */+/*    The FreeType position independent code services (declaration).       */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /*  Modules that ordinarily have const global data that need address     */+  /*  can instead define pointers here.                                    */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTPIC_H__+#define __FTPIC_H__++  +FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC++  typedef struct FT_PIC_Container_+  {+    /* pic containers for base */+    void* base;+    /* pic containers for modules */+    void* autofit;   +    void* cff;    +    void* pshinter;    +    void* psnames;    +    void* raster;     +    void* sfnt;     +    void* smooth;     +    void* truetype;     +  } FT_PIC_Container;++  /* Initialize the various function tables, structs, etc. stored in the container. */+  FT_BASE( FT_Error )+  ft_pic_container_init( FT_Library library );+++  /* Destroy the contents of the container. */+  FT_BASE( void )+  ft_pic_container_destroy( FT_Library library );++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __FTPIC_H__ */+++/* END */
+ include/freetype/internal/ftrfork.h view
@@ -0,0 +1,196 @@+/***************************************************************************/+/*                                                                         */+/*  ftrfork.h                                                              */+/*                                                                         */+/*    Embedded resource forks accessor (specification).                    */+/*                                                                         */+/*  Copyright 2004, 2006, 2007 by                                          */+/*  Masatake YAMATO and Redhat K.K.                                        */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/***************************************************************************/+/* Development of the code in this file is support of                      */+/* Information-technology Promotion Agency, Japan.                         */+/***************************************************************************/+++#ifndef __FTRFORK_H__+#define __FTRFORK_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++  /* Number of guessing rules supported in `FT_Raccess_Guess'.            */+  /* Don't forget to increment the number if you add a new guessing rule. */+#define FT_RACCESS_N_RULES  9+++  /* A structure to describe a reference in a resource by its resource ID */+  /* and internal offset.  The `POST' resource expects to be concatenated */+  /* by the order of resource IDs instead of its appearance in the file.  */++  typedef struct  FT_RFork_Ref_+  {+    FT_UShort  res_id;+    FT_ULong   offset;++  } FT_RFork_Ref;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Raccess_Guess                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Guess a file name and offset where the actual resource fork is     */+  /*    stored.  The macro FT_RACCESS_N_RULES holds the number of          */+  /*    guessing rules;  the guessed result for the Nth rule is            */+  /*    represented as a triplet: a new file name (new_names[N]), a file   */+  /*    offset (offsets[N]), and an error code (errors[N]).                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library ::                                                         */+  /*      A FreeType library instance.                                     */+  /*                                                                       */+  /*    stream ::                                                          */+  /*      A file stream containing the resource fork.                      */+  /*                                                                       */+  /*    base_name ::                                                       */+  /*      The (base) file name of the resource fork used for some          */+  /*      guessing rules.                                                  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    new_names ::                                                       */+  /*      An array of guessed file names in which the resource forks may   */+  /*      exist.  If `new_names[N]' is NULL, the guessed file name is      */+  /*      equal to `base_name'.                                            */+  /*                                                                       */+  /*    offsets ::                                                         */+  /*      An array of guessed file offsets.  `offsets[N]' holds the file   */+  /*      offset of the possible start of the resource fork in file        */+  /*      `new_names[N]'.                                                  */+  /*                                                                       */+  /*    errors ::                                                          */+  /*      An array of FreeType error codes.  `errors[N]' is the error      */+  /*      code of Nth guessing rule function.  If `errors[N]' is not       */+  /*      FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless.      */+  /*                                                                       */+  FT_BASE( void )+  FT_Raccess_Guess( FT_Library  library,+                    FT_Stream   stream,+                    char*       base_name,+                    char**      new_names,+                    FT_Long*    offsets,+                    FT_Error*   errors );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Raccess_Get_HeaderInfo                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Get the information from the header of resource fork.  The         */+  /*    information includes the file offset where the resource map        */+  /*    starts, and the file offset where the resource data starts.        */+  /*    `FT_Raccess_Get_DataOffsets' requires these two data.              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library ::                                                         */+  /*      A FreeType library instance.                                     */+  /*                                                                       */+  /*    stream ::                                                          */+  /*      A file stream containing the resource fork.                      */+  /*                                                                       */+  /*    rfork_offset ::                                                    */+  /*      The file offset where the resource fork starts.                  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    map_offset ::                                                      */+  /*      The file offset where the resource map starts.                   */+  /*                                                                       */+  /*    rdata_pos ::                                                       */+  /*      The file offset where the resource data starts.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  FT_Err_Ok means success.                     */+  /*                                                                       */+  FT_BASE( FT_Error )+  FT_Raccess_Get_HeaderInfo( FT_Library  library,+                             FT_Stream   stream,+                             FT_Long     rfork_offset,+                             FT_Long    *map_offset,+                             FT_Long    *rdata_pos );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Raccess_Get_DataOffsets                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Get the data offsets for a tag in a resource fork.  Offsets are    */+  /*    stored in an array because, in some cases, resources in a resource */+  /*    fork have the same tag.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    library ::                                                         */+  /*      A FreeType library instance.                                     */+  /*                                                                       */+  /*    stream ::                                                          */+  /*      A file stream containing the resource fork.                      */+  /*                                                                       */+  /*    map_offset ::                                                      */+  /*      The file offset where the resource map starts.                   */+  /*                                                                       */+  /*    rdata_pos ::                                                       */+  /*      The file offset where the resource data starts.                  */+  /*                                                                       */+  /*    tag ::                                                             */+  /*      The resource tag.                                                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    offsets ::                                                         */+  /*      The stream offsets for the resource data specified by `tag'.     */+  /*      This array is allocated by the function, so you have to call     */+  /*      @ft_mem_free after use.                                          */+  /*                                                                       */+  /*    count ::                                                           */+  /*      The length of offsets array.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  FT_Err_Ok means success.                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Normally you should use `FT_Raccess_Get_HeaderInfo' to get the     */+  /*    value for `map_offset' and `rdata_pos'.                            */+  /*                                                                       */+  FT_BASE( FT_Error )+  FT_Raccess_Get_DataOffsets( FT_Library  library,+                              FT_Stream   stream,+                              FT_Long     map_offset,+                              FT_Long     rdata_pos,+                              FT_Long     tag,+                              FT_Long   **offsets,+                              FT_Long    *count );+++FT_END_HEADER++#endif /* __FTRFORK_H__ */+++/* END */
+ include/freetype/internal/ftserv.h view
@@ -0,0 +1,620 @@+/***************************************************************************/+/*                                                                         */+/*  ftserv.h                                                               */+/*                                                                         */+/*    The FreeType services (specification only).                          */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /*  Each module can export one or more `services'.  Each service is      */+  /*  identified by a constant string and modeled by a pointer; the latter */+  /*  generally corresponds to a structure containing function pointers.   */+  /*                                                                       */+  /*  Note that a service's data cannot be a mere function pointer because */+  /*  in C it is possible that function pointers might be implemented      */+  /*  differently than data pointers (e.g. 48 bits instead of 32).         */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTSERV_H__+#define __FTSERV_H__+++FT_BEGIN_HEADER++#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */++  /* we disable the warning `conditional expression is constant' here */+  /* in order to compile cleanly with the maximum level of warnings   */+#pragma warning( disable : 4127 )++#endif /* _MSC_VER */++  /*+   * @macro:+   *   FT_FACE_FIND_SERVICE+   *+   * @description:+   *   This macro is used to look up a service from a face's driver module.+   *+   * @input:+   *   face ::+   *     The source face handle.+   *+   *   id ::+   *     A string describing the service as defined in the service's+   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to+   *     `multi-masters').  It is automatically prefixed with+   *     `FT_SERVICE_ID_'.+   *+   * @output:+   *   ptr ::+   *     A variable that receives the service pointer.  Will be NULL+   *     if not found.+   */+#ifdef __cplusplus++#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \+  FT_BEGIN_STMNT                                                            \+    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \+    FT_Pointer   _tmp_  = NULL;                                             \+    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \+                                                                            \+                                                                            \+    if ( module->clazz->get_interface )                                     \+      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \+    *_pptr_ = _tmp_;                                                        \+  FT_END_STMNT++#else /* !C++ */++#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \+  FT_BEGIN_STMNT                                                            \+    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \+    FT_Pointer  _tmp_  = NULL;                                              \+                                                                            \+    if ( module->clazz->get_interface )                                     \+      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \+    ptr = _tmp_;                                                            \+  FT_END_STMNT++#endif /* !C++ */++  /*+   * @macro:+   *   FT_FACE_FIND_GLOBAL_SERVICE+   *+   * @description:+   *   This macro is used to look up a service from all modules.+   *+   * @input:+   *   face ::+   *     The source face handle.+   *+   *   id ::+   *     A string describing the service as defined in the service's+   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to+   *     `multi-masters').  It is automatically prefixed with+   *     `FT_SERVICE_ID_'.+   *+   * @output:+   *   ptr ::+   *     A variable that receives the service pointer.  Will be NULL+   *     if not found.+   */+#ifdef __cplusplus++#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \+  FT_BEGIN_STMNT                                                   \+    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \+    FT_Pointer   _tmp_;                                            \+    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \+                                                                   \+                                                                   \+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \+    *_pptr_ = _tmp_;                                               \+  FT_END_STMNT++#else /* !C++ */++#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \+  FT_BEGIN_STMNT                                                   \+    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \+    FT_Pointer  _tmp_;                                             \+                                                                   \+                                                                   \+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \+    ptr   = _tmp_;                                                 \+  FT_END_STMNT++#endif /* !C++ */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****         S E R V I C E   D E S C R I P T O R S                 *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*+   *  The following structure is used to _describe_ a given service+   *  to the library.  This is useful to build simple static service lists.+   */+  typedef struct  FT_ServiceDescRec_+  {+    const char*  serv_id;     /* service name         */+    const void*  serv_data;   /* service pointer/data */++  } FT_ServiceDescRec;++  typedef const FT_ServiceDescRec*  FT_ServiceDesc;++  /*************************************************************************/+  /*                                                                       */+  /* <Macro>                                                               */+  /*    FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Used to initialize an array of FT_ServiceDescRec structs.          */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */+  /*    to called with a pointer where the allocated array is returned.    */+  /*    And when it is no longer needed a Destroy function needs           */+  /*    to be called to release that allocation.                           */+  /*                                                                       */+  /*    These functions should be manyally called from the pic_init and    */+  /*    pic_free functions of your module (see FT_DEFINE_MODULE)           */+  /*                                                                       */+  /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */+  /*    allocated in the global scope (or the scope where the macro        */+  /*    is used).                                                          */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {NULL, NULL}                                                               \+  };+#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2)                                              \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {serv_id_2, serv_data_2},                                                  \+  {NULL, NULL}                                                               \+  };+#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {serv_id_2, serv_data_2},                                                  \+  {serv_id_3, serv_data_3},                                                  \+  {NULL, NULL}                                                               \+  };+#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \+        serv_id_4, serv_data_4)                                              \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {serv_id_2, serv_data_2},                                                  \+  {serv_id_3, serv_data_3},                                                  \+  {serv_id_4, serv_data_4},                                                  \+  {NULL, NULL}                                                               \+  };+#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \+        serv_id_4, serv_data_4, serv_id_5, serv_data_5)                      \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {serv_id_2, serv_data_2},                                                  \+  {serv_id_3, serv_data_3},                                                  \+  {serv_id_4, serv_data_4},                                                  \+  {serv_id_5, serv_data_5},                                                  \+  {NULL, NULL}                                                               \+  };+#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \+        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \+        serv_id_6, serv_data_6)                                              \+  static const FT_ServiceDescRec class_[] =                                  \+  {                                                                          \+  {serv_id_1, serv_data_1},                                                  \+  {serv_id_2, serv_data_2},                                                  \+  {serv_id_3, serv_data_3},                                                  \+  {serv_id_4, serv_data_4},                                                  \+  {serv_id_5, serv_data_5},                                                  \+  {serv_id_6, serv_data_6},                                                  \+  {NULL, NULL}                                                               \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = NULL;                                                 \+    clazz[1].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2)                                              \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = serv_id_2;                                            \+    clazz[1].serv_data = serv_data_2;                                        \+    clazz[2].serv_id = NULL;                                                 \+    clazz[2].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = serv_id_2;                                            \+    clazz[1].serv_data = serv_data_2;                                        \+    clazz[2].serv_id = serv_id_3;                                            \+    clazz[2].serv_data = serv_data_3;                                        \+    clazz[3].serv_id = NULL;                                                 \+    clazz[3].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \+        serv_id_4, serv_data_4)                                              \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = serv_id_2;                                            \+    clazz[1].serv_data = serv_data_2;                                        \+    clazz[2].serv_id = serv_id_3;                                            \+    clazz[2].serv_data = serv_data_3;                                        \+    clazz[3].serv_id = serv_id_4;                                            \+    clazz[3].serv_data = serv_data_4;                                        \+    clazz[4].serv_id = NULL;                                                 \+    clazz[4].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4,           \+        serv_data_4, serv_id_5, serv_data_5)                                 \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = serv_id_2;                                            \+    clazz[1].serv_data = serv_data_2;                                        \+    clazz[2].serv_id = serv_id_3;                                            \+    clazz[2].serv_data = serv_data_3;                                        \+    clazz[3].serv_id = serv_id_4;                                            \+    clazz[3].serv_data = serv_data_4;                                        \+    clazz[4].serv_id = serv_id_5;                                            \+    clazz[4].serv_data = serv_data_5;                                        \+    clazz[5].serv_id = NULL;                                                 \+    clazz[5].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } ++#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \+        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \+        serv_id_6, serv_data_6)                                              \+  void                                                                       \+  FT_Destroy_Class_##class_( FT_Library library,                             \+                             FT_ServiceDescRec* clazz )                      \+  {                                                                          \+    FT_Memory memory = library->memory;                                      \+    if ( clazz )                                                             \+      FT_FREE( clazz );                                                      \+  }                                                                          \+                                                                             \+  FT_Error                                                                   \+  FT_Create_Class_##class_( FT_Library library,                              \+                            FT_ServiceDescRec** output_class)                \+  {                                                                          \+    FT_ServiceDescRec*  clazz;                                               \+    FT_Error          error;                                                 \+    FT_Memory memory = library->memory;                                      \+                                                                             \+    if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) )                               \+      return error;                                                          \+    clazz[0].serv_id = serv_id_1;                                            \+    clazz[0].serv_data = serv_data_1;                                        \+    clazz[1].serv_id = serv_id_2;                                            \+    clazz[1].serv_data = serv_data_2;                                        \+    clazz[2].serv_id = serv_id_3;                                            \+    clazz[2].serv_data = serv_data_3;                                        \+    clazz[3].serv_id = serv_id_4;                                            \+    clazz[3].serv_data = serv_data_4;                                        \+    clazz[4].serv_id = serv_id_5;                                            \+    clazz[4].serv_data = serv_data_5;                                        \+    clazz[5].serv_id = serv_id_6;                                            \+    clazz[5].serv_data = serv_data_6;                                        \+    clazz[6].serv_id = NULL;                                                 \+    clazz[6].serv_data = NULL;                                               \+    *output_class = clazz;                                                   \+    return FT_Err_Ok;                                                        \+  } +#endif /* FT_CONFIG_OPTION_PIC */ ++  /*+   *  Parse a list of FT_ServiceDescRec descriptors and look for+   *  a specific service by ID.  Note that the last element in the+   *  array must be { NULL, NULL }, and that the function should+   *  return NULL if the service isn't available.+   *+   *  This function can be used by modules to implement their+   *  `get_service' method.+   */+  FT_BASE( FT_Pointer )+  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,+                          const char*     service_id );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****             S E R V I C E S   C A C H E                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*+   *  This structure is used to store a cache for several frequently used+   *  services.  It is the type of `face->internal->services'.  You+   *  should only use FT_FACE_LOOKUP_SERVICE to access it.+   *+   *  All fields should have the type FT_Pointer to relax compilation+   *  dependencies.  We assume the developer isn't completely stupid.+   *+   *  Each field must be named `service_XXXX' where `XXX' corresponds to+   *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of+   *  FT_FACE_LOOKUP_SERVICE below how this is implemented.+   *+   */+  typedef struct  FT_ServiceCacheRec_+  {+    FT_Pointer  service_POSTSCRIPT_FONT_NAME;+    FT_Pointer  service_MULTI_MASTERS;+    FT_Pointer  service_GLYPH_DICT;+    FT_Pointer  service_PFR_METRICS;+    FT_Pointer  service_WINFNT;++  } FT_ServiceCacheRec, *FT_ServiceCache;+++  /*+   *  A magic number used within the services cache.+   */+#define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)-2)  /* magic number */+++  /*+   * @macro:+   *   FT_FACE_LOOKUP_SERVICE+   *+   * @description:+   *   This macro is used to lookup a service from a face's driver module+   *   using its cache.+   *+   * @input:+   *   face::+   *     The source face handle containing the cache.+   *+   *   field ::+   *     The field name in the cache.+   *+   *   id ::+   *     The service ID.+   *+   * @output:+   *   ptr ::+   *     A variable receiving the service data.  NULL if not available.+   */+#ifdef __cplusplus++#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \+  FT_BEGIN_STMNT                                               \+    FT_Pointer   svc;                                          \+    FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \+                                                               \+                                                               \+    svc = FT_FACE( face )->internal->services. service_ ## id; \+    if ( svc == FT_SERVICE_UNAVAILABLE )                       \+      svc = NULL;                                              \+    else if ( svc == NULL )                                    \+    {                                                          \+      FT_FACE_FIND_SERVICE( face, svc, id );                   \+                                                               \+      FT_FACE( face )->internal->services. service_ ## id =    \+        (FT_Pointer)( svc != NULL ? svc                        \+                                  : FT_SERVICE_UNAVAILABLE );  \+    }                                                          \+    *Pptr = svc;                                               \+  FT_END_STMNT++#else /* !C++ */++#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \+  FT_BEGIN_STMNT                                               \+    FT_Pointer  svc;                                           \+                                                               \+                                                               \+    svc = FT_FACE( face )->internal->services. service_ ## id; \+    if ( svc == FT_SERVICE_UNAVAILABLE )                       \+      svc = NULL;                                              \+    else if ( svc == NULL )                                    \+    {                                                          \+      FT_FACE_FIND_SERVICE( face, svc, id );                   \+                                                               \+      FT_FACE( face )->internal->services. service_ ## id =    \+        (FT_Pointer)( svc != NULL ? svc                        \+                                  : FT_SERVICE_UNAVAILABLE );  \+    }                                                          \+    ptr = svc;                                                 \+  FT_END_STMNT++#endif /* !C++ */++  /*+   *  A macro used to define new service structure types.+   */++#define FT_DEFINE_SERVICE( name )            \+  typedef struct FT_Service_ ## name ## Rec_ \+    FT_Service_ ## name ## Rec ;             \+  typedef struct FT_Service_ ## name ## Rec_ \+    const * FT_Service_ ## name ;            \+  struct FT_Service_ ## name ## Rec_++  /* */++  /*+   *  The header files containing the services.+   */++#define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>+#define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>+#define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>+#define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>+#define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>+#define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>+#define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>+#define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>+#define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>+#define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>+#define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>+#define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>+#define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>+#define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>+#define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>+#define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>+#define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>++ /* */++FT_END_HEADER++#endif /* __FTSERV_H__ */+++/* END */
+ include/freetype/internal/ftstream.h view
@@ -0,0 +1,539 @@+/***************************************************************************/+/*                                                                         */+/*  ftstream.h                                                             */+/*                                                                         */+/*    Stream handling (specification).                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2005, 2006 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTSTREAM_H__+#define __FTSTREAM_H__+++#include <ft2build.h>+#include FT_SYSTEM_H+#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++  /* format of an 8-bit frame_op value:           */+  /*                                              */+  /* bit  76543210                                */+  /*      xxxxxxes                                */+  /*                                              */+  /* s is set to 1 if the value is signed.        */+  /* e is set to 1 if the value is little-endian. */+  /* xxx is a command.                            */++#define FT_FRAME_OP_SHIFT         2+#define FT_FRAME_OP_SIGNED        1+#define FT_FRAME_OP_LITTLE        2+#define FT_FRAME_OP_COMMAND( x )  ( x >> FT_FRAME_OP_SHIFT )++#define FT_MAKE_FRAME_OP( command, little, sign ) \+          ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign )++#define FT_FRAME_OP_END    0+#define FT_FRAME_OP_START  1  /* start a new frame     */+#define FT_FRAME_OP_BYTE   2  /* read 1-byte value     */+#define FT_FRAME_OP_SHORT  3  /* read 2-byte value     */+#define FT_FRAME_OP_LONG   4  /* read 4-byte value     */+#define FT_FRAME_OP_OFF3   5  /* read 3-byte value     */+#define FT_FRAME_OP_BYTES  6  /* read a bytes sequence */+++  typedef enum  FT_Frame_Op_+  {+    ft_frame_end       = 0,+    ft_frame_start     = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ),++    ft_frame_byte      = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE,  0, 0 ),+    ft_frame_schar     = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE,  0, 1 ),++    ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ),+    ft_frame_short_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ),+    ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ),+    ft_frame_short_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ),++    ft_frame_ulong_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ),+    ft_frame_long_be   = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ),+    ft_frame_ulong_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ),+    ft_frame_long_le   = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ),++    ft_frame_uoff3_be  = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ),+    ft_frame_off3_be   = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ),+    ft_frame_uoff3_le  = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ),+    ft_frame_off3_le   = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ),++    ft_frame_bytes     = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ),+    ft_frame_skip      = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 )++  } FT_Frame_Op;+++  typedef struct  FT_Frame_Field_+  {+    FT_Byte    value;+    FT_Byte    size;+    FT_UShort  offset;++  } FT_Frame_Field;+++  /* Construct an FT_Frame_Field out of a structure type and a field name. */+  /* The structure type must be set in the FT_STRUCTURE macro before       */+  /* calling the FT_FRAME_START() macro.                                   */+  /*                                                                       */+#define FT_FIELD_SIZE( f ) \+          (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f )++#define FT_FIELD_SIZE_DELTA( f ) \+          (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] )++#define FT_FIELD_OFFSET( f ) \+          (FT_UShort)( offsetof( FT_STRUCTURE, f ) )++#define FT_FRAME_FIELD( frame_op, field ) \+          {                               \+            frame_op,                     \+            FT_FIELD_SIZE( field ),       \+            FT_FIELD_OFFSET( field )      \+          }++#define FT_MAKE_EMPTY_FIELD( frame_op )  { frame_op, 0, 0 }++#define FT_FRAME_START( size )   { ft_frame_start, 0, size }+#define FT_FRAME_END             { ft_frame_end, 0, 0 }++#define FT_FRAME_LONG( f )       FT_FRAME_FIELD( ft_frame_long_be, f )+#define FT_FRAME_ULONG( f )      FT_FRAME_FIELD( ft_frame_ulong_be, f )+#define FT_FRAME_SHORT( f )      FT_FRAME_FIELD( ft_frame_short_be, f )+#define FT_FRAME_USHORT( f )     FT_FRAME_FIELD( ft_frame_ushort_be, f )+#define FT_FRAME_OFF3( f )       FT_FRAME_FIELD( ft_frame_off3_be, f )+#define FT_FRAME_UOFF3( f )      FT_FRAME_FIELD( ft_frame_uoff3_be, f )+#define FT_FRAME_BYTE( f )       FT_FRAME_FIELD( ft_frame_byte, f )+#define FT_FRAME_CHAR( f )       FT_FRAME_FIELD( ft_frame_schar, f )++#define FT_FRAME_LONG_LE( f )    FT_FRAME_FIELD( ft_frame_long_le, f )+#define FT_FRAME_ULONG_LE( f )   FT_FRAME_FIELD( ft_frame_ulong_le, f )+#define FT_FRAME_SHORT_LE( f )   FT_FRAME_FIELD( ft_frame_short_le, f )+#define FT_FRAME_USHORT_LE( f )  FT_FRAME_FIELD( ft_frame_ushort_le, f )+#define FT_FRAME_OFF3_LE( f )    FT_FRAME_FIELD( ft_frame_off3_le, f )+#define FT_FRAME_UOFF3_LE( f )   FT_FRAME_FIELD( ft_frame_uoff3_le, f )++#define FT_FRAME_SKIP_LONG       { ft_frame_long_be, 0, 0 }+#define FT_FRAME_SKIP_SHORT      { ft_frame_short_be, 0, 0 }+#define FT_FRAME_SKIP_BYTE       { ft_frame_byte, 0, 0 }++#define FT_FRAME_BYTES( field, count ) \+          {                            \+            ft_frame_bytes,            \+            count,                     \+            FT_FIELD_OFFSET( field )   \+          }++#define FT_FRAME_SKIP_BYTES( count )  { ft_frame_skip, count, 0 }+++  /*************************************************************************/+  /*                                                                       */+  /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */+  /* type `char*' or equivalent (1-byte elements).                         */+  /*                                                                       */++#define FT_BYTE_( p, i )  ( ((const FT_Byte*)(p))[(i)] )+#define FT_INT8_( p, i )  ( ((const FT_Char*)(p))[(i)] )++#define FT_INT16( x )   ( (FT_Int16)(x)  )+#define FT_UINT16( x )  ( (FT_UInt16)(x) )+#define FT_INT32( x )   ( (FT_Int32)(x)  )+#define FT_UINT32( x )  ( (FT_UInt32)(x) )++#define FT_BYTE_I16( p, i, s )  ( FT_INT16(  FT_BYTE_( p, i ) ) << (s) )+#define FT_BYTE_U16( p, i, s )  ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) )+#define FT_BYTE_I32( p, i, s )  ( FT_INT32(  FT_BYTE_( p, i ) ) << (s) )+#define FT_BYTE_U32( p, i, s )  ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )++#define FT_INT8_I16( p, i, s )  ( FT_INT16(  FT_INT8_( p, i ) ) << (s) )+#define FT_INT8_U16( p, i, s )  ( FT_UINT16( FT_INT8_( p, i ) ) << (s) )+#define FT_INT8_I32( p, i, s )  ( FT_INT32(  FT_INT8_( p, i ) ) << (s) )+#define FT_INT8_U32( p, i, s )  ( FT_UINT32( FT_INT8_( p, i ) ) << (s) )+++#define FT_PEEK_SHORT( p )  FT_INT16( FT_INT8_I16( p, 0, 8) | \+                                      FT_BYTE_I16( p, 1, 0) )++#define FT_PEEK_USHORT( p )  FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \+                                        FT_BYTE_U16( p, 1, 0 ) )++#define FT_PEEK_LONG( p )  FT_INT32( FT_INT8_I32( p, 0, 24 ) | \+                                     FT_BYTE_I32( p, 1, 16 ) | \+                                     FT_BYTE_I32( p, 2,  8 ) | \+                                     FT_BYTE_I32( p, 3,  0 ) )++#define FT_PEEK_ULONG( p )  FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \+                                       FT_BYTE_U32( p, 1, 16 ) | \+                                       FT_BYTE_U32( p, 2,  8 ) | \+                                       FT_BYTE_U32( p, 3,  0 ) )++#define FT_PEEK_OFF3( p )  FT_INT32( FT_INT8_I32( p, 0, 16 ) | \+                                     FT_BYTE_I32( p, 1,  8 ) | \+                                     FT_BYTE_I32( p, 2,  0 ) )++#define FT_PEEK_UOFF3( p )  FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \+                                       FT_BYTE_U32( p, 1,  8 ) | \+                                       FT_BYTE_U32( p, 2,  0 ) )++#define FT_PEEK_SHORT_LE( p )  FT_INT16( FT_INT8_I16( p, 1, 8 ) | \+                                         FT_BYTE_I16( p, 0, 0 ) )++#define FT_PEEK_USHORT_LE( p )  FT_UINT16( FT_BYTE_U16( p, 1, 8 ) |  \+                                           FT_BYTE_U16( p, 0, 0 ) )++#define FT_PEEK_LONG_LE( p )  FT_INT32( FT_INT8_I32( p, 3, 24 ) | \+                                        FT_BYTE_I32( p, 2, 16 ) | \+                                        FT_BYTE_I32( p, 1,  8 ) | \+                                        FT_BYTE_I32( p, 0,  0 ) )++#define FT_PEEK_ULONG_LE( p )  FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \+                                          FT_BYTE_U32( p, 2, 16 ) | \+                                          FT_BYTE_U32( p, 1,  8 ) | \+                                          FT_BYTE_U32( p, 0,  0 ) )++#define FT_PEEK_OFF3_LE( p )  FT_INT32( FT_INT8_I32( p, 2, 16 ) | \+                                        FT_BYTE_I32( p, 1,  8 ) | \+                                        FT_BYTE_I32( p, 0,  0 ) )++#define FT_PEEK_UOFF3_LE( p )  FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \+                                          FT_BYTE_U32( p, 1,  8 ) | \+                                          FT_BYTE_U32( p, 0,  0 ) )+++#define FT_NEXT_CHAR( buffer )       \+          ( (signed char)*buffer++ )++#define FT_NEXT_BYTE( buffer )         \+          ( (unsigned char)*buffer++ )++#define FT_NEXT_SHORT( buffer )                                   \+          ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )++#define FT_NEXT_USHORT( buffer )                                            \+          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )++#define FT_NEXT_OFF3( buffer )                                  \+          ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )++#define FT_NEXT_UOFF3( buffer )                                           \+          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )++#define FT_NEXT_LONG( buffer )                                  \+          ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )++#define FT_NEXT_ULONG( buffer )                                           \+          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )+++#define FT_NEXT_SHORT_LE( buffer )                                   \+          ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )++#define FT_NEXT_USHORT_LE( buffer )                                            \+          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )++#define FT_NEXT_OFF3_LE( buffer )                                  \+          ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )++#define FT_NEXT_UOFF3_LE( buffer )                                           \+          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )++#define FT_NEXT_LONG_LE( buffer )                                  \+          ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )++#define FT_NEXT_ULONG_LE( buffer )                                           \+          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )+++  /*************************************************************************/+  /*                                                                       */+  /* Each GET_xxxx() macro uses an implicit `stream' variable.             */+  /*                                                                       */+#if 0+#define FT_GET_MACRO( type )    FT_NEXT_ ## type ( stream->cursor )++#define FT_GET_CHAR()       FT_GET_MACRO( CHAR )+#define FT_GET_BYTE()       FT_GET_MACRO( BYTE )+#define FT_GET_SHORT()      FT_GET_MACRO( SHORT )+#define FT_GET_USHORT()     FT_GET_MACRO( USHORT )+#define FT_GET_OFF3()       FT_GET_MACRO( OFF3 )+#define FT_GET_UOFF3()      FT_GET_MACRO( UOFF3 )+#define FT_GET_LONG()       FT_GET_MACRO( LONG )+#define FT_GET_ULONG()      FT_GET_MACRO( ULONG )+#define FT_GET_TAG4()       FT_GET_MACRO( ULONG )++#define FT_GET_SHORT_LE()   FT_GET_MACRO( SHORT_LE )+#define FT_GET_USHORT_LE()  FT_GET_MACRO( USHORT_LE )+#define FT_GET_LONG_LE()    FT_GET_MACRO( LONG_LE )+#define FT_GET_ULONG_LE()   FT_GET_MACRO( ULONG_LE )++#else+#define FT_GET_MACRO( func, type )        ( (type)func( stream ) )++#define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetChar, FT_Char )+#define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )+#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetShort, FT_Short )+#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetShort, FT_UShort )+#define FT_GET_OFF3()       FT_GET_MACRO( FT_Stream_GetOffset, FT_Long )+#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong )+#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetLong, FT_Long )+#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )+#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )++#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short )+#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort )+#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long )+#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong )+#endif++#define FT_READ_MACRO( func, type, var )        \+          ( var = (type)func( stream, &error ), \+            error != FT_Err_Ok )++#define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var )+#define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var )+#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var )+#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var )+#define FT_READ_OFF3( var )       FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var )+#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var )+#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var )+#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var )++#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var )+#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var )+#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var )+#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var )+++#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM++  /* initialize a stream for reading a regular system stream */+  FT_BASE( FT_Error )+  FT_Stream_Open( FT_Stream    stream,+                  const char*  filepathname );++#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */+++  /* create a new (input) stream from an FT_Open_Args structure */+  FT_BASE( FT_Error )+  FT_Stream_New( FT_Library           library,+                 const FT_Open_Args*  args,+                 FT_Stream           *astream );++  /* free a stream */+  FT_BASE( void )+  FT_Stream_Free( FT_Stream  stream,+                  FT_Int     external );++  /* initialize a stream for reading in-memory data */+  FT_BASE( void )+  FT_Stream_OpenMemory( FT_Stream       stream,+                        const FT_Byte*  base,+                        FT_ULong        size );++  /* close a stream (does not destroy the stream structure) */+  FT_BASE( void )+  FT_Stream_Close( FT_Stream  stream );+++  /* seek within a stream. position is relative to start of stream */+  FT_BASE( FT_Error )+  FT_Stream_Seek( FT_Stream  stream,+                  FT_ULong   pos );++  /* skip bytes in a stream */+  FT_BASE( FT_Error )+  FT_Stream_Skip( FT_Stream  stream,+                  FT_Long    distance );++  /* return current stream position */+  FT_BASE( FT_Long )+  FT_Stream_Pos( FT_Stream  stream );++  /* read bytes from a stream into a user-allocated buffer, returns an */+  /* error if not all bytes could be read.                             */+  FT_BASE( FT_Error )+  FT_Stream_Read( FT_Stream  stream,+                  FT_Byte*   buffer,+                  FT_ULong   count );++  /* read bytes from a stream at a given position */+  FT_BASE( FT_Error )+  FT_Stream_ReadAt( FT_Stream  stream,+                    FT_ULong   pos,+                    FT_Byte*   buffer,+                    FT_ULong   count );++  /* try to read bytes at the end of a stream; return number of bytes */+  /* really available                                                 */+  FT_BASE( FT_ULong )+  FT_Stream_TryRead( FT_Stream  stream,+                     FT_Byte*   buffer,+                     FT_ULong   count );++  /* Enter a frame of `count' consecutive bytes in a stream.  Returns an */+  /* error if the frame could not be read/accessed.  The caller can use  */+  /* the FT_Stream_Get_XXX functions to retrieve frame data without      */+  /* error checks.                                                       */+  /*                                                                     */+  /* You must _always_ call FT_Stream_ExitFrame() once you have entered  */+  /* a stream frame!                                                     */+  /*                                                                     */+  FT_BASE( FT_Error )+  FT_Stream_EnterFrame( FT_Stream  stream,+                        FT_ULong   count );++  /* exit a stream frame */+  FT_BASE( void )+  FT_Stream_ExitFrame( FT_Stream  stream );++  /* Extract a stream frame.  If the stream is disk-based, a heap block */+  /* is allocated and the frame bytes are read into it.  If the stream  */+  /* is memory-based, this function simply set a pointer to the data.   */+  /*                                                                    */+  /* Useful to optimize access to memory-based streams transparently.   */+  /*                                                                    */+  /* All extracted frames must be `freed' with a call to the function   */+  /* FT_Stream_ReleaseFrame().                                          */+  /*                                                                    */+  FT_BASE( FT_Error )+  FT_Stream_ExtractFrame( FT_Stream  stream,+                          FT_ULong   count,+                          FT_Byte**  pbytes );++  /* release an extract frame (see FT_Stream_ExtractFrame) */+  FT_BASE( void )+  FT_Stream_ReleaseFrame( FT_Stream  stream,+                          FT_Byte**  pbytes );++  /* read a byte from an entered frame */+  FT_BASE( FT_Char )+  FT_Stream_GetChar( FT_Stream  stream );++  /* read a 16-bit big-endian integer from an entered frame */+  FT_BASE( FT_Short )+  FT_Stream_GetShort( FT_Stream  stream );++  /* read a 24-bit big-endian integer from an entered frame */+  FT_BASE( FT_Long )+  FT_Stream_GetOffset( FT_Stream  stream );++  /* read a 32-bit big-endian integer from an entered frame */+  FT_BASE( FT_Long )+  FT_Stream_GetLong( FT_Stream  stream );++  /* read a 16-bit little-endian integer from an entered frame */+  FT_BASE( FT_Short )+  FT_Stream_GetShortLE( FT_Stream  stream );++  /* read a 32-bit little-endian integer from an entered frame */+  FT_BASE( FT_Long )+  FT_Stream_GetLongLE( FT_Stream  stream );+++  /* read a byte from a stream */+  FT_BASE( FT_Char )+  FT_Stream_ReadChar( FT_Stream  stream,+                      FT_Error*  error );++  /* read a 16-bit big-endian integer from a stream */+  FT_BASE( FT_Short )+  FT_Stream_ReadShort( FT_Stream  stream,+                       FT_Error*  error );++  /* read a 24-bit big-endian integer from a stream */+  FT_BASE( FT_Long )+  FT_Stream_ReadOffset( FT_Stream  stream,+                        FT_Error*  error );++  /* read a 32-bit big-endian integer from a stream */+  FT_BASE( FT_Long )+  FT_Stream_ReadLong( FT_Stream  stream,+                      FT_Error*  error );++  /* read a 16-bit little-endian integer from a stream */+  FT_BASE( FT_Short )+  FT_Stream_ReadShortLE( FT_Stream  stream,+                         FT_Error*  error );++  /* read a 32-bit little-endian integer from a stream */+  FT_BASE( FT_Long )+  FT_Stream_ReadLongLE( FT_Stream  stream,+                        FT_Error*  error );++  /* Read a structure from a stream.  The structure must be described */+  /* by an array of FT_Frame_Field records.                           */+  FT_BASE( FT_Error )+  FT_Stream_ReadFields( FT_Stream              stream,+                        const FT_Frame_Field*  fields,+                        void*                  structure );+++#define FT_STREAM_POS()           \+          FT_Stream_Pos( stream )++#define FT_STREAM_SEEK( position )                           \+          FT_SET_ERROR( FT_Stream_Seek( stream, position ) )++#define FT_STREAM_SKIP( distance )                           \+          FT_SET_ERROR( FT_Stream_Skip( stream, distance ) )++#define FT_STREAM_READ( buffer, count )                   \+          FT_SET_ERROR( FT_Stream_Read( stream,           \+                                        (FT_Byte*)buffer, \+                                        count ) )++#define FT_STREAM_READ_AT( position, buffer, count )         \+          FT_SET_ERROR( FT_Stream_ReadAt( stream,            \+                                           position,         \+                                           (FT_Byte*)buffer, \+                                           count ) )++#define FT_STREAM_READ_FIELDS( fields, object )                          \+          FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) )+++#define FT_FRAME_ENTER( size )                                       \+          FT_SET_ERROR(                                              \+            FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, size ) ) )++#define FT_FRAME_EXIT()                 \+          FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) )++#define FT_FRAME_EXTRACT( size, bytes )                                       \+          FT_SET_ERROR(                                                       \+            FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, size,             \+                                                    (FT_Byte**)&(bytes) ) ) )++#define FT_FRAME_RELEASE( bytes )                                         \+          FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream,                 \+                                                  (FT_Byte**)&(bytes) ) )+++FT_END_HEADER++#endif /* __FTSTREAM_H__ */+++/* END */
+ include/freetype/internal/fttrace.h view
@@ -0,0 +1,139 @@+/***************************************************************************/+/*                                                                         */+/*  fttrace.h                                                              */+/*                                                                         */+/*    Tracing handling (specification only).                               */+/*                                                                         */+/*  Copyright 2002, 2004, 2005, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /* definitions of trace levels for FreeType 2 */++  /* the first level must always be `trace_any' */+FT_TRACE_DEF( any )++  /* base components */+FT_TRACE_DEF( calc )      /* calculations            (ftcalc.c)   */+FT_TRACE_DEF( memory )    /* memory manager          (ftobjs.c)   */+FT_TRACE_DEF( stream )    /* stream manager          (ftstream.c) */+FT_TRACE_DEF( io )        /* i/o interface           (ftsystem.c) */+FT_TRACE_DEF( list )      /* list management         (ftlist.c)   */+FT_TRACE_DEF( init )      /* initialization          (ftinit.c)   */+FT_TRACE_DEF( objs )      /* base objects            (ftobjs.c)   */+FT_TRACE_DEF( outline )   /* outline management      (ftoutln.c)  */+FT_TRACE_DEF( glyph )     /* glyph management        (ftglyph.c)  */+FT_TRACE_DEF( gloader )   /* glyph loader            (ftgloadr.c) */++FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */+FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */+FT_TRACE_DEF( mm )        /* MM interface            (ftmm.c)     */+FT_TRACE_DEF( raccess )   /* resource fork accessor  (ftrfork.c)  */+FT_TRACE_DEF( synth )     /* bold/slant synthesizer  (ftsynth.c)  */++  /* Cache sub-system */+FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc.) */++  /* SFNT driver components */+FT_TRACE_DEF( sfdriver )  /* SFNT font driver        (sfdriver.c) */+FT_TRACE_DEF( sfobjs )    /* SFNT object handler     (sfobjs.c)   */+FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */+FT_TRACE_DEF( ttkern )    /* kerning handler         (ttkern.c)   */+FT_TRACE_DEF( ttload )    /* basic TrueType tables   (ttload.c)   */+FT_TRACE_DEF( ttmtx )     /* metrics-related tables  (ttmtx.c)    */+FT_TRACE_DEF( ttpost )    /* PS table processing     (ttpost.c)   */+FT_TRACE_DEF( ttsbit )    /* TrueType sbit handling  (ttsbit.c)   */+FT_TRACE_DEF( ttbdf )     /* TrueType embedded BDF   (ttbdf.c)    */++  /* TrueType driver components */+FT_TRACE_DEF( ttdriver )  /* TT font driver          (ttdriver.c) */+FT_TRACE_DEF( ttgload )   /* TT glyph loader         (ttgload.c)  */+FT_TRACE_DEF( ttinterp )  /* bytecode interpreter    (ttinterp.c) */+FT_TRACE_DEF( ttobjs )    /* TT objects manager      (ttobjs.c)   */+FT_TRACE_DEF( ttpload )   /* TT data/program loader  (ttpload.c)  */+FT_TRACE_DEF( ttgxvar )   /* TrueType GX var handler (ttgxvar.c)  */++  /* Type 1 driver components */+FT_TRACE_DEF( t1afm )+FT_TRACE_DEF( t1driver )+FT_TRACE_DEF( t1gload )+FT_TRACE_DEF( t1hint )+FT_TRACE_DEF( t1load )+FT_TRACE_DEF( t1objs )+FT_TRACE_DEF( t1parse )++  /* PostScript helper module `psaux' */+FT_TRACE_DEF( t1decode )+FT_TRACE_DEF( psobjs )++  /* PostScript hinting module `pshinter' */+FT_TRACE_DEF( pshrec )+FT_TRACE_DEF( pshalgo1 )+FT_TRACE_DEF( pshalgo2 )++  /* Type 2 driver components */+FT_TRACE_DEF( cffdriver )+FT_TRACE_DEF( cffgload )+FT_TRACE_DEF( cffload )+FT_TRACE_DEF( cffobjs )+FT_TRACE_DEF( cffparse )++  /* Type 42 driver component */+FT_TRACE_DEF( t42 )++  /* CID driver components */+FT_TRACE_DEF( cidafm )+FT_TRACE_DEF( ciddriver )+FT_TRACE_DEF( cidgload )+FT_TRACE_DEF( cidload )+FT_TRACE_DEF( cidobjs )+FT_TRACE_DEF( cidparse )++  /* Windows font component */+FT_TRACE_DEF( winfnt )++  /* PCF font components */+FT_TRACE_DEF( pcfdriver )+FT_TRACE_DEF( pcfread )++  /* BDF font components */+FT_TRACE_DEF( bdfdriver )+FT_TRACE_DEF( bdflib )++  /* PFR font component */+FT_TRACE_DEF( pfr )++  /* OpenType validation components */+FT_TRACE_DEF( otvmodule )+FT_TRACE_DEF( otvcommon )+FT_TRACE_DEF( otvbase )+FT_TRACE_DEF( otvgdef )+FT_TRACE_DEF( otvgpos )+FT_TRACE_DEF( otvgsub )+FT_TRACE_DEF( otvjstf )+FT_TRACE_DEF( otvmath )++  /* TrueTypeGX/AAT validation components */+FT_TRACE_DEF( gxvmodule )+FT_TRACE_DEF( gxvcommon )+FT_TRACE_DEF( gxvfeat )+FT_TRACE_DEF( gxvmort )+FT_TRACE_DEF( gxvmorx )+FT_TRACE_DEF( gxvbsln )+FT_TRACE_DEF( gxvjust )+FT_TRACE_DEF( gxvkern )+FT_TRACE_DEF( gxvopbd )+FT_TRACE_DEF( gxvtrak )+FT_TRACE_DEF( gxvprop )+FT_TRACE_DEF( gxvlcar )+++/* END */
+ include/freetype/internal/ftvalid.h view
@@ -0,0 +1,150 @@+/***************************************************************************/+/*                                                                         */+/*  ftvalid.h                                                              */+/*                                                                         */+/*    FreeType validation support (specification).                         */+/*                                                                         */+/*  Copyright 2004 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTVALID_H__+#define __FTVALID_H__++#include <ft2build.h>+#include FT_CONFIG_STANDARD_LIBRARY_H   /* for ft_setjmp and ft_longjmp */+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                    V A L I D A T I O N                          ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /* handle to a validation object */+  typedef struct FT_ValidatorRec_ volatile*  FT_Validator;+++  /*************************************************************************/+  /*                                                                       */+  /* There are three distinct validation levels defined here:              */+  /*                                                                       */+  /* FT_VALIDATE_DEFAULT ::                                                */+  /*   A table that passes this validation level can be used reliably by   */+  /*   FreeType.  It generally means that all offsets have been checked to */+  /*   prevent out-of-bound reads, that array counts are correct, etc.     */+  /*                                                                       */+  /* FT_VALIDATE_TIGHT ::                                                  */+  /*   A table that passes this validation level can be used reliably and  */+  /*   doesn't contain invalid data.  For example, a charmap table that    */+  /*   returns invalid glyph indices will not pass, even though it can     */+  /*   be used with FreeType in default mode (the library will simply      */+  /*   return an error later when trying to load the glyph).               */+  /*                                                                       */+  /*   It also checks that fields which must be a multiple of 2, 4, or 8,  */+  /*   don't have incorrect values, etc.                                   */+  /*                                                                       */+  /* FT_VALIDATE_PARANOID ::                                               */+  /*   Only for font debugging.  Checks that a table follows the           */+  /*   specification by 100%.  Very few fonts will be able to pass this    */+  /*   level anyway but it can be useful for certain tools like font       */+  /*   editors/converters.                                                 */+  /*                                                                       */+  typedef enum  FT_ValidationLevel_+  {+    FT_VALIDATE_DEFAULT = 0,+    FT_VALIDATE_TIGHT,+    FT_VALIDATE_PARANOID++  } FT_ValidationLevel;+++  /* validator structure */+  typedef struct  FT_ValidatorRec_+  {+    const FT_Byte*      base;        /* address of table in memory       */+    const FT_Byte*      limit;       /* `base' + sizeof(table) in memory */+    FT_ValidationLevel  level;       /* validation level                 */+    FT_Error            error;       /* error returned. 0 means success  */++    ft_jmp_buf          jump_buffer; /* used for exception handling      */++  } FT_ValidatorRec;+++#define FT_VALIDATOR( x )  ((FT_Validator)( x ))+++  FT_BASE( void )+  ft_validator_init( FT_Validator        valid,+                     const FT_Byte*      base,+                     const FT_Byte*      limit,+                     FT_ValidationLevel  level );++  /* Do not use this. It's broken and will cause your validator to crash */+  /* if you run it on an invalid font.                                   */+  FT_BASE( FT_Int )+  ft_validator_run( FT_Validator  valid );++  /* Sets the error field in a validator, then calls `longjmp' to return */+  /* to high-level caller.  Using `setjmp/longjmp' avoids many stupid    */+  /* error checks within the validation routines.                        */+  /*                                                                     */+  FT_BASE( void )+  ft_validator_error( FT_Validator  valid,+                      FT_Error      error );+++  /* Calls ft_validate_error.  Assumes that the `valid' local variable */+  /* holds a pointer to the current validator object.                  */+  /*                                                                   */+  /* Use preprocessor prescan to pass FT_ERR_PREFIX.                   */+  /*                                                                   */+#define FT_INVALID( _prefix, _error )  FT_INVALID_( _prefix, _error )+#define FT_INVALID_( _prefix, _error ) \+          ft_validator_error( valid, _prefix ## _error )++  /* called when a broken table is detected */+#define FT_INVALID_TOO_SHORT \+          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )++  /* called when an invalid offset is detected */+#define FT_INVALID_OFFSET \+          FT_INVALID( FT_ERR_PREFIX, Invalid_Offset )++  /* called when an invalid format/value is detected */+#define FT_INVALID_FORMAT \+          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )++  /* called when an invalid glyph index is detected */+#define FT_INVALID_GLYPH_ID \+          FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index )++  /* called when an invalid field value is detected */+#define FT_INVALID_DATA \+          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )+++FT_END_HEADER++#endif /* __FTVALID_H__ */+++/* END */
+ include/freetype/internal/internal.h view
@@ -0,0 +1,51 @@+/***************************************************************************/+/*                                                                         */+/*  internal.h                                                             */+/*                                                                         */+/*    Internal header files (specification only).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is automatically included by `ft2build.h'.                  */+  /* Do not include it manually!                                           */+  /*                                                                       */+  /*************************************************************************/+++#define FT_INTERNAL_OBJECTS_H             <freetype/internal/ftobjs.h>+#define FT_INTERNAL_PIC_H                 <freetype/internal/ftpic.h>+#define FT_INTERNAL_STREAM_H              <freetype/internal/ftstream.h>+#define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>+#define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>+#define FT_INTERNAL_CALC_H                <freetype/internal/ftcalc.h>+#define FT_INTERNAL_DRIVER_H              <freetype/internal/ftdriver.h>+#define FT_INTERNAL_TRACE_H               <freetype/internal/fttrace.h>+#define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>+#define FT_INTERNAL_SFNT_H                <freetype/internal/sfnt.h>+#define FT_INTERNAL_SERVICE_H             <freetype/internal/ftserv.h>+#define FT_INTERNAL_RFORK_H               <freetype/internal/ftrfork.h>+#define FT_INTERNAL_VALIDATE_H            <freetype/internal/ftvalid.h>++#define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>+#define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>++#define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>+#define FT_INTERNAL_POSTSCRIPT_HINTS_H    <freetype/internal/pshints.h>+#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H  <freetype/internal/psglobal.h>++#define FT_INTERNAL_AUTOHINT_H            <freetype/internal/autohint.h>+++/* END */
+ include/freetype/internal/pcftypes.h view
@@ -0,0 +1,56 @@+/*  pcftypes.h++  FreeType font driver for pcf fonts++  Copyright (C) 2000, 2001, 2002 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __PCFTYPES_H__+#define __PCFTYPES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+++FT_BEGIN_HEADER+++  typedef struct  PCF_Public_FaceRec_+  {+    FT_FaceRec    root;+    FT_StreamRec  gzip_stream;+    FT_Stream     gzip_source;++    char*         charset_encoding;+    char*         charset_registry;++  } PCF_Public_FaceRec, *PCF_Public_Face;+++FT_END_HEADER++#endif  /* __PCFTYPES_H__ */+++/* END */
+ include/freetype/internal/psaux.h view
@@ -0,0 +1,873 @@+/***************************************************************************/+/*                                                                         */+/*  psaux.h                                                                */+/*                                                                         */+/*    Auxiliary functions and data structures related to PostScript fonts  */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSAUX_H__+#define __PSAUX_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_TYPE1_TYPES_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                             T1_TABLE                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  typedef struct PS_TableRec_*              PS_Table;+  typedef const struct PS_Table_FuncsRec_*  PS_Table_Funcs;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_Table_FuncsRec                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A set of function pointers to manage PS_Table objects.             */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    table_init    :: Used to initialize a table.                       */+  /*                                                                       */+  /*    table_done    :: Finalizes resp. destroy a given table.            */+  /*                                                                       */+  /*    table_add     :: Adds a new object to a table.                     */+  /*                                                                       */+  /*    table_release :: Releases table data, then finalizes it.           */+  /*                                                                       */+  typedef struct  PS_Table_FuncsRec_+  {+    FT_Error+    (*init)( PS_Table   table,+             FT_Int     count,+             FT_Memory  memory );++    void+    (*done)( PS_Table  table );++    FT_Error+    (*add)( PS_Table    table,+            FT_Int      idx,+            void*       object,+            FT_PtrDist  length );++    void+    (*release)( PS_Table  table );++  } PS_Table_FuncsRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_TableRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A PS_Table is a simple object used to store an array of objects in */+  /*    a single memory block.                                             */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    block     :: The address in memory of the growheap's block.  This  */+  /*                 can change between two object adds, due to            */+  /*                 reallocation.                                         */+  /*                                                                       */+  /*    cursor    :: The current top of the grow heap within its block.    */+  /*                                                                       */+  /*    capacity  :: The current size of the heap block.  Increments by    */+  /*                 1kByte chunks.                                        */+  /*                                                                       */+  /*    max_elems :: The maximum number of elements in table.              */+  /*                                                                       */+  /*    num_elems :: The current number of elements in table.              */+  /*                                                                       */+  /*    elements  :: A table of element addresses within the block.        */+  /*                                                                       */+  /*    lengths   :: A table of element sizes within the block.            */+  /*                                                                       */+  /*    memory    :: The object used for memory operations                 */+  /*                 (alloc/realloc).                                      */+  /*                                                                       */+  /*    funcs     :: A table of method pointers for this object.           */+  /*                                                                       */+  typedef struct  PS_TableRec_+  {+    FT_Byte*           block;          /* current memory block           */+    FT_Offset          cursor;         /* current cursor in memory block */+    FT_Offset          capacity;       /* current size of memory block   */+    FT_Long            init;++    FT_Int             max_elems;+    FT_Int             num_elems;+    FT_Byte**          elements;       /* addresses of table elements */+    FT_PtrDist*        lengths;        /* lengths of table elements   */++    FT_Memory          memory;+    PS_Table_FuncsRec  funcs;++  } PS_TableRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       T1 FIELDS & TOKENS                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct PS_ParserRec_*  PS_Parser;++  typedef struct T1_TokenRec_*   T1_Token;++  typedef struct T1_FieldRec_*   T1_Field;+++  /* simple enumeration type used to identify token types */+  typedef enum  T1_TokenType_+  {+    T1_TOKEN_TYPE_NONE = 0,+    T1_TOKEN_TYPE_ANY,+    T1_TOKEN_TYPE_STRING,+    T1_TOKEN_TYPE_ARRAY,+    T1_TOKEN_TYPE_KEY, /* aka `name' */++    /* do not remove */+    T1_TOKEN_TYPE_MAX++  } T1_TokenType;+++  /* a simple structure used to identify tokens */+  typedef struct  T1_TokenRec_+  {+    FT_Byte*      start;   /* first character of token in input stream */+    FT_Byte*      limit;   /* first character after the token          */+    T1_TokenType  type;    /* type of token                            */++  } T1_TokenRec;+++  /* enumeration type used to identify object fields */+  typedef enum  T1_FieldType_+  {+    T1_FIELD_TYPE_NONE = 0,+    T1_FIELD_TYPE_BOOL,+    T1_FIELD_TYPE_INTEGER,+    T1_FIELD_TYPE_FIXED,+    T1_FIELD_TYPE_FIXED_1000,+    T1_FIELD_TYPE_STRING,+    T1_FIELD_TYPE_KEY,+    T1_FIELD_TYPE_BBOX,+    T1_FIELD_TYPE_INTEGER_ARRAY,+    T1_FIELD_TYPE_FIXED_ARRAY,+    T1_FIELD_TYPE_CALLBACK,++    /* do not remove */+    T1_FIELD_TYPE_MAX++  } T1_FieldType;+++  typedef enum  T1_FieldLocation_+  {+    T1_FIELD_LOCATION_CID_INFO,+    T1_FIELD_LOCATION_FONT_DICT,+    T1_FIELD_LOCATION_FONT_EXTRA,+    T1_FIELD_LOCATION_FONT_INFO,+    T1_FIELD_LOCATION_PRIVATE,+    T1_FIELD_LOCATION_BBOX,+    T1_FIELD_LOCATION_LOADER,+    T1_FIELD_LOCATION_FACE,+    T1_FIELD_LOCATION_BLEND,++    /* do not remove */+    T1_FIELD_LOCATION_MAX++  } T1_FieldLocation;+++  typedef void+  (*T1_Field_ParseFunc)( FT_Face     face,+                         FT_Pointer  parser );+++  /* structure type used to model object fields */+  typedef struct  T1_FieldRec_+  {+    const char*         ident;        /* field identifier               */+    T1_FieldLocation    location;+    T1_FieldType        type;         /* type of field                  */+    T1_Field_ParseFunc  reader;+    FT_UInt             offset;       /* offset of field in object      */+    FT_Byte             size;         /* size of field in bytes         */+    FT_UInt             array_max;    /* maximal number of elements for */+                                      /* array                          */+    FT_UInt             count_offset; /* offset of element count for    */+                                      /* arrays; must not be zero if in */+                                      /* use -- in other words, a       */+                                      /* `num_FOO' element must not     */+                                      /* start the used structure if we */+                                      /* parse a `FOO' array            */+    FT_UInt             dict;         /* where we expect it             */+  } T1_FieldRec;++#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */+#define T1_FIELD_DICT_PRIVATE  ( 1 << 1 )++++#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \+          {                                                 \+            _ident, T1CODE, _type,                          \+            0,                                              \+            FT_FIELD_OFFSET( _fname ),                      \+            FT_FIELD_SIZE( _fname ),                        \+            0, 0,                                           \+            _dict                                           \+          },++#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \+          {                                             \+            _ident, T1CODE, T1_FIELD_TYPE_CALLBACK,     \+            (T1_Field_ParseFunc)_reader,                \+            0, 0,                                       \+            0, 0,                                       \+            _dict                                       \+          },++#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \+          {                                                      \+            _ident, T1CODE, _type,                               \+            0,                                                   \+            FT_FIELD_OFFSET( _fname ),                           \+            FT_FIELD_SIZE_DELTA( _fname ),                       \+            _max,                                                \+            FT_FIELD_OFFSET( num_ ## _fname ),                   \+            _dict                                                \+          },++#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \+          {                                                       \+            _ident, T1CODE, _type,                                \+            0,                                                    \+            FT_FIELD_OFFSET( _fname ),                            \+            FT_FIELD_SIZE_DELTA( _fname ),                        \+            _max, 0,                                              \+            _dict                                                 \+          },+++#define T1_FIELD_BOOL( _ident, _fname, _dict )                             \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict )++#define T1_FIELD_NUM( _ident, _fname, _dict )                                 \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict )++#define T1_FIELD_FIXED( _ident, _fname, _dict )                             \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict )++#define T1_FIELD_FIXED_1000( _ident, _fname, _dict )                     \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \+                               _dict )++#define T1_FIELD_STRING( _ident, _fname, _dict )                             \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict )++#define T1_FIELD_KEY( _ident, _fname, _dict )                             \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict )++#define T1_FIELD_BBOX( _ident, _fname, _dict )                             \+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict )+++#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict )         \+          T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \+                              _fname, _fmax, _dict )++#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict )     \+          T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \+                              _fname, _fmax, _dict )++#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict )         \+          T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \+                               _fname, _fmax, _dict )++#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict )     \+          T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \+                               _fname, _fmax, _dict )++#define T1_FIELD_CALLBACK( _ident, _name, _dict )       \+          T1_NEW_CALLBACK_FIELD( _ident, _name, _dict )+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            T1 PARSER                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef const struct PS_Parser_FuncsRec_*  PS_Parser_Funcs;++  typedef struct  PS_Parser_FuncsRec_+  {+    void+    (*init)( PS_Parser  parser,+             FT_Byte*   base,+             FT_Byte*   limit,+             FT_Memory  memory );++    void+    (*done)( PS_Parser  parser );++    void+    (*skip_spaces)( PS_Parser  parser );+    void+    (*skip_PS_token)( PS_Parser  parser );++    FT_Long+    (*to_int)( PS_Parser  parser );+    FT_Fixed+    (*to_fixed)( PS_Parser  parser,+                 FT_Int     power_ten );++    FT_Error+    (*to_bytes)( PS_Parser  parser,+                 FT_Byte*   bytes,+                 FT_Offset  max_bytes,+                 FT_Long*   pnum_bytes,+                 FT_Bool    delimiters );++    FT_Int+    (*to_coord_array)( PS_Parser  parser,+                       FT_Int     max_coords,+                       FT_Short*  coords );+    FT_Int+    (*to_fixed_array)( PS_Parser  parser,+                       FT_Int     max_values,+                       FT_Fixed*  values,+                       FT_Int     power_ten );++    void+    (*to_token)( PS_Parser  parser,+                 T1_Token   token );+    void+    (*to_token_array)( PS_Parser  parser,+                       T1_Token   tokens,+                       FT_UInt    max_tokens,+                       FT_Int*    pnum_tokens );++    FT_Error+    (*load_field)( PS_Parser       parser,+                   const T1_Field  field,+                   void**          objects,+                   FT_UInt         max_objects,+                   FT_ULong*       pflags );++    FT_Error+    (*load_field_table)( PS_Parser       parser,+                         const T1_Field  field,+                         void**          objects,+                         FT_UInt         max_objects,+                         FT_ULong*       pflags );++  } PS_Parser_FuncsRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_ParserRec                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A PS_Parser is an object used to parse a Type 1 font very quickly. */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    cursor :: The current position in the text.                        */+  /*                                                                       */+  /*    base   :: Start of the processed text.                             */+  /*                                                                       */+  /*    limit  :: End of the processed text.                               */+  /*                                                                       */+  /*    error  :: The last error returned.                                 */+  /*                                                                       */+  /*    memory :: The object used for memory operations (alloc/realloc).   */+  /*                                                                       */+  /*    funcs  :: A table of functions for the parser.                     */+  /*                                                                       */+  typedef struct  PS_ParserRec_+  {+    FT_Byte*   cursor;+    FT_Byte*   base;+    FT_Byte*   limit;+    FT_Error   error;+    FT_Memory  memory;++    PS_Parser_FuncsRec  funcs;++  } PS_ParserRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                         T1 BUILDER                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  typedef struct T1_BuilderRec_*  T1_Builder;+++  typedef FT_Error+  (*T1_Builder_Check_Points_Func)( T1_Builder  builder,+                                   FT_Int      count );++  typedef void+  (*T1_Builder_Add_Point_Func)( T1_Builder  builder,+                                FT_Pos      x,+                                FT_Pos      y,+                                FT_Byte     flag );++  typedef FT_Error+  (*T1_Builder_Add_Point1_Func)( T1_Builder  builder,+                                 FT_Pos      x,+                                 FT_Pos      y );++  typedef FT_Error+  (*T1_Builder_Add_Contour_Func)( T1_Builder  builder );++  typedef FT_Error+  (*T1_Builder_Start_Point_Func)( T1_Builder  builder,+                                  FT_Pos      x,+                                  FT_Pos      y );++  typedef void+  (*T1_Builder_Close_Contour_Func)( T1_Builder  builder );+++  typedef const struct T1_Builder_FuncsRec_*  T1_Builder_Funcs;++  typedef struct  T1_Builder_FuncsRec_+  {+    void+    (*init)( T1_Builder    builder,+             FT_Face       face,+             FT_Size       size,+             FT_GlyphSlot  slot,+             FT_Bool       hinting );++    void+    (*done)( T1_Builder   builder );++    T1_Builder_Check_Points_Func   check_points;+    T1_Builder_Add_Point_Func      add_point;+    T1_Builder_Add_Point1_Func     add_point1;+    T1_Builder_Add_Contour_Func    add_contour;+    T1_Builder_Start_Point_Func    start_point;+    T1_Builder_Close_Contour_Func  close_contour;++  } T1_Builder_FuncsRec;+++  /* an enumeration type to handle charstring parsing states */+  typedef enum  T1_ParseState_+  {+    T1_Parse_Start,+    T1_Parse_Have_Width,+    T1_Parse_Have_Moveto,+    T1_Parse_Have_Path++  } T1_ParseState;+++  /*************************************************************************/+  /*                                                                       */+  /* <Structure>                                                           */+  /*    T1_BuilderRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*     A structure used during glyph loading to store its outline.       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    memory       :: The current memory object.                         */+  /*                                                                       */+  /*    face         :: The current face object.                           */+  /*                                                                       */+  /*    glyph        :: The current glyph slot.                            */+  /*                                                                       */+  /*    loader       :: XXX                                                */+  /*                                                                       */+  /*    base         :: The base glyph outline.                            */+  /*                                                                       */+  /*    current      :: The current glyph outline.                         */+  /*                                                                       */+  /*    max_points   :: maximum points in builder outline                  */+  /*                                                                       */+  /*    max_contours :: Maximal number of contours in builder outline.     */+  /*                                                                       */+  /*    pos_x        :: The horizontal translation (if composite glyph).   */+  /*                                                                       */+  /*    pos_y        :: The vertical translation (if composite glyph).     */+  /*                                                                       */+  /*    left_bearing :: The left side bearing point.                       */+  /*                                                                       */+  /*    advance      :: The horizontal advance vector.                     */+  /*                                                                       */+  /*    bbox         :: Unused.                                            */+  /*                                                                       */+  /*    parse_state  :: An enumeration which controls the charstring       */+  /*                    parsing state.                                     */+  /*                                                                       */+  /*    load_points  :: If this flag is not set, no points are loaded.     */+  /*                                                                       */+  /*    no_recurse   :: Set but not used.                                  */+  /*                                                                       */+  /*    metrics_only :: A boolean indicating that we only want to compute  */+  /*                    the metrics of a given glyph, not load all of its  */+  /*                    points.                                            */+  /*                                                                       */+  /*    funcs        :: An array of function pointers for the builder.     */+  /*                                                                       */+  typedef struct  T1_BuilderRec_+  {+    FT_Memory       memory;+    FT_Face         face;+    FT_GlyphSlot    glyph;+    FT_GlyphLoader  loader;+    FT_Outline*     base;+    FT_Outline*     current;++    FT_Pos          pos_x;+    FT_Pos          pos_y;++    FT_Vector       left_bearing;+    FT_Vector       advance;++    FT_BBox         bbox;          /* bounding box */+    T1_ParseState   parse_state;+    FT_Bool         load_points;+    FT_Bool         no_recurse;++    FT_Bool         metrics_only;++    void*           hints_funcs;    /* hinter-specific */+    void*           hints_globals;  /* hinter-specific */++    T1_Builder_FuncsRec  funcs;++  } T1_BuilderRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                         T1 DECODER                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#if 0++  /*************************************************************************/+  /*                                                                       */+  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */+  /* calls during glyph loading.                                           */+  /*                                                                       */+#define T1_MAX_SUBRS_CALLS  8+++  /*************************************************************************/+  /*                                                                       */+  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */+  /* minimum of 16 is required.                                            */+  /*                                                                       */+#define T1_MAX_CHARSTRINGS_OPERANDS  32++#endif /* 0 */+++  typedef struct  T1_Decoder_ZoneRec_+  {+    FT_Byte*  cursor;+    FT_Byte*  base;+    FT_Byte*  limit;++  } T1_Decoder_ZoneRec, *T1_Decoder_Zone;+++  typedef struct T1_DecoderRec_*              T1_Decoder;+  typedef const struct T1_Decoder_FuncsRec_*  T1_Decoder_Funcs;+++  typedef FT_Error+  (*T1_Decoder_Callback)( T1_Decoder  decoder,+                          FT_UInt     glyph_index );+++  typedef struct  T1_Decoder_FuncsRec_+  {+    FT_Error+    (*init)( T1_Decoder           decoder,+             FT_Face              face,+             FT_Size              size,+             FT_GlyphSlot         slot,+             FT_Byte**            glyph_names,+             PS_Blend             blend,+             FT_Bool              hinting,+             FT_Render_Mode       hint_mode,+             T1_Decoder_Callback  callback );++    void+    (*done)( T1_Decoder  decoder );++    FT_Error+    (*parse_charstrings)( T1_Decoder  decoder,+                          FT_Byte*    base,+                          FT_UInt     len );++  } T1_Decoder_FuncsRec;+++  typedef struct  T1_DecoderRec_+  {+    T1_BuilderRec        builder;++    FT_Long              stack[T1_MAX_CHARSTRINGS_OPERANDS];+    FT_Long*             top;++    T1_Decoder_ZoneRec   zones[T1_MAX_SUBRS_CALLS + 1];+    T1_Decoder_Zone      zone;++    FT_Service_PsCMaps   psnames;      /* for seac */+    FT_UInt              num_glyphs;+    FT_Byte**            glyph_names;++    FT_Int               lenIV;        /* internal for sub routine calls */+    FT_UInt              num_subrs;+    FT_Byte**            subrs;+    FT_PtrDist*          subrs_len;    /* array of subrs length (optional) */++    FT_Matrix            font_matrix;+    FT_Vector            font_offset;++    FT_Int               flex_state;+    FT_Int               num_flex_vectors;+    FT_Vector            flex_vectors[7];++    PS_Blend             blend;       /* for multiple master support */++    FT_Render_Mode       hint_mode;++    T1_Decoder_Callback  parse_callback;+    T1_Decoder_FuncsRec  funcs;++    FT_Long*             buildchar;+    FT_UInt              len_buildchar;++    FT_Bool              seac;++  } T1_DecoderRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            AFM PARSER                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct AFM_ParserRec_*  AFM_Parser;++  typedef struct  AFM_Parser_FuncsRec_+  {+    FT_Error+    (*init)( AFM_Parser  parser,+             FT_Memory   memory,+             FT_Byte*    base,+             FT_Byte*    limit );++    void+    (*done)( AFM_Parser  parser );++    FT_Error+    (*parse)( AFM_Parser  parser );++  } AFM_Parser_FuncsRec;+++  typedef struct AFM_StreamRec_*  AFM_Stream;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    AFM_ParserRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An AFM_Parser is a parser for the AFM files.                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    memory    :: The object used for memory operations (alloc and      */+  /*                 realloc).                                             */+  /*                                                                       */+  /*    stream    :: This is an opaque object.                             */+  /*                                                                       */+  /*    FontInfo  :: The result will be stored here.                       */+  /*                                                                       */+  /*    get_index :: A user provided function to get a glyph index by its  */+  /*                 name.                                                 */+  /*                                                                       */+  typedef struct  AFM_ParserRec_+  {+    FT_Memory     memory;+    AFM_Stream    stream;++    AFM_FontInfo  FontInfo;++    FT_Int+    (*get_index)( const char*  name,+                  FT_Offset    len,+                  void*        user_data );++    void*         user_data;++  } AFM_ParserRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     TYPE1 CHARMAPS                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef const struct T1_CMap_ClassesRec_*  T1_CMap_Classes;++  typedef struct T1_CMap_ClassesRec_+  {+    FT_CMap_Class  standard;+    FT_CMap_Class  expert;+    FT_CMap_Class  custom;+    FT_CMap_Class  unicode;++  } T1_CMap_ClassesRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                        PSAux Module Interface                 *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct  PSAux_ServiceRec_+  {+    /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */+    const PS_Table_FuncsRec*    ps_table_funcs;+    const PS_Parser_FuncsRec*   ps_parser_funcs;+    const T1_Builder_FuncsRec*  t1_builder_funcs;+    const T1_Decoder_FuncsRec*  t1_decoder_funcs;++    void+    (*t1_decrypt)( FT_Byte*   buffer,+                   FT_Offset  length,+                   FT_UShort  seed );++    T1_CMap_Classes  t1_cmap_classes;++    /* fields after this comment line were added after version 2.1.10 */+    const AFM_Parser_FuncsRec*  afm_parser_funcs;++  } PSAux_ServiceRec, *PSAux_Service;++  /* backwards-compatible type definition */+  typedef PSAux_ServiceRec   PSAux_Interface;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                 Some convenience functions                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#define IS_PS_NEWLINE( ch ) \+  ( (ch) == '\r' ||         \+    (ch) == '\n' )++#define IS_PS_SPACE( ch )  \+  ( (ch) == ' '         || \+    IS_PS_NEWLINE( ch ) || \+    (ch) == '\t'        || \+    (ch) == '\f'        || \+    (ch) == '\0' )++#define IS_PS_SPECIAL( ch )       \+  ( (ch) == '/'                || \+    (ch) == '(' || (ch) == ')' || \+    (ch) == '<' || (ch) == '>' || \+    (ch) == '[' || (ch) == ']' || \+    (ch) == '{' || (ch) == '}' || \+    (ch) == '%'                )++#define IS_PS_DELIM( ch )  \+  ( IS_PS_SPACE( ch )   || \+    IS_PS_SPECIAL( ch ) )++#define IS_PS_DIGIT( ch )        \+  ( (ch) >= '0' && (ch) <= '9' )++#define IS_PS_XDIGIT( ch )            \+  ( IS_PS_DIGIT( ch )              || \+    ( (ch) >= 'A' && (ch) <= 'F' ) || \+    ( (ch) >= 'a' && (ch) <= 'f' ) )++#define IS_PS_BASE85( ch )       \+  ( (ch) >= '!' && (ch) <= 'u' )++#define IS_PS_TOKEN( cur, limit, token )                                \+  ( (char)(cur)[0] == (token)[0]                                     && \+    ( (cur) + sizeof ( (token) ) == (limit) ||                          \+      ( (cur) + sizeof( (token) ) < (limit)          &&                 \+        IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) )             && \+    ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 )+++FT_END_HEADER++#endif /* __PSAUX_H__ */+++/* END */
+ include/freetype/internal/pshints.h view
@@ -0,0 +1,712 @@+/***************************************************************************/+/*                                                                         */+/*  pshints.h                                                              */+/*                                                                         */+/*    Interface to Postscript-specific (Type 1 and Type 2) hints           */+/*    recorders (specification only).  These are used to support native    */+/*    T1/T2 hints in the `type1', `cid', and `cff' font drivers.           */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSHINTS_H__+#define __PSHINTS_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TYPE1_TABLES_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****               INTERNAL REPRESENTATION OF GLOBALS              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct PSH_GlobalsRec_*  PSH_Globals;++  typedef FT_Error+  (*PSH_Globals_NewFunc)( FT_Memory     memory,+                          T1_Private*   private_dict,+                          PSH_Globals*  aglobals );++  typedef FT_Error+  (*PSH_Globals_SetScaleFunc)( PSH_Globals  globals,+                               FT_Fixed     x_scale,+                               FT_Fixed     y_scale,+                               FT_Fixed     x_delta,+                               FT_Fixed     y_delta );++  typedef void+  (*PSH_Globals_DestroyFunc)( PSH_Globals  globals );+++  typedef struct  PSH_Globals_FuncsRec_+  {+    PSH_Globals_NewFunc       create;+    PSH_Globals_SetScaleFunc  set_scale;+    PSH_Globals_DestroyFunc   destroy;++  } PSH_Globals_FuncsRec, *PSH_Globals_Funcs;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                  PUBLIC TYPE 1 HINTS RECORDER                 *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************+   *+   * @type:+   *   T1_Hints+   *+   * @description:+   *   This is a handle to an opaque structure used to record glyph hints+   *   from a Type 1 character glyph character string.+   *+   *   The methods used to operate on this object are defined by the+   *   @T1_Hints_FuncsRec structure.  Recording glyph hints is normally+   *   achieved through the following scheme:+   *+   *   - Open a new hint recording session by calling the `open' method.+   *     This rewinds the recorder and prepare it for new input.+   *+   *   - For each hint found in the glyph charstring, call the corresponding+   *     method (`stem', `stem3', or `reset').  Note that these functions do+   *     not return an error code.+   *+   *   - Close the recording session by calling the `close' method.  It+   *     returns an error code if the hints were invalid or something+   *     strange happened (e.g., memory shortage).+   *+   *   The hints accumulated in the object can later be used by the+   *   PostScript hinter.+   *+   */+  typedef struct T1_HintsRec_*  T1_Hints;+++  /*************************************************************************+   *+   * @type:+   *   T1_Hints_Funcs+   *+   * @description:+   *   A pointer to the @T1_Hints_FuncsRec structure that defines the API of+   *   a given @T1_Hints object.+   *+   */+  typedef const struct T1_Hints_FuncsRec_*  T1_Hints_Funcs;+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_OpenFunc+   *+   * @description:+   *   A method of the @T1_Hints class used to prepare it for a new Type 1+   *   hints recording session.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   * @note:+   *   You should always call the @T1_Hints_CloseFunc method in order to+   *   close an opened recording session.+   *+   */+  typedef void+  (*T1_Hints_OpenFunc)( T1_Hints  hints );+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_SetStemFunc+   *+   * @description:+   *   A method of the @T1_Hints class used to record a new horizontal or+   *   vertical stem.  This corresponds to the Type 1 `hstem' and `vstem'+   *   operators.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   *   dimension ::+   *     0 for horizontal stems (hstem), 1 for vertical ones (vstem).+   *+   *   coords ::+   *     Array of 2 coordinates in 16.16 format, used as (position,length)+   *     stem descriptor.+   *+   * @note:+   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use+   *   horizontal coordinates (x) for vertical stems (dim=1).+   *+   *   `coords[0]' is the absolute stem position (lowest coordinate);+   *   `coords[1]' is the length.+   *+   *   The length can be negative, in which case it must be either -20 or+   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1+   *   specification.+   *+   *   If the length is -21 (corresponding to a bottom ghost stem), then+   *   the real stem position is `coords[0]+coords[1]'.+   *+   */+  typedef void+  (*T1_Hints_SetStemFunc)( T1_Hints   hints,+                           FT_UInt    dimension,+                           FT_Fixed*  coords );+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_SetStem3Func+   *+   * @description:+   *   A method of the @T1_Hints class used to record three+   *   counter-controlled horizontal or vertical stems at once.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   *   dimension ::+   *     0 for horizontal stems, 1 for vertical ones.+   *+   *   coords ::+   *     An array of 6 values in 16.16 format, holding 3 (position,length)+   *     pairs for the counter-controlled stems.+   *+   * @note:+   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use+   *   horizontal coordinates (x) for vertical stems (dim=1).+   *+   *   The lengths cannot be negative (ghost stems are never+   *   counter-controlled).+   *+   */+  typedef void+  (*T1_Hints_SetStem3Func)( T1_Hints   hints,+                            FT_UInt    dimension,+                            FT_Fixed*  coords );+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_ResetFunc+   *+   * @description:+   *   A method of the @T1_Hints class used to reset the stems hints in a+   *   recording session.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   *   end_point ::+   *     The index of the last point in the input glyph in which the+   *     previously defined hints apply.+   *+   */+  typedef void+  (*T1_Hints_ResetFunc)( T1_Hints  hints,+                         FT_UInt   end_point );+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_CloseFunc+   *+   * @description:+   *   A method of the @T1_Hints class used to close a hint recording+   *   session.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   *   end_point ::+   *     The index of the last point in the input glyph.+   *+   * @return:+   *   FreeType error code.  0 means success.+   *+   * @note:+   *   The error code is set to indicate that an error occurred during the+   *   recording session.+   *+   */+  typedef FT_Error+  (*T1_Hints_CloseFunc)( T1_Hints  hints,+                         FT_UInt   end_point );+++  /*************************************************************************+   *+   * @functype:+   *   T1_Hints_ApplyFunc+   *+   * @description:+   *   A method of the @T1_Hints class used to apply hints to the+   *   corresponding glyph outline.  Must be called once all hints have been+   *   recorded.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 1 hints recorder.+   *+   *   outline ::+   *     A pointer to the target outline descriptor.+   *+   *   globals ::+   *     The hinter globals for this font.+   *+   *   hint_mode ::+   *     Hinting information.+   *+   * @return:+   *   FreeType error code.  0 means success.+   *+   * @note:+   *   On input, all points within the outline are in font coordinates. On+   *   output, they are in 1/64th of pixels.+   *+   *   The scaling transformation is taken from the `globals' object which+   *   must correspond to the same font as the glyph.+   *+   */+  typedef FT_Error+  (*T1_Hints_ApplyFunc)( T1_Hints        hints,+                         FT_Outline*     outline,+                         PSH_Globals     globals,+                         FT_Render_Mode  hint_mode );+++  /*************************************************************************+   *+   * @struct:+   *   T1_Hints_FuncsRec+   *+   * @description:+   *   The structure used to provide the API to @T1_Hints objects.+   *+   * @fields:+   *   hints ::+   *     A handle to the T1 Hints recorder.+   *+   *   open ::+   *     The function to open a recording session.+   *+   *   close ::+   *     The function to close a recording session.+   *+   *   stem ::+   *     The function to set a simple stem.+   *+   *   stem3 ::+   *     The function to set counter-controlled stems.+   *+   *   reset ::+   *     The function to reset stem hints.+   *+   *   apply ::+   *     The function to apply the hints to the corresponding glyph outline.+   *+   */+  typedef struct  T1_Hints_FuncsRec_+  {+    T1_Hints               hints;+    T1_Hints_OpenFunc      open;+    T1_Hints_CloseFunc     close;+    T1_Hints_SetStemFunc   stem;+    T1_Hints_SetStem3Func  stem3;+    T1_Hints_ResetFunc     reset;+    T1_Hints_ApplyFunc     apply;++  } T1_Hints_FuncsRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                  PUBLIC TYPE 2 HINTS RECORDER                 *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************+   *+   * @type:+   *   T2_Hints+   *+   * @description:+   *   This is a handle to an opaque structure used to record glyph hints+   *   from a Type 2 character glyph character string.+   *+   *   The methods used to operate on this object are defined by the+   *   @T2_Hints_FuncsRec structure.  Recording glyph hints is normally+   *   achieved through the following scheme:+   *+   *   - Open a new hint recording session by calling the `open' method.+   *     This rewinds the recorder and prepare it for new input.+   *+   *   - For each hint found in the glyph charstring, call the corresponding+   *     method (`stems', `hintmask', `counters').  Note that these+   *     functions do not return an error code.+   *+   *   - Close the recording session by calling the `close' method.  It+   *     returns an error code if the hints were invalid or something+   *     strange happened (e.g., memory shortage).+   *+   *   The hints accumulated in the object can later be used by the+   *   Postscript hinter.+   *+   */+  typedef struct T2_HintsRec_*  T2_Hints;+++  /*************************************************************************+   *+   * @type:+   *   T2_Hints_Funcs+   *+   * @description:+   *   A pointer to the @T2_Hints_FuncsRec structure that defines the API of+   *   a given @T2_Hints object.+   *+   */+  typedef const struct T2_Hints_FuncsRec_*  T2_Hints_Funcs;+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_OpenFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to prepare it for a new Type 2+   *   hints recording session.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   * @note:+   *   You should always call the @T2_Hints_CloseFunc method in order to+   *   close an opened recording session.+   *+   */+  typedef void+  (*T2_Hints_OpenFunc)( T2_Hints  hints );+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_StemsFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to set the table of stems in+   *   either the vertical or horizontal dimension.  Equivalent to the+   *   `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   *   dimension ::+   *     0 for horizontal stems (hstem), 1 for vertical ones (vstem).+   *+   *   count ::+   *     The number of stems.+   *+   *   coords ::+   *     An array of `count' (position,length) pairs in 16.16 format.+   *+   * @note:+   *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use+   *   horizontal coordinates (x) for vertical stems (dim=1).+   *+   *   There are `2*count' elements in the `coords' array.  Each even+   *   element is an absolute position in font units, each odd element is a+   *   length in font units.+   *+   *   A length can be negative, in which case it must be either -20 or+   *   -21.  It is interpreted as a `ghost' stem, according to the Type 1+   *   specification.+   *+   */+  typedef void+  (*T2_Hints_StemsFunc)( T2_Hints   hints,+                         FT_UInt    dimension,+                         FT_UInt    count,+                         FT_Fixed*  coordinates );+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_MaskFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to set a given hintmask (this+   *   corresponds to the `hintmask' Type 2 operator).+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   *   end_point ::+   *     The glyph index of the last point to which the previously defined+   *     or activated hints apply.+   *+   *   bit_count ::+   *     The number of bits in the hint mask.+   *+   *   bytes ::+   *     An array of bytes modelling the hint mask.+   *+   * @note:+   *   If the hintmask starts the charstring (before any glyph point+   *   definition), the value of `end_point' should be 0.+   *+   *   `bit_count' is the number of meaningful bits in the `bytes' array; it+   *   must be equal to the total number of hints defined so far (i.e.,+   *   horizontal+verticals).+   *+   *   The `bytes' array can come directly from the Type 2 charstring and+   *   respects the same format.+   *+   */+  typedef void+  (*T2_Hints_MaskFunc)( T2_Hints        hints,+                        FT_UInt         end_point,+                        FT_UInt         bit_count,+                        const FT_Byte*  bytes );+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_CounterFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to set a given counter mask+   *   (this corresponds to the `hintmask' Type 2 operator).+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   *   end_point ::+   *     A glyph index of the last point to which the previously defined or+   *     active hints apply.+   *+   *   bit_count ::+   *     The number of bits in the hint mask.+   *+   *   bytes ::+   *     An array of bytes modelling the hint mask.+   *+   * @note:+   *   If the hintmask starts the charstring (before any glyph point+   *   definition), the value of `end_point' should be 0.+   *+   *   `bit_count' is the number of meaningful bits in the `bytes' array; it+   *   must be equal to the total number of hints defined so far (i.e.,+   *   horizontal+verticals).+   *+   *    The `bytes' array can come directly from the Type 2 charstring and+   *    respects the same format.+   *+   */+  typedef void+  (*T2_Hints_CounterFunc)( T2_Hints        hints,+                           FT_UInt         bit_count,+                           const FT_Byte*  bytes );+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_CloseFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to close a hint recording+   *   session.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   *   end_point ::+   *     The index of the last point in the input glyph.+   *+   * @return:+   *   FreeType error code.  0 means success.+   *+   * @note:+   *   The error code is set to indicate that an error occurred during the+   *   recording session.+   *+   */+  typedef FT_Error+  (*T2_Hints_CloseFunc)( T2_Hints  hints,+                         FT_UInt   end_point );+++  /*************************************************************************+   *+   * @functype:+   *   T2_Hints_ApplyFunc+   *+   * @description:+   *   A method of the @T2_Hints class used to apply hints to the+   *   corresponding glyph outline.  Must be called after the `close'+   *   method.+   *+   * @input:+   *   hints ::+   *     A handle to the Type 2 hints recorder.+   *+   *   outline ::+   *     A pointer to the target outline descriptor.+   *+   *   globals ::+   *     The hinter globals for this font.+   *+   *   hint_mode ::+   *     Hinting information.+   *+   * @return:+   *   FreeType error code.  0 means success.+   *+   * @note:+   *   On input, all points within the outline are in font coordinates. On+   *   output, they are in 1/64th of pixels.+   *+   *   The scaling transformation is taken from the `globals' object which+   *   must correspond to the same font than the glyph.+   *+   */+  typedef FT_Error+  (*T2_Hints_ApplyFunc)( T2_Hints        hints,+                         FT_Outline*     outline,+                         PSH_Globals     globals,+                         FT_Render_Mode  hint_mode );+++  /*************************************************************************+   *+   * @struct:+   *   T2_Hints_FuncsRec+   *+   * @description:+   *   The structure used to provide the API to @T2_Hints objects.+   *+   * @fields:+   *   hints ::+   *     A handle to the T2 hints recorder object.+   *+   *   open ::+   *     The function to open a recording session.+   *+   *   close ::+   *     The function to close a recording session.+   *+   *   stems ::+   *     The function to set the dimension's stems table.+   *+   *   hintmask ::+   *     The function to set hint masks.+   *+   *   counter ::+   *     The function to set counter masks.+   *+   *   apply ::+   *     The function to apply the hints on the corresponding glyph outline.+   *+   */+  typedef struct  T2_Hints_FuncsRec_+  {+    T2_Hints              hints;+    T2_Hints_OpenFunc     open;+    T2_Hints_CloseFunc    close;+    T2_Hints_StemsFunc    stems;+    T2_Hints_MaskFunc     hintmask;+    T2_Hints_CounterFunc  counter;+    T2_Hints_ApplyFunc    apply;++  } T2_Hints_FuncsRec;+++  /* */+++  typedef struct  PSHinter_Interface_+  {+    PSH_Globals_Funcs  (*get_globals_funcs)( FT_Module  module );+    T1_Hints_Funcs     (*get_t1_funcs)     ( FT_Module  module );+    T2_Hints_Funcs     (*get_t2_funcs)     ( FT_Module  module );++  } PSHinter_Interface;++  typedef PSHinter_Interface*  PSHinter_Service;++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \+                                     get_t1_funcs_, get_t2_funcs_)           \+  static const PSHinter_Interface class_ =                                   \+  {                                                                          \+    get_globals_funcs_, get_t1_funcs_, get_t2_funcs_                         \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \+                                     get_t1_funcs_, get_t2_funcs_)           \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library,                                \+                          PSHinter_Interface*  clazz)                        \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    clazz->get_globals_funcs = get_globals_funcs_;                           \+    clazz->get_t1_funcs = get_t1_funcs_;                                     \+    clazz->get_t2_funcs = get_t2_funcs_;                                     \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++FT_END_HEADER++#endif /* __PSHINTS_H__ */+++/* END */
+ include/freetype/internal/services/svbdf.h view
@@ -0,0 +1,77 @@+/***************************************************************************/+/*                                                                         */+/*  svbdf.h                                                                */+/*                                                                         */+/*    The FreeType BDF services (specification).                           */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVBDF_H__+#define __SVBDF_H__++#include FT_BDF_H+#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_BDF  "bdf"++  typedef FT_Error+  (*FT_BDF_GetCharsetIdFunc)( FT_Face       face,+                              const char*  *acharset_encoding,+                              const char*  *acharset_registry );++  typedef FT_Error+  (*FT_BDF_GetPropertyFunc)( FT_Face           face,+                             const char*       prop_name,+                             BDF_PropertyRec  *aproperty );+++  FT_DEFINE_SERVICE( BDF )+  {+    FT_BDF_GetCharsetIdFunc  get_charset_id;+    FT_BDF_GetPropertyFunc   get_property;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \+  static const FT_Service_BDFRec class_ =                                \+  {                                                                      \+    get_charset_id_, get_property_                                       \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \+  void                                                                   \+  FT_Init_Class_##class_( FT_Service_BDFRec*  clazz )                    \+  {                                                                      \+    clazz->get_charset_id = get_charset_id_;                             \+    clazz->get_property = get_property_;                                 \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVBDF_H__ */+++/* END */
+ include/freetype/internal/services/svcid.h view
@@ -0,0 +1,83 @@+/***************************************************************************/+/*                                                                         */+/*  svcid.h                                                                */+/*                                                                         */+/*    The FreeType CID font services (specification).                      */+/*                                                                         */+/*  Copyright 2007, 2009 by Derek Clegg, Michael Toftdal.                  */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVCID_H__+#define __SVCID_H__++#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_CID  "CID"++  typedef FT_Error+  (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face       face,+                                               const char*  *registry,+                                               const char*  *ordering,+                                               FT_Int       *supplement );+  typedef FT_Error+  (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face   face,+                                         FT_Bool  *is_cid );+  typedef FT_Error+  (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face   face,+                                      FT_UInt   glyph_index,+                                      FT_UInt  *cid );++  FT_DEFINE_SERVICE( CID )+  {+    FT_CID_GetRegistryOrderingSupplementFunc  get_ros;+    FT_CID_GetIsInternallyCIDKeyedFunc        get_is_cid;+    FT_CID_GetCIDFromGlyphIndexFunc           get_cid_from_glyph_index;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \+        get_is_cid_, get_cid_from_glyph_index_ )                             \+  static const FT_Service_CIDRec class_ =                                    \+  {                                                                          \+    get_ros_, get_is_cid_, get_cid_from_glyph_index_                         \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \+        get_is_cid_, get_cid_from_glyph_index_ )                             \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library,                                \+                          FT_Service_CIDRec* clazz)                          \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    clazz->get_ros = get_ros_;                                               \+    clazz->get_is_cid = get_is_cid_;                                         \+    clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_;             \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVCID_H__ */+++/* END */
+ include/freetype/internal/services/svgldict.h view
@@ -0,0 +1,82 @@+/***************************************************************************/+/*                                                                         */+/*  svgldict.h                                                             */+/*                                                                         */+/*    The FreeType glyph dictionary services (specification).              */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVGLDICT_H__+#define __SVGLDICT_H__++#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++  /*+   *  A service used to retrieve glyph names, as well as to find the+   *  index of a given glyph name in a font.+   *+   */++#define FT_SERVICE_ID_GLYPH_DICT  "glyph-dict"+++  typedef FT_Error+  (*FT_GlyphDict_GetNameFunc)( FT_Face     face,+                               FT_UInt     glyph_index,+                               FT_Pointer  buffer,+                               FT_UInt     buffer_max );++  typedef FT_UInt+  (*FT_GlyphDict_NameIndexFunc)( FT_Face     face,+                                 FT_String*  glyph_name );+++  FT_DEFINE_SERVICE( GlyphDict )+  {+    FT_GlyphDict_GetNameFunc    get_name;+    FT_GlyphDict_NameIndexFunc  name_index;  /* optional */+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \+  static const FT_Service_GlyphDictRec class_ =                        \+  {                                                                    \+    get_name_, name_index_                                             \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \+  void                                                                 \+  FT_Init_Class_##class_( FT_Library library,                          \+                          FT_Service_GlyphDictRec* clazz)              \+  {                                                                    \+    FT_UNUSED(library);                                                \+    clazz->get_name = get_name_;                                       \+    clazz->name_index = name_index_;                                   \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVGLDICT_H__ */
+ include/freetype/internal/services/svgxval.h view
@@ -0,0 +1,72 @@+/***************************************************************************/+/*                                                                         */+/*  svgxval.h                                                              */+/*                                                                         */+/*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */+/*                                                                         */+/*  Copyright 2004, 2005 by                                                */+/*  Masatake YAMATO, Red Hat K.K.,                                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/***************************************************************************/+/*                                                                         */+/* gxvalid is derived from both gxlayout module and otvalid module.        */+/* Development of gxlayout is supported by the Information-technology      */+/* Promotion Agency(IPA), Japan.                                           */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVGXVAL_H__+#define __SVGXVAL_H__++#include FT_GX_VALIDATE_H+#include FT_INTERNAL_VALIDATE_H++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_GX_VALIDATE           "truetypegx-validate"+#define FT_SERVICE_ID_CLASSICKERN_VALIDATE  "classickern-validate"++  typedef FT_Error+  (*gxv_validate_func)( FT_Face   face,+                        FT_UInt   gx_flags,+                        FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],+                        FT_UInt   table_length );+++  typedef FT_Error+  (*ckern_validate_func)( FT_Face   face,+                          FT_UInt   ckern_flags,+                          FT_Bytes  *ckern_table );+++  FT_DEFINE_SERVICE( GXvalidate )+  {+    gxv_validate_func  validate;+  };++  FT_DEFINE_SERVICE( CKERNvalidate )+  {+    ckern_validate_func  validate;+  };++  /* */+++FT_END_HEADER+++#endif /* __SVGXVAL_H__ */+++/* END */
+ include/freetype/internal/services/svkern.h view
@@ -0,0 +1,51 @@+/***************************************************************************/+/*                                                                         */+/*  svkern.h                                                               */+/*                                                                         */+/*    The FreeType Kerning service (specification).                        */+/*                                                                         */+/*  Copyright 2006 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVKERN_H__+#define __SVKERN_H__++#include FT_INTERNAL_SERVICE_H+#include FT_TRUETYPE_TABLES_H+++FT_BEGIN_HEADER++#define FT_SERVICE_ID_KERNING  "kerning"+++  typedef FT_Error+  (*FT_Kerning_TrackGetFunc)( FT_Face    face,+                              FT_Fixed   point_size,+                              FT_Int     degree,+                              FT_Fixed*  akerning );++  FT_DEFINE_SERVICE( Kerning )+  {+    FT_Kerning_TrackGetFunc  get_track;+  };++  /* */+++FT_END_HEADER+++#endif /* __SVKERN_H__ */+++/* END */
+ include/freetype/internal/services/svmm.h view
@@ -0,0 +1,104 @@+/***************************************************************************/+/*                                                                         */+/*  svmm.h                                                                 */+/*                                                                         */+/*    The FreeType Multiple Masters and GX var services (specification).   */+/*                                                                         */+/*  Copyright 2003, 2004 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVMM_H__+#define __SVMM_H__++#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++  /*+   *  A service used to manage multiple-masters data in a given face.+   *+   *  See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H).+   *+   */++#define FT_SERVICE_ID_MULTI_MASTERS  "multi-masters"+++  typedef FT_Error+  (*FT_Get_MM_Func)( FT_Face           face,+                     FT_Multi_Master*  master );++  typedef FT_Error+  (*FT_Get_MM_Var_Func)( FT_Face      face,+                         FT_MM_Var*  *master );++  typedef FT_Error+  (*FT_Set_MM_Design_Func)( FT_Face   face,+                            FT_UInt   num_coords,+                            FT_Long*  coords );++  typedef FT_Error+  (*FT_Set_Var_Design_Func)( FT_Face    face,+                             FT_UInt    num_coords,+                             FT_Fixed*  coords );++  typedef FT_Error+  (*FT_Set_MM_Blend_Func)( FT_Face   face,+                           FT_UInt   num_coords,+                           FT_Long*  coords );+++  FT_DEFINE_SERVICE( MultiMasters )+  {+    FT_Get_MM_Func          get_mm;+    FT_Set_MM_Design_Func   set_mm_design;+    FT_Set_MM_Blend_Func    set_mm_blend;+    FT_Get_MM_Var_Func      get_mm_var;+    FT_Set_Var_Design_Func  set_var_design;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \+        set_mm_blend_, get_mm_var_, set_var_design_)                         \+  static const FT_Service_MultiMastersRec class_ =                           \+  {                                                                          \+    get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_     \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \+        set_mm_blend_, get_mm_var_, set_var_design_)                         \+  void                                                                       \+  FT_Init_Class_##class_( FT_Service_MultiMastersRec*  clazz )               \+  {                                                                          \+    clazz->get_mm = get_mm_;                                                 \+    clazz->set_mm_design = set_mm_design_;                                   \+    clazz->set_mm_blend = set_mm_blend_;                                     \+    clazz->get_mm_var = get_mm_var_;                                         \+    clazz->set_var_design = set_var_design_;                                 \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER++#endif /* __SVMM_H__ */+++/* END */
+ include/freetype/internal/services/svotval.h view
@@ -0,0 +1,55 @@+/***************************************************************************/+/*                                                                         */+/*  svotval.h                                                              */+/*                                                                         */+/*    The FreeType OpenType validation service (specification).            */+/*                                                                         */+/*  Copyright 2004, 2006 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVOTVAL_H__+#define __SVOTVAL_H__++#include FT_OPENTYPE_VALIDATE_H+#include FT_INTERNAL_VALIDATE_H++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_OPENTYPE_VALIDATE  "opentype-validate"+++  typedef FT_Error+  (*otv_validate_func)( FT_Face volatile  face,+                        FT_UInt           ot_flags,+                        FT_Bytes         *base,+                        FT_Bytes         *gdef,+                        FT_Bytes         *gpos,+                        FT_Bytes         *gsub,+                        FT_Bytes         *jstf );+++  FT_DEFINE_SERVICE( OTvalidate )+  {+    otv_validate_func  validate;+  };++  /* */+++FT_END_HEADER+++#endif /* __SVOTVAL_H__ */+++/* END */
+ include/freetype/internal/services/svpfr.h view
@@ -0,0 +1,66 @@+/***************************************************************************/+/*                                                                         */+/*  svpfr.h                                                                */+/*                                                                         */+/*    Internal PFR service functions (specification).                      */+/*                                                                         */+/*  Copyright 2003, 2006 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVPFR_H__+#define __SVPFR_H__++#include FT_PFR_H+#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_PFR_METRICS  "pfr-metrics"+++  typedef FT_Error+  (*FT_PFR_GetMetricsFunc)( FT_Face    face,+                            FT_UInt   *aoutline,+                            FT_UInt   *ametrics,+                            FT_Fixed  *ax_scale,+                            FT_Fixed  *ay_scale );++  typedef FT_Error+  (*FT_PFR_GetKerningFunc)( FT_Face     face,+                            FT_UInt     left,+                            FT_UInt     right,+                            FT_Vector  *avector );++  typedef FT_Error+  (*FT_PFR_GetAdvanceFunc)( FT_Face   face,+                            FT_UInt   gindex,+                            FT_Pos   *aadvance );+++  FT_DEFINE_SERVICE( PfrMetrics )+  {+    FT_PFR_GetMetricsFunc  get_metrics;+    FT_PFR_GetKerningFunc  get_kerning;+    FT_PFR_GetAdvanceFunc  get_advance;++  };++ /* */++FT_END_HEADER++#endif /* __SVPFR_H__ */+++/* END */
+ include/freetype/internal/services/svpostnm.h view
@@ -0,0 +1,79 @@+/***************************************************************************/+/*                                                                         */+/*  svpostnm.h                                                             */+/*                                                                         */+/*    The FreeType PostScript name services (specification).               */+/*                                                                         */+/*  Copyright 2003, 2007 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVPOSTNM_H__+#define __SVPOSTNM_H__++#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER++  /*+   *  A trivial service used to retrieve the PostScript name of a given+   *  font when available.  The `get_name' field should never be NULL.+   *+   *  The corresponding function can return NULL to indicate that the+   *  PostScript name is not available.+   *+   *  The name is owned by the face and will be destroyed with it.+   */++#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME  "postscript-font-name"+++  typedef const char*+  (*FT_PsName_GetFunc)( FT_Face  face );+++  FT_DEFINE_SERVICE( PsFontName )+  {+    FT_PsName_GetFunc  get_ps_font_name;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \+  static const FT_Service_PsFontNameRec class_ =                   \+  {                                                                \+    get_ps_font_name_                                              \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \+  void                                                             \+  FT_Init_Class_##class_( FT_Library library,                      \+                          FT_Service_PsFontNameRec* clazz)         \+  {                                                                \+    FT_UNUSED(library);                                            \+    clazz->get_ps_font_name = get_ps_font_name_;                   \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVPOSTNM_H__ */+++/* END */
+ include/freetype/internal/services/svpscmap.h view
@@ -0,0 +1,164 @@+/***************************************************************************/+/*                                                                         */+/*  svpscmap.h                                                             */+/*                                                                         */+/*    The FreeType PostScript charmap service (specification).             */+/*                                                                         */+/*  Copyright 2003, 2006 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVPSCMAP_H__+#define __SVPSCMAP_H__++#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_POSTSCRIPT_CMAPS  "postscript-cmaps"+++  /*+   *  Adobe glyph name to unicode value.+   */+  typedef FT_UInt32+  (*PS_Unicode_ValueFunc)( const char*  glyph_name );++  /*+   *  Macintosh name id to glyph name.  NULL if invalid index.+   */+  typedef const char*+  (*PS_Macintosh_NameFunc)( FT_UInt  name_index );++  /*+   *  Adobe standard string ID to glyph name.  NULL if invalid index.+   */+  typedef const char*+  (*PS_Adobe_Std_StringsFunc)( FT_UInt  string_index );+++  /*+   *  Simple unicode -> glyph index charmap built from font glyph names+   *  table.+   */+  typedef struct  PS_UniMap_+  {+    FT_UInt32  unicode;      /* bit 31 set: is glyph variant */+    FT_UInt    glyph_index;++  } PS_UniMap;+++  typedef struct PS_UnicodesRec_*  PS_Unicodes;++  typedef struct  PS_UnicodesRec_+  {+    FT_CMapRec  cmap;+    FT_UInt     num_maps;+    PS_UniMap*  maps;++  } PS_UnicodesRec;+++  /*+   *  A function which returns a glyph name for a given index.  Returns+   *  NULL if invalid index.+   */+  typedef const char*+  (*PS_GetGlyphNameFunc)( FT_Pointer  data,+                          FT_UInt     string_index );++  /*+   *  A function used to release the glyph name returned by+   *  PS_GetGlyphNameFunc, when needed+   */+  typedef void+  (*PS_FreeGlyphNameFunc)( FT_Pointer  data,+                           const char*  name );++  typedef FT_Error+  (*PS_Unicodes_InitFunc)( FT_Memory             memory,+                           PS_Unicodes           unicodes,+                           FT_UInt               num_glyphs,+                           PS_GetGlyphNameFunc   get_glyph_name,+                           PS_FreeGlyphNameFunc  free_glyph_name,+                           FT_Pointer            glyph_data );++  typedef FT_UInt+  (*PS_Unicodes_CharIndexFunc)( PS_Unicodes  unicodes,+                                FT_UInt32    unicode );++  typedef FT_UInt32+  (*PS_Unicodes_CharNextFunc)( PS_Unicodes  unicodes,+                               FT_UInt32   *unicode );+++  FT_DEFINE_SERVICE( PsCMaps )+  {+    PS_Unicode_ValueFunc       unicode_value;++    PS_Unicodes_InitFunc       unicodes_init;+    PS_Unicodes_CharIndexFunc  unicodes_char_index;+    PS_Unicodes_CharNextFunc   unicodes_char_next;++    PS_Macintosh_NameFunc      macintosh_name;+    PS_Adobe_Std_StringsFunc   adobe_std_strings;+    const unsigned short*      adobe_std_encoding;+    const unsigned short*      adobe_expert_encoding;+  };+++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \+        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \+        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \+  static const FT_Service_PsCMapsRec class_ =                                \+  {                                                                          \+    unicode_value_, unicodes_init_,                                          \+    unicodes_char_index_, unicodes_char_next_, macintosh_name_,              \+    adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_          \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \+        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \+        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library,                                \+                          FT_Service_PsCMapsRec* clazz)                      \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    clazz->unicode_value = unicode_value_;                                   \+    clazz->unicodes_init = unicodes_init_;                                   \+    clazz->unicodes_char_index = unicodes_char_index_;                       \+    clazz->unicodes_char_next = unicodes_char_next_;                         \+    clazz->macintosh_name = macintosh_name_;                                 \+    clazz->adobe_std_strings = adobe_std_strings_;                           \+    clazz->adobe_std_encoding = adobe_std_encoding_;                         \+    clazz->adobe_expert_encoding = adobe_expert_encoding_;                   \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVPSCMAP_H__ */+++/* END */
+ include/freetype/internal/services/svpsinfo.h view
@@ -0,0 +1,92 @@+/***************************************************************************/+/*                                                                         */+/*  svpsinfo.h                                                             */+/*                                                                         */+/*    The FreeType PostScript info service (specification).                */+/*                                                                         */+/*  Copyright 2003, 2004, 2009 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVPSINFO_H__+#define __SVPSINFO_H__++#include FT_INTERNAL_SERVICE_H+#include FT_INTERNAL_TYPE1_TYPES_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_POSTSCRIPT_INFO  "postscript-info"+++  typedef FT_Error+  (*PS_GetFontInfoFunc)( FT_Face          face,+                         PS_FontInfoRec*  afont_info );++  typedef FT_Error+  (*PS_GetFontExtraFunc)( FT_Face           face,+                          PS_FontExtraRec*  afont_extra );++  typedef FT_Int+  (*PS_HasGlyphNamesFunc)( FT_Face   face );++  typedef FT_Error+  (*PS_GetFontPrivateFunc)( FT_Face         face,+                            PS_PrivateRec*  afont_private );+++  FT_DEFINE_SERVICE( PsInfo )+  {+    PS_GetFontInfoFunc     ps_get_font_info;+    PS_GetFontExtraFunc    ps_get_font_extra;+    PS_HasGlyphNamesFunc   ps_has_glyph_names;+    PS_GetFontPrivateFunc  ps_get_font_private;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \+        ps_get_font_extra_, has_glyph_names_, get_font_private_) \+  static const FT_Service_PsInfoRec class_ =                     \+  {                                                              \+    get_font_info_, ps_get_font_extra_, has_glyph_names_,        \+    get_font_private_                                            \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \+        ps_get_font_extra_, has_glyph_names_, get_font_private_) \+  void                                                           \+  FT_Init_Class_##class_( FT_Library library,                    \+                          FT_Service_PsInfoRec*  clazz)          \+  {                                                              \+    FT_UNUSED(library);                                          \+    clazz->ps_get_font_info = get_font_info_;                    \+    clazz->ps_get_font_extra = ps_get_font_extra_;               \+    clazz->ps_has_glyph_names = has_glyph_names_;                \+    clazz->ps_get_font_private = get_font_private_;              \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVPSINFO_H__ */+++/* END */
+ include/freetype/internal/services/svsfnt.h view
@@ -0,0 +1,102 @@+/***************************************************************************/+/*                                                                         */+/*  svsfnt.h                                                               */+/*                                                                         */+/*    The FreeType SFNT table loading service (specification).             */+/*                                                                         */+/*  Copyright 2003, 2004 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVSFNT_H__+#define __SVSFNT_H__++#include FT_INTERNAL_SERVICE_H+#include FT_TRUETYPE_TABLES_H+++FT_BEGIN_HEADER+++  /*+   *  SFNT table loading service.+   */++#define FT_SERVICE_ID_SFNT_TABLE  "sfnt-table"+++  /*+   * Used to implement FT_Load_Sfnt_Table().+   */+  typedef FT_Error+  (*FT_SFNT_TableLoadFunc)( FT_Face    face,+                            FT_ULong   tag,+                            FT_Long    offset,+                            FT_Byte*   buffer,+                            FT_ULong*  length );++  /*+   * Used to implement FT_Get_Sfnt_Table().+   */+  typedef void*+  (*FT_SFNT_TableGetFunc)( FT_Face      face,+                           FT_Sfnt_Tag  tag );+++  /*+   * Used to implement FT_Sfnt_Table_Info().+   */+  typedef FT_Error+  (*FT_SFNT_TableInfoFunc)( FT_Face    face,+                            FT_UInt    idx,+                            FT_ULong  *tag,+                            FT_ULong  *offset,+                            FT_ULong  *length );+++  FT_DEFINE_SERVICE( SFNT_Table )+  {+    FT_SFNT_TableLoadFunc  load_table;+    FT_SFNT_TableGetFunc   get_table;+    FT_SFNT_TableInfoFunc  table_info;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_)  \+  static const FT_Service_SFNT_TableRec class_ =                     \+  {                                                                  \+    load_, get_, info_                                               \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \+  void                                                              \+  FT_Init_Class_##class_( FT_Service_SFNT_TableRec*  clazz )        \+  {                                                                 \+    clazz->load_table = load_;                                      \+    clazz->get_table = get_;                                        \+    clazz->table_info = info_;                                      \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER+++#endif /* __SVSFNT_H__ */+++/* END */
+ include/freetype/internal/services/svttcmap.h view
@@ -0,0 +1,106 @@+/***************************************************************************/+/*                                                                         */+/*  svttcmap.h                                                             */+/*                                                                         */+/*    The FreeType TrueType/sfnt cmap extra information service.           */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  Masatake YAMATO, Redhat K.K.                                           */+/*                                                                         */+/*  Copyright 2003, 2008 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/* Development of this service is support of+   Information-technology Promotion Agency, Japan. */++#ifndef __SVTTCMAP_H__+#define __SVTTCMAP_H__++#include FT_INTERNAL_SERVICE_H+#include FT_TRUETYPE_TABLES_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_TT_CMAP "tt-cmaps"+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_CMapInfo                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to store TrueType/sfnt specific cmap information  */+  /*    which is not covered by the generic @FT_CharMap structure.  This   */+  /*    structure can be accessed with the @FT_Get_TT_CMap_Info function.  */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    language ::                                                        */+  /*      The language ID used in Mac fonts.  Definitions of values are in */+  /*      freetype/ttnameid.h.                                             */+  /*                                                                       */+  /*    format ::                                                          */+  /*      The cmap format.  OpenType 1.5 defines the formats 0 (byte       */+  /*      encoding table), 2~(high-byte mapping through table), 4~(segment */+  /*      mapping to delta values), 6~(trimmed table mapping), 8~(mixed    */+  /*      16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented   */+  /*      coverage), and 14 (Unicode Variation Sequences).                 */+  /*                                                                       */+  typedef struct  TT_CMapInfo_+  {+    FT_ULong language;+    FT_Long  format;++  } TT_CMapInfo;+++  typedef FT_Error+  (*TT_CMap_Info_GetFunc)( FT_CharMap    charmap,+                           TT_CMapInfo  *cmap_info );+++  FT_DEFINE_SERVICE( TTCMaps )+  {+    TT_CMap_Info_GetFunc  get_cmap_info;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_)  \+  static const FT_Service_TTCMapsRec class_ =                 \+  {                                                           \+    get_cmap_info_                                            \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \+  void                                                       \+  FT_Init_Class_##class_( FT_Library library,                \+                          FT_Service_TTCMapsRec*  clazz)     \+  {                                                          \+    FT_UNUSED(library);                                      \+    clazz->get_cmap_info = get_cmap_info_;                   \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER++#endif /* __SVTTCMAP_H__ */+++/* END */
+ include/freetype/internal/services/svtteng.h view
@@ -0,0 +1,53 @@+/***************************************************************************/+/*                                                                         */+/*  svtteng.h                                                              */+/*                                                                         */+/*    The FreeType TrueType engine query service (specification).          */+/*                                                                         */+/*  Copyright 2006 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVTTENG_H__+#define __SVTTENG_H__++#include FT_INTERNAL_SERVICE_H+#include FT_MODULE_H+++FT_BEGIN_HEADER+++  /*+   *  SFNT table loading service.+   */++#define FT_SERVICE_ID_TRUETYPE_ENGINE  "truetype-engine"++  /*+   * Used to implement FT_Get_TrueType_Engine_Type+   */++  FT_DEFINE_SERVICE( TrueTypeEngine )+  {+    FT_TrueTypeEngineType  engine_type;+  };++  /* */+++FT_END_HEADER+++#endif /* __SVTTENG_H__ */+++/* END */
+ include/freetype/internal/services/svttglyf.h view
@@ -0,0 +1,67 @@+/***************************************************************************/+/*                                                                         */+/*  svttglyf.h                                                             */+/*                                                                         */+/*    The FreeType TrueType glyph service.                                 */+/*                                                                         */+/*  Copyright 2007 by David Turner.                                        */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#ifndef __SVTTGLYF_H__+#define __SVTTGLYF_H__++#include FT_INTERNAL_SERVICE_H+#include FT_TRUETYPE_TABLES_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_TT_GLYF "tt-glyf"+++  typedef FT_ULong+  (*TT_Glyf_GetLocationFunc)( FT_Face    face,+                              FT_UInt    gindex,+                              FT_ULong  *psize );++  FT_DEFINE_SERVICE( TTGlyf )+  {+    TT_Glyf_GetLocationFunc  get_location;+  };++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \+  static const FT_Service_TTGlyfRec class_ =                  \+  {                                                           \+    get_location_                                             \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \+  void                                                        \+  FT_Init_Class_##class_( FT_Service_TTGlyfRec*  clazz )      \+  {                                                           \+    clazz->get_location = get_location_;                      \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  /* */+++FT_END_HEADER++#endif /* __SVTTGLYF_H__ */+++/* END */
+ include/freetype/internal/services/svwinfnt.h view
@@ -0,0 +1,50 @@+/***************************************************************************/+/*                                                                         */+/*  svwinfnt.h                                                             */+/*                                                                         */+/*    The FreeType Windows FNT/FONT service (specification).               */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVWINFNT_H__+#define __SVWINFNT_H__++#include FT_INTERNAL_SERVICE_H+#include FT_WINFONTS_H+++FT_BEGIN_HEADER+++#define FT_SERVICE_ID_WINFNT  "winfonts"++  typedef FT_Error+  (*FT_WinFnt_GetHeaderFunc)( FT_Face               face,+                              FT_WinFNT_HeaderRec  *aheader );+++  FT_DEFINE_SERVICE( WinFnt )+  {+    FT_WinFnt_GetHeaderFunc  get_header;+  };++  /* */+++FT_END_HEADER+++#endif /* __SVWINFNT_H__ */+++/* END */
+ include/freetype/internal/services/svxf86nm.h view
@@ -0,0 +1,55 @@+/***************************************************************************/+/*                                                                         */+/*  svxf86nm.h                                                             */+/*                                                                         */+/*    The FreeType XFree86 services (specification only).                  */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SVXF86NM_H__+#define __SVXF86NM_H__++#include FT_INTERNAL_SERVICE_H+++FT_BEGIN_HEADER+++  /*+   *  A trivial service used to return the name of a face's font driver,+   *  according to the XFree86 nomenclature.  Note that the service data+   *  is a simple constant string pointer.+   */++#define FT_SERVICE_ID_XF86_NAME  "xf86-driver-name"++#define FT_XF86_FORMAT_TRUETYPE  "TrueType"+#define FT_XF86_FORMAT_TYPE_1    "Type 1"+#define FT_XF86_FORMAT_BDF       "BDF"+#define FT_XF86_FORMAT_PCF       "PCF"+#define FT_XF86_FORMAT_TYPE_42   "Type 42"+#define FT_XF86_FORMAT_CID       "CID Type 1"+#define FT_XF86_FORMAT_CFF       "CFF"+#define FT_XF86_FORMAT_PFR       "PFR"+#define FT_XF86_FORMAT_WINFNT    "Windows FNT"++  /* */+++FT_END_HEADER+++#endif /* __SVXF86NM_H__ */+++/* END */
+ include/freetype/internal/sfnt.h view
@@ -0,0 +1,897 @@+/***************************************************************************/+/*                                                                         */+/*  sfnt.h                                                                 */+/*                                                                         */+/*    High-level `sfnt' driver interface (specification).                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SFNT_H__+#define __SFNT_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Init_Face_Func                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    First part of the SFNT face object initialization.  This finds     */+  /*    the face in a SFNT file or collection, and load its format tag in  */+  /*    face->format_tag.                                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream     :: The input stream.                                    */+  /*                                                                       */+  /*    face       :: A handle to the target face object.                  */+  /*                                                                       */+  /*    face_index :: The index of the TrueType font, if we are opening a  */+  /*                  collection.                                          */+  /*                                                                       */+  /*    num_params :: The number of additional parameters.                 */+  /*                                                                       */+  /*    params     :: Optional additional parameters.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be at the font file's origin.               */+  /*                                                                       */+  /*    This function recognizes fonts embedded in a `TrueType             */+  /*    collection'.                                                       */+  /*                                                                       */+  /*    Once the format tag has been validated by the font driver, it      */+  /*    should then call the TT_Load_Face_Func() callback to read the rest */+  /*    of the SFNT tables in the object.                                  */+  /*                                                                       */+  typedef FT_Error+  (*TT_Init_Face_Func)( FT_Stream      stream,+                        TT_Face        face,+                        FT_Int         face_index,+                        FT_Int         num_params,+                        FT_Parameter*  params );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Face_Func                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Second part of the SFNT face object initialization.  This loads    */+  /*    the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the    */+  /*    face object.                                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream     :: The input stream.                                    */+  /*                                                                       */+  /*    face       :: A handle to the target face object.                  */+  /*                                                                       */+  /*    face_index :: The index of the TrueType font, if we are opening a  */+  /*                  collection.                                          */+  /*                                                                       */+  /*    num_params :: The number of additional parameters.                 */+  /*                                                                       */+  /*    params     :: Optional additional parameters.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function must be called after TT_Init_Face_Func().            */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Face_Func)( FT_Stream      stream,+                        TT_Face        face,+                        FT_Int         face_index,+                        FT_Int         num_params,+                        FT_Parameter*  params );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Done_Face_Func                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A callback used to delete the common SFNT data from a face.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the target face object.                        */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function does NOT destroy the face object.                    */+  /*                                                                       */+  typedef void+  (*TT_Done_Face_Func)( TT_Face  face );+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_SFNT_HeaderRec_Func                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the header of a SFNT font file.  Supports collections.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face       :: A handle to the target face object.                  */+  /*                                                                       */+  /*    stream     :: The input stream.                                    */+  /*                                                                       */+  /*    face_index :: The index of the TrueType font, if we are opening a  */+  /*                  collection.                                          */+  /*                                                                       */+  /* <Output>                                                              */+  /*    sfnt       :: The SFNT header.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be at the font file's origin.               */+  /*                                                                       */+  /*    This function recognizes fonts embedded in a `TrueType             */+  /*    collection'.                                                       */+  /*                                                                       */+  /*    This function checks that the header is valid by looking at the    */+  /*    values of `search_range', `entry_selector', and `range_shift'.     */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_SFNT_HeaderRec_Func)( TT_Face      face,+                                  FT_Stream    stream,+                                  FT_Long      face_index,+                                  SFNT_Header  sfnt );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Directory_Func                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the table directory into a face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /*    sfnt   :: The SFNT header.                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be on the first byte after the 4-byte font  */+  /*    format tag.  This is the case just after a call to                 */+  /*    TT_Load_Format_Tag().                                              */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Directory_Func)( TT_Face      face,+                             FT_Stream    stream,+                             SFNT_Header  sfnt );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Any_Func                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load any font table into client memory.                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: The face object to look for.                             */+  /*                                                                       */+  /*    tag    :: The tag of table to load.  Use the value 0 if you want   */+  /*              to access the whole font file, else set this parameter   */+  /*              to a valid TrueType table tag that you can forge with    */+  /*              the MAKE_TT_TAG macro.                                   */+  /*                                                                       */+  /*    offset :: The starting offset in the table (or the file if         */+  /*              tag == 0).                                               */+  /*                                                                       */+  /*    length :: The address of the decision variable:                    */+  /*                                                                       */+  /*                If length == NULL:                                     */+  /*                  Loads the whole table.  Returns an error if          */+  /*                  `offset' == 0!                                       */+  /*                                                                       */+  /*                If *length == 0:                                       */+  /*                  Exits immediately; returning the length of the given */+  /*                  table or of the font file, depending on the value of */+  /*                  `tag'.                                               */+  /*                                                                       */+  /*                If *length != 0:                                       */+  /*                  Loads the next `length' bytes of table or font,      */+  /*                  starting at offset `offset' (in table or font too).  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    buffer :: The address of target buffer.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    TrueType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Any_Func)( TT_Face    face,+                       FT_ULong   tag,+                       FT_Long    offset,+                       FT_Byte   *buffer,+                       FT_ULong*  length );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Find_SBit_Image_Func                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Check whether an embedded bitmap (an `sbit') exists for a given    */+  /*    glyph, at a given strike.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face          :: The target face object.                           */+  /*                                                                       */+  /*    glyph_index   :: The glyph index.                                  */+  /*                                                                       */+  /*    strike_index  :: The current strike index.                         */+  /*                                                                       */+  /* <Output>                                                              */+  /*    arange        :: The SBit range containing the glyph index.        */+  /*                                                                       */+  /*    astrike       :: The SBit strike containing the glyph index.       */+  /*                                                                       */+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns                    */+  /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */+  /*    glyph.                                                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Find_SBit_Image_Func)( TT_Face          face,+                              FT_UInt          glyph_index,+                              FT_ULong         strike_index,+                              TT_SBit_Range   *arange,+                              TT_SBit_Strike  *astrike,+                              FT_ULong        *aglyph_offset );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_SBit_Metrics_Func                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Get the big metrics for a given embedded bitmap.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream      :: The input stream.                                   */+  /*                                                                       */+  /*    range       :: The SBit range containing the glyph.                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    big_metrics :: A big SBit metrics structure for the glyph.         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be positioned at the glyph's offset within  */+  /*    the `EBDT' table before the call.                                  */+  /*                                                                       */+  /*    If the image format uses variable metrics, the stream cursor is    */+  /*    positioned just after the metrics header in the `EBDT' table on    */+  /*    function exit.                                                     */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_SBit_Metrics_Func)( FT_Stream        stream,+                                TT_SBit_Range    range,+                                TT_SBit_Metrics  metrics );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_SBit_Image_Func                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load a given glyph sbit image from the font resource.  This also   */+  /*    returns its metrics.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face ::                                                            */+  /*      The target face object.                                          */+  /*                                                                       */+  /*    strike_index ::                                                    */+  /*      The strike index.                                                */+  /*                                                                       */+  /*    glyph_index ::                                                     */+  /*      The current glyph index.                                         */+  /*                                                                       */+  /*    load_flags ::                                                      */+  /*      The current load flags.                                          */+  /*                                                                       */+  /*    stream ::                                                          */+  /*      The input stream.                                                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    amap ::                                                            */+  /*      The target pixmap.                                               */+  /*                                                                       */+  /*    ametrics ::                                                        */+  /*      A big sbit metrics structure for the glyph image.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns an error if no     */+  /*    glyph sbit exists for the index.                                   */+  /*                                                                       */+  /*  <Note>                                                               */+  /*    The `map.buffer' field is always freed before the glyph is loaded. */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_SBit_Image_Func)( TT_Face              face,+                              FT_ULong             strike_index,+                              FT_UInt              glyph_index,+                              FT_UInt              load_flags,+                              FT_Stream            stream,+                              FT_Bitmap           *amap,+                              TT_SBit_MetricsRec  *ametrics );+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Set_SBit_Strike_OldFunc                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Select an sbit strike for a given size request.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face          :: The target face object.                           */+  /*                                                                       */+  /*    req           :: The size request.                                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    astrike_index :: The index of the sbit strike.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns an error if no     */+  /*    sbit strike exists for the selected ppem values.                   */+  /*                                                                       */+  typedef FT_Error+  (*TT_Set_SBit_Strike_OldFunc)( TT_Face    face,+                                 FT_UInt    x_ppem,+                                 FT_UInt    y_ppem,+                                 FT_ULong*  astrike_index );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_CharMap_Load_Func                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads a given TrueType character map into memory.                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the parent face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the current stream object.                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    cmap   :: A pointer to a cmap object.                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The function assumes that the stream is already in use (i.e.,      */+  /*    opened).  In case of error, all partially allocated tables are     */+  /*    released.                                                          */+  /*                                                                       */+  typedef FT_Error+  (*TT_CharMap_Load_Func)( TT_Face    face,+                           void*      cmap,+                           FT_Stream  input );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_CharMap_Free_Func                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroys a character mapping table.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the parent face object.                        */+  /*                                                                       */+  /*    cmap :: A handle to a cmap object.                                 */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_CharMap_Free_Func)( TT_Face       face,+                           void*         cmap );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Set_SBit_Strike_Func                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Select an sbit strike for a given size request.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face          :: The target face object.                           */+  /*                                                                       */+  /*    req           :: The size request.                                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    astrike_index :: The index of the sbit strike.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns an error if no     */+  /*    sbit strike exists for the selected ppem values.                   */+  /*                                                                       */+  typedef FT_Error+  (*TT_Set_SBit_Strike_Func)( TT_Face          face,+                              FT_Size_Request  req,+                              FT_ULong*        astrike_index );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Strike_Metrics_Func                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the metrics of a given strike.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face          :: The target face object.                           */+  /*                                                                       */+  /*    strike_index  :: The strike index.                                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    metrics       :: the metrics of the strike.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns an error if no     */+  /*    such sbit strike exists.                                           */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Strike_Metrics_Func)( TT_Face           face,+                                  FT_ULong          strike_index,+                                  FT_Size_Metrics*  metrics );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Get_PS_Name_Func                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Get the PostScript glyph name of a glyph.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    idx  :: The glyph index.                                           */+  /*                                                                       */+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */+  /*              of error, otherwise it is a pointer to the glyph name.   */+  /*                                                                       */+  /*              You must not modify the returned string!                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Get_PS_Name_Func)( TT_Face      face,+                          FT_UInt      idx,+                          FT_String**  PSname );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Metrics_Func                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load a metrics table, which is a table with a horizontal and a     */+  /*    vertical version.                                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: A handle to the target face object.                    */+  /*                                                                       */+  /*    stream   :: The input stream.                                      */+  /*                                                                       */+  /*    vertical :: A boolean flag.  If set, load the vertical one.        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Metrics_Func)( TT_Face    face,+                           FT_Stream  stream,+                           FT_Bool    vertical );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Get_Metrics_Func                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the horizontal or vertical header in a face object.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: A handle to the target face object.                    */+  /*                                                                       */+  /*    stream   :: The input stream.                                      */+  /*                                                                       */+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Get_Metrics_Func)( TT_Face     face,+                          FT_Bool     vertical,+                          FT_UInt     gindex,+                          FT_Short*   abearing,+                          FT_UShort*  aadvance );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Load_Table_Func                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load a given TrueType table.                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The function uses `face->goto_table' to seek the stream to the     */+  /*    start of the table, except while loading the font directory.       */+  /*                                                                       */+  typedef FT_Error+  (*TT_Load_Table_Func)( TT_Face    face,+                         FT_Stream  stream );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Free_Table_Func                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Free a given TrueType table.                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the target face object.                        */+  /*                                                                       */+  typedef void+  (*TT_Free_Table_Func)( TT_Face  face );+++  /*+   * @functype:+   *    TT_Face_GetKerningFunc+   *+   * @description:+   *    Return the horizontal kerning value between two glyphs.+   *+   * @input:+   *    face        :: A handle to the source face object.+   *    left_glyph  :: The left glyph index.+   *    right_glyph :: The right glyph index.+   *+   * @return:+   *    The kerning value in font units.+   */+  typedef FT_Int+  (*TT_Face_GetKerningFunc)( TT_Face  face,+                             FT_UInt  left_glyph,+                             FT_UInt  right_glyph );+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    SFNT_Interface                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure holds pointers to the functions used to load and    */+  /*    free the basic tables that are required in a `sfnt' font file.     */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    Check the various xxx_Func() descriptions for details.             */+  /*                                                                       */+  typedef struct  SFNT_Interface_+  {+    TT_Loader_GotoTableFunc      goto_table;++    TT_Init_Face_Func            init_face;+    TT_Load_Face_Func            load_face;+    TT_Done_Face_Func            done_face;+    FT_Module_Requester          get_interface;++    TT_Load_Any_Func             load_any;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    TT_Load_SFNT_HeaderRec_Func  load_sfnt_header;+    TT_Load_Directory_Func       load_directory;+#endif++    /* these functions are called by `load_face' but they can also  */+    /* be called from external modules, if there is a need to do so */+    TT_Load_Table_Func           load_head;+    TT_Load_Metrics_Func         load_hhea;+    TT_Load_Table_Func           load_cmap;+    TT_Load_Table_Func           load_maxp;+    TT_Load_Table_Func           load_os2;+    TT_Load_Table_Func           load_post;++    TT_Load_Table_Func           load_name;+    TT_Free_Table_Func           free_name;++    /* optional tables */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    TT_Load_Table_Func           load_hdmx_stub;+    TT_Free_Table_Func           free_hdmx_stub;+#endif++    /* this field was called `load_kerning' up to version 2.1.10 */+    TT_Load_Table_Func           load_kern;++    TT_Load_Table_Func           load_gasp;+    TT_Load_Table_Func           load_pclt;++    /* see `ttload.h'; this field was called `load_bitmap_header' up to */+    /* version 2.1.10                                                   */+    TT_Load_Table_Func           load_bhed;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++    /* see `ttsbit.h' */+    TT_Set_SBit_Strike_OldFunc   set_sbit_strike_stub;+    TT_Load_Table_Func           load_sbits_stub;++    /*+     *  The following two fields appeared in version 2.1.8, and were placed+     *  between `load_sbits' and `load_sbit_image'.  We support them as a+     *  special exception since they are used by Xfont library within the+     *  X.Org xserver, and because the probability that other rogue clients+     *  use the other version 2.1.7 fields below is _extremely_ low.+     *+     *  Note that this forces us to disable an interesting memory-saving+     *  optimization though...+     */++    TT_Find_SBit_Image_Func      find_sbit_image;+    TT_Load_SBit_Metrics_Func    load_sbit_metrics;++#endif++    TT_Load_SBit_Image_Func      load_sbit_image;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    TT_Free_Table_Func           free_sbits_stub;+#endif++    /* see `ttpost.h' */+    TT_Get_PS_Name_Func          get_psname;+    TT_Free_Table_Func           free_psnames;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    TT_CharMap_Load_Func         load_charmap_stub;+    TT_CharMap_Free_Func         free_charmap_stub;+#endif++    /* starting here, the structure differs from version 2.1.7 */++    /* this field was introduced in version 2.1.8, named `get_psname' */+    TT_Face_GetKerningFunc       get_kerning;++    /* new elements introduced after version 2.1.10 */++    /* load the font directory, i.e., the offset table and */+    /* the table directory                                 */+    TT_Load_Table_Func           load_font_dir;+    TT_Load_Metrics_Func         load_hmtx;++    TT_Load_Table_Func           load_eblc;+    TT_Free_Table_Func           free_eblc;++    TT_Set_SBit_Strike_Func      set_sbit_strike;+    TT_Load_Strike_Metrics_Func  load_strike_metrics;++    TT_Get_Metrics_Func          get_metrics;++  } SFNT_Interface;+++  /* transitional */+  typedef SFNT_Interface*   SFNT_Service;++#ifndef FT_CONFIG_OPTION_PIC++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \+  a, +#else+  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a)+#endif+#define FT_INTERNAL(a) \+  a, ++#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \+    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \+    load_any_, load_sfnt_header_, load_directory_, load_head_,               \+    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \+    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \+    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \+    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \+    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \+    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \+    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \+    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \+  static const SFNT_Interface class_ =                                       \+  {                                                                          \+    FT_INTERNAL(goto_table_) \+    FT_INTERNAL(init_face_) \+    FT_INTERNAL(load_face_) \+    FT_INTERNAL(done_face_) \+    FT_INTERNAL(get_interface_) \+    FT_INTERNAL(load_any_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \+    FT_INTERNAL(load_head_) \+    FT_INTERNAL(load_hhea_) \+    FT_INTERNAL(load_cmap_) \+    FT_INTERNAL(load_maxp_) \+    FT_INTERNAL(load_os2_) \+    FT_INTERNAL(load_post_) \+    FT_INTERNAL(load_name_) \+    FT_INTERNAL(free_name_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \+    FT_INTERNAL(load_kern_) \+    FT_INTERNAL(load_gasp_) \+    FT_INTERNAL(load_pclt_) \+    FT_INTERNAL(load_bhed_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \+    FT_INTERNAL(load_sbit_image_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \+    FT_INTERNAL(get_psname_) \+    FT_INTERNAL(free_psnames_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \+    FT_INTERNAL(get_kerning_) \+    FT_INTERNAL(load_font_dir_) \+    FT_INTERNAL(load_hmtx_) \+    FT_INTERNAL(load_eblc_) \+    FT_INTERNAL(free_eblc_) \+    FT_INTERNAL(set_sbit_strike_) \+    FT_INTERNAL(load_strike_metrics_) \+    FT_INTERNAL(get_metrics_) \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \+  clazz->a = a_;+#else+  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_)+#endif+#define FT_INTERNAL(a, a_) \+  clazz->a = a_;++#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \+    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \+    load_any_, load_sfnt_header_, load_directory_, load_head_,               \+    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \+    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \+    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \+    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \+    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \+    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \+    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \+    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \+  void                                                                       \+  FT_Init_Class_##class_( FT_Library library, SFNT_Interface*  clazz )       \+  {                                                                          \+    FT_UNUSED(library);                                                      \+    FT_INTERNAL(goto_table,goto_table_) \+    FT_INTERNAL(init_face,init_face_) \+    FT_INTERNAL(load_face,load_face_) \+    FT_INTERNAL(done_face,done_face_) \+    FT_INTERNAL(get_interface,get_interface_) \+    FT_INTERNAL(load_any,load_any_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \+    FT_INTERNAL(load_head,load_head_) \+    FT_INTERNAL(load_hhea,load_hhea_) \+    FT_INTERNAL(load_cmap,load_cmap_) \+    FT_INTERNAL(load_maxp,load_maxp_) \+    FT_INTERNAL(load_os2,load_os2_) \+    FT_INTERNAL(load_post,load_post_) \+    FT_INTERNAL(load_name,load_name_) \+    FT_INTERNAL(free_name,free_name_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \+    FT_INTERNAL(load_kern,load_kern_) \+    FT_INTERNAL(load_gasp,load_gasp_) \+    FT_INTERNAL(load_pclt,load_pclt_) \+    FT_INTERNAL(load_bhed,load_bhed_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \+    FT_INTERNAL(load_sbit_image,load_sbit_image_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \+    FT_INTERNAL(get_psname,get_psname_) \+    FT_INTERNAL(free_psnames,free_psnames_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \+    FT_INTERNAL(get_kerning,get_kerning_) \+    FT_INTERNAL(load_font_dir,load_font_dir_) \+    FT_INTERNAL(load_hmtx,load_hmtx_) \+    FT_INTERNAL(load_eblc,load_eblc_) \+    FT_INTERNAL(free_eblc,free_eblc_) \+    FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \+    FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \+    FT_INTERNAL(get_metrics,get_metrics_) \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++FT_END_HEADER++#endif /* __SFNT_H__ */+++/* END */
+ include/freetype/internal/t1types.h view
@@ -0,0 +1,270 @@+/***************************************************************************/+/*                                                                         */+/*  t1types.h                                                              */+/*                                                                         */+/*    Basic Type1/Type2 type definitions and interface (specification      */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1TYPES_H__+#define __T1TYPES_H__+++#include <ft2build.h>+#include FT_TYPE1_TABLES_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+#include FT_INTERNAL_SERVICE_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***              REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS              ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    T1_EncodingRec                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure modeling a custom encoding.                            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_chars  :: The number of character codes in the encoding.       */+  /*                  Usually 256.                                         */+  /*                                                                       */+  /*    code_first :: The lowest valid character code in the encoding.     */+  /*                                                                       */+  /*    code_last  :: The highest valid character code in the encoding     */+  /*                  + 1. When equal to code_first there are no valid     */+  /*                  character codes.                                     */+  /*                                                                       */+  /*    char_index :: An array of corresponding glyph indices.             */+  /*                                                                       */+  /*    char_name  :: An array of corresponding glyph names.               */+  /*                                                                       */+  typedef struct  T1_EncodingRecRec_+  {+    FT_Int       num_chars;+    FT_Int       code_first;+    FT_Int       code_last;++    FT_UShort*   char_index;+    FT_String**  char_name;++  } T1_EncodingRec, *T1_Encoding;+++  typedef enum  T1_EncodingType_+  {+    T1_ENCODING_TYPE_NONE = 0,+    T1_ENCODING_TYPE_ARRAY,+    T1_ENCODING_TYPE_STANDARD,+    T1_ENCODING_TYPE_ISOLATIN1,+    T1_ENCODING_TYPE_EXPERT++  } T1_EncodingType;+++  /* used to hold extra data of PS_FontInfoRec that+   * cannot be stored in the publicly defined structure.+   *+   * Note these can't be blended with multiple-masters.+   */+  typedef struct  PS_FontExtraRec_+  {+    FT_UShort  fs_type;++  } PS_FontExtraRec;+++  typedef struct  T1_FontRec_+  {+    PS_FontInfoRec   font_info;         /* font info dictionary   */+    PS_FontExtraRec  font_extra;        /* font info extra fields */+    PS_PrivateRec    private_dict;      /* private dictionary     */+    FT_String*       font_name;         /* top-level dictionary   */++    T1_EncodingType  encoding_type;+    T1_EncodingRec   encoding;++    FT_Byte*         subrs_block;+    FT_Byte*         charstrings_block;+    FT_Byte*         glyph_names_block;++    FT_Int           num_subrs;+    FT_Byte**        subrs;+    FT_PtrDist*      subrs_len;++    FT_Int           num_glyphs;+    FT_String**      glyph_names;       /* array of glyph names       */+    FT_Byte**        charstrings;       /* array of glyph charstrings */+    FT_PtrDist*      charstrings_len;++    FT_Byte          paint_type;+    FT_Byte          font_type;+    FT_Matrix        font_matrix;+    FT_Vector        font_offset;+    FT_BBox          font_bbox;+    FT_Long          font_id;++    FT_Fixed         stroke_width;++  } T1_FontRec, *T1_Font;+++  typedef struct  CID_SubrsRec_+  {+    FT_UInt    num_subrs;+    FT_Byte**  code;++  } CID_SubrsRec, *CID_Subrs;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                AFM FONT INFORMATION STRUCTURES                    ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct  AFM_TrackKernRec_+  {+    FT_Int    degree;+    FT_Fixed  min_ptsize;+    FT_Fixed  min_kern;+    FT_Fixed  max_ptsize;+    FT_Fixed  max_kern;++  } AFM_TrackKernRec, *AFM_TrackKern;++  typedef struct  AFM_KernPairRec_+  {+    FT_Int  index1;+    FT_Int  index2;+    FT_Int  x;+    FT_Int  y;++  } AFM_KernPairRec, *AFM_KernPair;++  typedef struct  AFM_FontInfoRec_+  {+    FT_Bool        IsCIDFont;+    FT_BBox        FontBBox;+    FT_Fixed       Ascender;+    FT_Fixed       Descender;+    AFM_TrackKern  TrackKerns;   /* free if non-NULL */+    FT_Int         NumTrackKern;+    AFM_KernPair   KernPairs;    /* free if non-NULL */+    FT_Int         NumKernPair;++  } AFM_FontInfoRec, *AFM_FontInfo;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                ORIGINAL T1_FACE CLASS DEFINITION                  ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  typedef struct T1_FaceRec_*   T1_Face;+  typedef struct CID_FaceRec_*  CID_Face;+++  typedef struct  T1_FaceRec_+  {+    FT_FaceRec      root;+    T1_FontRec      type1;+    const void*     psnames;+    const void*     psaux;+    const void*     afm_data;+    FT_CharMapRec   charmaprecs[2];+    FT_CharMap      charmaps[2];++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    PS_Unicodes     unicode_map;+#endif++    /* support for Multiple Masters fonts */+    PS_Blend        blend;++    /* undocumented, optional: indices of subroutines that express      */+    /* the NormalizeDesignVector and the ConvertDesignVector procedure, */+    /* respectively, as Type 2 charstrings; -1 if keywords not present  */+    FT_Int           ndv_idx;+    FT_Int           cdv_idx;++    /* undocumented, optional: has the same meaning as len_buildchar */+    /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25    */+    FT_UInt          len_buildchar;+    FT_Long*         buildchar;++    /* since version 2.1 - interface to PostScript hinter */+    const void*     pshinter;++  } T1_FaceRec;+++  typedef struct  CID_FaceRec_+  {+    FT_FaceRec       root;+    void*            psnames;+    void*            psaux;+    CID_FaceInfoRec  cid;+    PS_FontExtraRec  font_extra;+#if 0+    void*            afm_data;+#endif+    CID_Subrs        subrs;++    /* since version 2.1 - interface to PostScript hinter */+    void*            pshinter;++    /* since version 2.1.8, but was originally positioned after `afm_data' */+    FT_Byte*         binary_data; /* used if hex data has been converted */+    FT_Stream        cid_stream;++  } CID_FaceRec;+++FT_END_HEADER++#endif /* __T1TYPES_H__ */+++/* END */
+ include/freetype/internal/tttypes.h view
@@ -0,0 +1,1543 @@+/***************************************************************************/+/*                                                                         */+/*  tttypes.h                                                              */+/*                                                                         */+/*    Basic SFNT/TrueType type definitions and interface (specification    */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTTYPES_H__+#define __TTTYPES_H__+++#include <ft2build.h>+#include FT_TRUETYPE_TABLES_H+#include FT_INTERNAL_OBJECTS_H++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include FT_MULTIPLE_MASTERS_H+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***             REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TTC_HeaderRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    TrueType collection header.  This table contains the offsets of    */+  /*    the font headers of each distinct TrueType face in the file.       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    tag     :: Must be `ttc ' to indicate a TrueType collection.       */+  /*                                                                       */+  /*    version :: The version number.                                     */+  /*                                                                       */+  /*    count   :: The number of faces in the collection.  The             */+  /*               specification says this should be an unsigned long, but */+  /*               we use a signed long since we need the value -1 for     */+  /*               specific purposes.                                      */+  /*                                                                       */+  /*    offsets :: The offsets of the font headers, one per face.          */+  /*                                                                       */+  typedef struct  TTC_HeaderRec_+  {+    FT_ULong   tag;+    FT_Fixed   version;+    FT_Long    count;+    FT_ULong*  offsets;++  } TTC_HeaderRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    SFNT_HeaderRec                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    SFNT file format header.                                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    format_tag     :: The font format tag.                             */+  /*                                                                       */+  /*    num_tables     :: The number of tables in file.                    */+  /*                                                                       */+  /*    search_range   :: Must be `16 * (max power of 2 <= num_tables)'.   */+  /*                                                                       */+  /*    entry_selector :: Must be log2 of `search_range / 16'.             */+  /*                                                                       */+  /*    range_shift    :: Must be `num_tables * 16 - search_range'.        */+  /*                                                                       */+  typedef struct  SFNT_HeaderRec_+  {+    FT_ULong   format_tag;+    FT_UShort  num_tables;+    FT_UShort  search_range;+    FT_UShort  entry_selector;+    FT_UShort  range_shift;++    FT_ULong   offset;  /* not in file */++  } SFNT_HeaderRec, *SFNT_Header;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_TableRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This structure describes a given table of a TrueType font.         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    Tag      :: A four-bytes tag describing the table.                 */+  /*                                                                       */+  /*    CheckSum :: The table checksum.  This value can be ignored.        */+  /*                                                                       */+  /*    Offset   :: The offset of the table from the start of the TrueType */+  /*                font in its resource.                                  */+  /*                                                                       */+  /*    Length   :: The table length (in bytes).                           */+  /*                                                                       */+  typedef struct  TT_TableRec_+  {+    FT_ULong  Tag;        /*        table type */+    FT_ULong  CheckSum;   /*    table checksum */+    FT_ULong  Offset;     /* table file offset */+    FT_ULong  Length;     /*      table length */++  } TT_TableRec, *TT_Table;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_LongMetricsRec                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure modeling the long metrics of the `hmtx' and `vmtx'     */+  /*    TrueType tables.  The values are expressed in font units.          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    advance :: The advance width or height for the glyph.              */+  /*                                                                       */+  /*    bearing :: The left-side or top-side bearing for the glyph.        */+  /*                                                                       */+  typedef struct  TT_LongMetricsRec_+  {+    FT_UShort  advance;+    FT_Short   bearing;++  } TT_LongMetricsRec, *TT_LongMetrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    TT_ShortMetrics                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple type to model the short metrics of the `hmtx' and `vmtx'  */+  /*    tables.                                                            */+  /*                                                                       */+  typedef FT_Short  TT_ShortMetrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_NameEntryRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure modeling TrueType name records.  Name records are used */+  /*    to store important strings like family name, style name,           */+  /*    copyright, etc. in _localized_ versions (i.e., language, encoding, */+  /*    etc).                                                              */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    platformID   :: The ID of the name's encoding platform.            */+  /*                                                                       */+  /*    encodingID   :: The platform-specific ID for the name's encoding.  */+  /*                                                                       */+  /*    languageID   :: The platform-specific ID for the name's language.  */+  /*                                                                       */+  /*    nameID       :: The ID specifying what kind of name this is.       */+  /*                                                                       */+  /*    stringLength :: The length of the string in bytes.                 */+  /*                                                                       */+  /*    stringOffset :: The offset to the string in the `name' table.      */+  /*                                                                       */+  /*    string       :: A pointer to the string's bytes.  Note that these  */+  /*                    are usually UTF-16 encoded characters.             */+  /*                                                                       */+  typedef struct  TT_NameEntryRec_+  {+    FT_UShort  platformID;+    FT_UShort  encodingID;+    FT_UShort  languageID;+    FT_UShort  nameID;+    FT_UShort  stringLength;+    FT_ULong   stringOffset;++    /* this last field is not defined in the spec */+    /* but used by the FreeType engine            */++    FT_Byte*   string;++  } TT_NameEntryRec, *TT_NameEntry;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_NameTableRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure modeling the TrueType name table.                      */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    format         :: The format of the name table.                    */+  /*                                                                       */+  /*    numNameRecords :: The number of names in table.                    */+  /*                                                                       */+  /*    storageOffset  :: The offset of the name table in the `name'       */+  /*                      TrueType table.                                  */+  /*                                                                       */+  /*    names          :: An array of name records.                        */+  /*                                                                       */+  /*    stream         :: the file's input stream.                         */+  /*                                                                       */+  typedef struct  TT_NameTableRec_+  {+    FT_UShort         format;+    FT_UInt           numNameRecords;+    FT_UInt           storageOffset;+    TT_NameEntryRec*  names;+    FT_Stream         stream;++  } TT_NameTableRec, *TT_NameTable;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***             OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_GaspRangeRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A tiny structure used to model a gasp range according to the       */+  /*    TrueType specification.                                            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    maxPPEM  :: The maximum ppem value to which `gaspFlag' applies.    */+  /*                                                                       */+  /*    gaspFlag :: A flag describing the grid-fitting and anti-aliasing   */+  /*                modes to be used.                                      */+  /*                                                                       */+  typedef struct  TT_GaspRangeRec_+  {+    FT_UShort  maxPPEM;+    FT_UShort  gaspFlag;++  } TT_GaspRangeRec, *TT_GaspRange;+++#define TT_GASP_GRIDFIT  0x01+#define TT_GASP_DOGRAY   0x02+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_GaspRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure modeling the TrueType `gasp' table used to specify     */+  /*    grid-fitting and anti-aliasing behaviour.                          */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    version    :: The version number.                                  */+  /*                                                                       */+  /*    numRanges  :: The number of gasp ranges in table.                  */+  /*                                                                       */+  /*    gaspRanges :: An array of gasp ranges.                             */+  /*                                                                       */+  typedef struct  TT_Gasp_+  {+    FT_UShort     version;+    FT_UShort     numRanges;+    TT_GaspRange  gaspRanges;++  } TT_GaspRec;+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_HdmxEntryRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A small structure used to model the pre-computed widths of a given */+  /*    size.  They are found in the `hdmx' table.                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    ppem      :: The pixels per EM value at which these metrics apply. */+  /*                                                                       */+  /*    max_width :: The maximum advance width for this metric.            */+  /*                                                                       */+  /*    widths    :: An array of widths.  Note: These are 8-bit bytes.     */+  /*                                                                       */+  typedef struct  TT_HdmxEntryRec_+  {+    FT_Byte   ppem;+    FT_Byte   max_width;+    FT_Byte*  widths;++  } TT_HdmxEntryRec, *TT_HdmxEntry;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_HdmxRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model the `hdmx' table, which contains         */+  /*    pre-computed widths for a set of given sizes/dimensions.           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    version     :: The version number.                                 */+  /*                                                                       */+  /*    num_records :: The number of hdmx records.                         */+  /*                                                                       */+  /*    records     :: An array of hdmx records.                           */+  /*                                                                       */+  typedef struct  TT_HdmxRec_+  {+    FT_UShort     version;+    FT_Short      num_records;+    TT_HdmxEntry  records;++  } TT_HdmxRec, *TT_Hdmx;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Kern0_PairRec                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a kerning pair for the kerning table     */+  /*    format 0.  The engine now loads this table if it finds one in the  */+  /*    font file.                                                         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    left  :: The index of the left glyph in pair.                      */+  /*                                                                       */+  /*    right :: The index of the right glyph in pair.                     */+  /*                                                                       */+  /*    value :: The kerning distance.  A positive value spaces the        */+  /*             glyphs, a negative one makes them closer.                 */+  /*                                                                       */+  typedef struct  TT_Kern0_PairRec_+  {+    FT_UShort  left;   /* index of left  glyph in pair */+    FT_UShort  right;  /* index of right glyph in pair */+    FT_FWord   value;  /* kerning value                */++  } TT_Kern0_PairRec, *TT_Kern0_Pair;++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                    EMBEDDED BITMAPS SUPPORT                       ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_MetricsRec                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to hold the big metrics of a given glyph bitmap   */+  /*    in a TrueType or OpenType font.  These are usually found in the    */+  /*    `EBDT' (Microsoft) or `bloc' (Apple) table.                        */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    height       :: The glyph height in pixels.                        */+  /*                                                                       */+  /*    width        :: The glyph width in pixels.                         */+  /*                                                                       */+  /*    horiBearingX :: The horizontal left bearing.                       */+  /*                                                                       */+  /*    horiBearingY :: The horizontal top bearing.                        */+  /*                                                                       */+  /*    horiAdvance  :: The horizontal advance.                            */+  /*                                                                       */+  /*    vertBearingX :: The vertical left bearing.                         */+  /*                                                                       */+  /*    vertBearingY :: The vertical top bearing.                          */+  /*                                                                       */+  /*    vertAdvance  :: The vertical advance.                              */+  /*                                                                       */+  typedef struct  TT_SBit_MetricsRec_+  {+    FT_Byte  height;+    FT_Byte  width;++    FT_Char  horiBearingX;+    FT_Char  horiBearingY;+    FT_Byte  horiAdvance;++    FT_Char  vertBearingX;+    FT_Char  vertBearingY;+    FT_Byte  vertAdvance;++  } TT_SBit_MetricsRec, *TT_SBit_Metrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_SmallMetricsRec                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to hold the small metrics of a given glyph bitmap */+  /*    in a TrueType or OpenType font.  These are usually found in the    */+  /*    `EBDT' (Microsoft) or the `bdat' (Apple) table.                    */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    height   :: The glyph height in pixels.                            */+  /*                                                                       */+  /*    width    :: The glyph width in pixels.                             */+  /*                                                                       */+  /*    bearingX :: The left-side bearing.                                 */+  /*                                                                       */+  /*    bearingY :: The top-side bearing.                                  */+  /*                                                                       */+  /*    advance  :: The advance width or height.                           */+  /*                                                                       */+  typedef struct  TT_SBit_Small_Metrics_+  {+    FT_Byte  height;+    FT_Byte  width;++    FT_Char  bearingX;+    FT_Char  bearingY;+    FT_Byte  advance;++  } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_LineMetricsRec                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to describe the text line metrics of a given      */+  /*    bitmap strike, for either a horizontal or vertical layout.         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    ascender                :: The ascender in pixels.                 */+  /*                                                                       */+  /*    descender               :: The descender in pixels.                */+  /*                                                                       */+  /*    max_width               :: The maximum glyph width in pixels.      */+  /*                                                                       */+  /*    caret_slope_enumerator  :: Rise of the caret slope, typically set  */+  /*                               to 1 for non-italic fonts.              */+  /*                                                                       */+  /*    caret_slope_denominator :: Rise of the caret slope, typically set  */+  /*                               to 0 for non-italic fonts.              */+  /*                                                                       */+  /*    caret_offset            :: Offset in pixels to move the caret for  */+  /*                               proper positioning.                     */+  /*                                                                       */+  /*    min_origin_SB           :: Minimum of horiBearingX (resp.          */+  /*                               vertBearingY).                          */+  /*    min_advance_SB          :: Minimum of                              */+  /*                                                                       */+  /*                                 horizontal advance -                  */+  /*                                   ( horiBearingX + width )            */+  /*                                                                       */+  /*                               resp.                                   */+  /*                                                                       */+  /*                                 vertical advance -                    */+  /*                                   ( vertBearingY + height )           */+  /*                                                                       */+  /*    max_before_BL           :: Maximum of horiBearingY (resp.          */+  /*                               vertBearingY).                          */+  /*                                                                       */+  /*    min_after_BL            :: Minimum of                              */+  /*                                                                       */+  /*                                 horiBearingY - height                 */+  /*                                                                       */+  /*                               resp.                                   */+  /*                                                                       */+  /*                                 vertBearingX - width                  */+  /*                                                                       */+  /*    pads                    :: Unused (to make the size of the record  */+  /*                               a multiple of 32 bits.                  */+  /*                                                                       */+  typedef struct  TT_SBit_LineMetricsRec_+  {+    FT_Char  ascender;+    FT_Char  descender;+    FT_Byte  max_width;+    FT_Char  caret_slope_numerator;+    FT_Char  caret_slope_denominator;+    FT_Char  caret_offset;+    FT_Char  min_origin_SB;+    FT_Char  min_advance_SB;+    FT_Char  max_before_BL;+    FT_Char  min_after_BL;+    FT_Char  pads[2];++  } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_RangeRec                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A TrueType/OpenType subIndexTable as defined in the `EBLC'         */+  /*    (Microsoft) or `bloc' (Apple) tables.                              */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    first_glyph   :: The first glyph index in the range.               */+  /*                                                                       */+  /*    last_glyph    :: The last glyph index in the range.                */+  /*                                                                       */+  /*    index_format  :: The format of index table.  Valid values are 1    */+  /*                     to 5.                                             */+  /*                                                                       */+  /*    image_format  :: The format of `EBDT' image data.                  */+  /*                                                                       */+  /*    image_offset  :: The offset to image data in `EBDT'.               */+  /*                                                                       */+  /*    image_size    :: For index formats 2 and 5.  This is the size in   */+  /*                     bytes of each glyph bitmap.                       */+  /*                                                                       */+  /*    big_metrics   :: For index formats 2 and 5.  This is the big       */+  /*                     metrics for each glyph bitmap.                    */+  /*                                                                       */+  /*    num_glyphs    :: For index formats 4 and 5.  This is the number of */+  /*                     glyphs in the code array.                         */+  /*                                                                       */+  /*    glyph_offsets :: For index formats 1 and 3.                        */+  /*                                                                       */+  /*    glyph_codes   :: For index formats 4 and 5.                        */+  /*                                                                       */+  /*    table_offset  :: The offset of the index table in the `EBLC'       */+  /*                     table.  Only used during strike loading.          */+  /*                                                                       */+  typedef struct  TT_SBit_RangeRec_+  {+    FT_UShort           first_glyph;+    FT_UShort           last_glyph;++    FT_UShort           index_format;+    FT_UShort           image_format;+    FT_ULong            image_offset;++    FT_ULong            image_size;+    TT_SBit_MetricsRec  metrics;+    FT_ULong            num_glyphs;++    FT_ULong*           glyph_offsets;+    FT_UShort*          glyph_codes;++    FT_ULong            table_offset;++  } TT_SBit_RangeRec, *TT_SBit_Range;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_StrikeRec                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used describe a given bitmap strike in the `EBLC'      */+  /*    (Microsoft) or `bloc' (Apple) tables.                              */+  /*                                                                       */+  /* <Fields>                                                              */+  /*   num_index_ranges :: The number of index ranges.                     */+  /*                                                                       */+  /*   index_ranges     :: An array of glyph index ranges.                 */+  /*                                                                       */+  /*   color_ref        :: Unused.  `color_ref' is put in for future       */+  /*                       enhancements, but these fields are already      */+  /*                       in use by other platforms (e.g. Newton).        */+  /*                       For details, please see                         */+  /*                                                                       */+  /*                         http://fonts.apple.com/                       */+  /*                                TTRefMan/RM06/Chap6bloc.html           */+  /*                                                                       */+  /*   hori             :: The line metrics for horizontal layouts.        */+  /*                                                                       */+  /*   vert             :: The line metrics for vertical layouts.          */+  /*                                                                       */+  /*   start_glyph      :: The lowest glyph index for this strike.         */+  /*                                                                       */+  /*   end_glyph        :: The highest glyph index for this strike.        */+  /*                                                                       */+  /*   x_ppem           :: The number of horizontal pixels per EM.         */+  /*                                                                       */+  /*   y_ppem           :: The number of vertical pixels per EM.           */+  /*                                                                       */+  /*   bit_depth        :: The bit depth.  Valid values are 1, 2, 4,       */+  /*                       and 8.                                          */+  /*                                                                       */+  /*   flags            :: Is this a vertical or horizontal strike?  For   */+  /*                       details, please see                             */+  /*                                                                       */+  /*                         http://fonts.apple.com/                       */+  /*                                TTRefMan/RM06/Chap6bloc.html           */+  /*                                                                       */+  typedef struct  TT_SBit_StrikeRec_+  {+    FT_Int                  num_ranges;+    TT_SBit_Range           sbit_ranges;+    FT_ULong                ranges_offset;++    FT_ULong                color_ref;++    TT_SBit_LineMetricsRec  hori;+    TT_SBit_LineMetricsRec  vert;++    FT_UShort               start_glyph;+    FT_UShort               end_glyph;++    FT_Byte                 x_ppem;+    FT_Byte                 y_ppem;++    FT_Byte                 bit_depth;+    FT_Char                 flags;++  } TT_SBit_StrikeRec, *TT_SBit_Strike;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_ComponentRec                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A simple structure to describe a compound sbit element.            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    glyph_code :: The element's glyph index.                           */+  /*                                                                       */+  /*    x_offset   :: The element's left bearing.                          */+  /*                                                                       */+  /*    y_offset   :: The element's top bearing.                           */+  /*                                                                       */+  typedef struct  TT_SBit_ComponentRec_+  {+    FT_UShort  glyph_code;+    FT_Char    x_offset;+    FT_Char    y_offset;++  } TT_SBit_ComponentRec, *TT_SBit_Component;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_SBit_ScaleRec                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used describe a given bitmap scaling table, as defined */+  /*    in the `EBSC' table.                                               */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    hori              :: The horizontal line metrics.                  */+  /*                                                                       */+  /*    vert              :: The vertical line metrics.                    */+  /*                                                                       */+  /*    x_ppem            :: The number of horizontal pixels per EM.       */+  /*                                                                       */+  /*    y_ppem            :: The number of vertical pixels per EM.         */+  /*                                                                       */+  /*    x_ppem_substitute :: Substitution x_ppem value.                    */+  /*                                                                       */+  /*    y_ppem_substitute :: Substitution y_ppem value.                    */+  /*                                                                       */+  typedef struct  TT_SBit_ScaleRec_+  {+    TT_SBit_LineMetricsRec  hori;+    TT_SBit_LineMetricsRec  vert;++    FT_Byte                 x_ppem;+    FT_Byte                 y_ppem;++    FT_Byte                 x_ppem_substitute;+    FT_Byte                 y_ppem_substitute;++  } TT_SBit_ScaleRec, *TT_SBit_Scale;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                  POSTSCRIPT GLYPH NAMES SUPPORT                   ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Post_20Rec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Postscript names sub-table, format 2.0.  Stores the PS name of     */+  /*    each glyph in the font face.                                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_glyphs    :: The number of named glyphs in the table.          */+  /*                                                                       */+  /*    num_names     :: The number of PS names stored in the table.       */+  /*                                                                       */+  /*    glyph_indices :: The indices of the glyphs in the names arrays.    */+  /*                                                                       */+  /*    glyph_names   :: The PS names not in Mac Encoding.                 */+  /*                                                                       */+  typedef struct  TT_Post_20Rec_+  {+    FT_UShort   num_glyphs;+    FT_UShort   num_names;+    FT_UShort*  glyph_indices;+    FT_Char**   glyph_names;++  } TT_Post_20Rec, *TT_Post_20;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Post_25Rec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Postscript names sub-table, format 2.5.  Stores the PS name of     */+  /*    each glyph in the font face.                                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_glyphs :: The number of glyphs in the table.                   */+  /*                                                                       */+  /*    offsets    :: An array of signed offsets in a normal Mac           */+  /*                  Postscript name encoding.                            */+  /*                                                                       */+  typedef struct  TT_Post_25_+  {+    FT_UShort  num_glyphs;+    FT_Char*   offsets;++  } TT_Post_25Rec, *TT_Post_25;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Post_NamesRec                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Postscript names table, either format 2.0 or 2.5.                  */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    loaded    :: A flag to indicate whether the PS names are loaded.   */+  /*                                                                       */+  /*    format_20 :: The sub-table used for format 2.0.                    */+  /*                                                                       */+  /*    format_25 :: The sub-table used for format 2.5.                    */+  /*                                                                       */+  typedef struct  TT_Post_NamesRec_+  {+    FT_Bool  loaded;++    union+    {+      TT_Post_20Rec  format_20;+      TT_Post_25Rec  format_25;++    } names;++  } TT_Post_NamesRec, *TT_Post_Names;+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                    GX VARIATION TABLE SUPPORT                     ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+  typedef struct GX_BlendRec_  *GX_Blend;+#endif++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***              EMBEDDED BDF PROPERTIES TABLE SUPPORT                ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /*+   * These types are used to support a `BDF ' table that isn't part of the+   * official TrueType specification.  It is mainly used in SFNT-based+   * bitmap fonts that were generated from a set of BDF fonts.+   *+   * The format of the table is as follows.+   *+   *   USHORT   version      `BDF ' table version number, should be 0x0001.+   *   USHORT   strikeCount  Number of strikes (bitmap sizes) in this table.+   *   ULONG    stringTable  Offset (from start of BDF table) to string+   *                         table.+   *+   * This is followed by an array of `strikeCount' descriptors, having the+   * following format.+   *+   *   USHORT   ppem         Vertical pixels per EM for this strike.+   *   USHORT   numItems     Number of items for this strike (properties and+   *                         atoms).  Maximum is 255.+   *+   * This array in turn is followed by `strikeCount' value sets.  Each+   * `value set' is an array of `numItems' items with the following format.+   *+   *   ULONG    item_name    Offset in string table to item name.+   *   USHORT   item_type    The item type.  Possible values are+   *                            0 => string (e.g., COMMENT)+   *                            1 => atom   (e.g., FONT or even SIZE)+   *                            2 => int32+   *                            3 => uint32+   *                         0x10 => A flag to indicate a properties.  This+   *                                 is ORed with the above values.+   *   ULONG    item_value   For strings  => Offset into string table without+   *                                         the corresponding double quotes.+   *                         For atoms    => Offset into string table.+   *                         For integers => Direct value.+   *+   * All strings in the string table consist of bytes and are+   * zero-terminated.+   *+   */++#ifdef TT_CONFIG_OPTION_BDF++  typedef struct  TT_BDFRec_+  {+    FT_Byte*   table;+    FT_Byte*   table_end;+    FT_Byte*   strings;+    FT_ULong   strings_size;+    FT_UInt    num_strikes;+    FT_Bool    loaded;++  } TT_BDFRec, *TT_BDF;++#endif /* TT_CONFIG_OPTION_BDF */++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***                                                                   ***/+  /***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/+  /***                                                                   ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This structure/class is defined here because it is common to the      */+  /* following formats: TTF, OpenType-TT, and OpenType-CFF.                */+  /*                                                                       */+  /* Note, however, that the classes TT_Size and TT_GlyphSlot are not      */+  /* shared between font drivers, and are thus defined in `ttobjs.h'.      */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    TT_Face                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a TrueType face/font object.  A TT_Face encapsulates   */+  /*    the resolution and scaling independent parts of a TrueType font    */+  /*    resource.                                                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The TT_Face structure is also used as a `parent class' for the     */+  /*    OpenType-CFF class (T2_Face).                                      */+  /*                                                                       */+  typedef struct TT_FaceRec_*  TT_Face;+++  /* a function type used for the truetype bytecode interpreter hooks */+  typedef FT_Error+  (*TT_Interpreter)( void*  exec_context );++  /* forward declaration */+  typedef struct TT_LoaderRec_*  TT_Loader;+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Loader_GotoTableFunc                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Seeks a stream to the start of a given TrueType table.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    tag    :: A 4-byte tag used to name the table.                     */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    length :: The length of the table in bytes.  Set to 0 if not       */+  /*              needed.                                                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be at the font file's origin.               */+  /*                                                                       */+  typedef FT_Error+  (*TT_Loader_GotoTableFunc)( TT_Face    face,+                              FT_ULong   tag,+                              FT_Stream  stream,+                              FT_ULong*  length );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Loader_StartGlyphFunc                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Seeks a stream to the start of a given glyph element, and opens a  */+  /*    frame for it.                                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    loader      :: The current TrueType glyph loader object.           */+  /*                                                                       */+  /*    glyph index :: The index of the glyph to access.                   */+  /*                                                                       */+  /*    offset      :: The offset of the glyph according to the            */+  /*                   `locations' table.                                  */+  /*                                                                       */+  /*    byte_count  :: The size of the frame in bytes.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function is normally equivalent to FT_STREAM_SEEK(offset)     */+  /*    followed by FT_FRAME_ENTER(byte_count) with the loader's stream,   */+  /*    but alternative formats (e.g. compressed ones) might use something */+  /*    different.                                                         */+  /*                                                                       */+  typedef FT_Error+  (*TT_Loader_StartGlyphFunc)( TT_Loader  loader,+                               FT_UInt    glyph_index,+                               FT_ULong   offset,+                               FT_UInt    byte_count );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Loader_ReadGlyphFunc                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Reads one glyph element (its header, a simple glyph, or a          */+  /*    composite) from the loader's current stream frame.                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    loader :: The current TrueType glyph loader object.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  typedef FT_Error+  (*TT_Loader_ReadGlyphFunc)( TT_Loader  loader );+++  /*************************************************************************/+  /*                                                                       */+  /* <FuncType>                                                            */+  /*    TT_Loader_EndGlyphFunc                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Closes the current loader stream frame for the glyph.              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    loader :: The current TrueType glyph loader object.                */+  /*                                                                       */+  typedef void+  (*TT_Loader_EndGlyphFunc)( TT_Loader  loader );+++  /*************************************************************************/+  /*                                                                       */+  /*                         TrueType Face Type                            */+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Face                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The TrueType face class.  These objects model the resolution and   */+  /*    point-size independent data found in a TrueType font file.         */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root                 :: The base FT_Face structure, managed by the */+  /*                            base layer.                                */+  /*                                                                       */+  /*    ttc_header           :: The TrueType collection header, used when  */+  /*                            the file is a `ttc' rather than a `ttf'.   */+  /*                            For ordinary font files, the field         */+  /*                            `ttc_header.count' is set to 0.            */+  /*                                                                       */+  /*    format_tag           :: The font format tag.                       */+  /*                                                                       */+  /*    num_tables           :: The number of TrueType tables in this font */+  /*                            file.                                      */+  /*                                                                       */+  /*    dir_tables           :: The directory of TrueType tables for this  */+  /*                            font file.                                 */+  /*                                                                       */+  /*    header               :: The font's font header (`head' table).     */+  /*                            Read on font opening.                      */+  /*                                                                       */+  /*    horizontal           :: The font's horizontal header (`hhea'       */+  /*                            table).  This field also contains the      */+  /*                            associated horizontal metrics table        */+  /*                            (`hmtx').                                  */+  /*                                                                       */+  /*    max_profile          :: The font's maximum profile table.  Read on */+  /*                            font opening.  Note that some maximum      */+  /*                            values cannot be taken directly from this  */+  /*                            table.  We thus define additional fields   */+  /*                            below to hold the computed maxima.         */+  /*                                                                       */+  /*    vertical_info        :: A boolean which is set when the font file  */+  /*                            contains vertical metrics.  If not, the    */+  /*                            value of the `vertical' field is           */+  /*                            undefined.                                 */+  /*                                                                       */+  /*    vertical             :: The font's vertical header (`vhea' table). */+  /*                            This field also contains the associated    */+  /*                            vertical metrics table (`vmtx'), if found. */+  /*                            IMPORTANT: The contents of this field is   */+  /*                            undefined if the `verticalInfo' field is   */+  /*                            unset.                                     */+  /*                                                                       */+  /*    num_names            :: The number of name records within this     */+  /*                            TrueType font.                             */+  /*                                                                       */+  /*    name_table           :: The table of name records (`name').        */+  /*                                                                       */+  /*    os2                  :: The font's OS/2 table (`OS/2').            */+  /*                                                                       */+  /*    postscript           :: The font's PostScript table (`post'        */+  /*                            table).  The PostScript glyph names are    */+  /*                            not loaded by the driver on face opening.  */+  /*                            See the `ttpost' module for more details.  */+  /*                                                                       */+  /*    cmap_table           :: Address of the face's `cmap' SFNT table    */+  /*                            in memory (it's an extracted frame).       */+  /*                                                                       */+  /*    cmap_size            :: The size in bytes of the `cmap_table'      */+  /*                            described above.                           */+  /*                                                                       */+  /*    goto_table           :: A function called by each TrueType table   */+  /*                            loader to position a stream's cursor to    */+  /*                            the start of a given table according to    */+  /*                            its tag.  It defaults to TT_Goto_Face but  */+  /*                            can be different for strange formats (e.g. */+  /*                            Type 42).                                  */+  /*                                                                       */+  /*    access_glyph_frame   :: A function used to access the frame of a   */+  /*                            given glyph within the face's font file.   */+  /*                                                                       */+  /*    forget_glyph_frame   :: A function used to forget the frame of a   */+  /*                            given glyph when all data has been loaded. */+  /*                                                                       */+  /*    read_glyph_header    :: A function used to read a glyph header.    */+  /*                            It must be called between an `access' and  */+  /*                            `forget'.                                  */+  /*                                                                       */+  /*    read_simple_glyph    :: A function used to read a simple glyph.    */+  /*                            It must be called after the header was     */+  /*                            read, and before the `forget'.             */+  /*                                                                       */+  /*    read_composite_glyph :: A function used to read a composite glyph. */+  /*                            It must be called after the header was     */+  /*                            read, and before the `forget'.             */+  /*                                                                       */+  /*    sfnt                 :: A pointer to the SFNT service.             */+  /*                                                                       */+  /*    psnames              :: A pointer to the PostScript names service. */+  /*                                                                       */+  /*    hdmx                 :: The face's horizontal device metrics       */+  /*                            (`hdmx' table).  This table is optional in */+  /*                            TrueType/OpenType fonts.                   */+  /*                                                                       */+  /*    gasp                 :: The grid-fitting and scaling properties    */+  /*                            table (`gasp').  This table is optional in */+  /*                            TrueType/OpenType fonts.                   */+  /*                                                                       */+  /*    pclt                 :: The `pclt' SFNT table.                     */+  /*                                                                       */+  /*    num_sbit_strikes     :: The number of sbit strikes, i.e., bitmap   */+  /*                            sizes, embedded in this font.              */+  /*                                                                       */+  /*    sbit_strikes         :: An array of sbit strikes embedded in this  */+  /*                            font.  This table is optional in a         */+  /*                            TrueType/OpenType font.                    */+  /*                                                                       */+  /*    num_sbit_scales      :: The number of sbit scales for this font.   */+  /*                                                                       */+  /*    sbit_scales          :: Array of sbit scales embedded in this      */+  /*                            font.  This table is optional in a         */+  /*                            TrueType/OpenType font.                    */+  /*                                                                       */+  /*    postscript_names     :: A table used to store the Postscript names */+  /*                            of  the glyphs for this font.  See the     */+  /*                            file  `ttconfig.h' for comments on the     */+  /*                            TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.  */+  /*                                                                       */+  /*    num_locations        :: The number of glyph locations in this      */+  /*                            TrueType file.  This should be             */+  /*                            identical to the number of glyphs.         */+  /*                            Ignored for Type 2 fonts.                  */+  /*                                                                       */+  /*    glyph_locations      :: An array of longs.  These are offsets to   */+  /*                            glyph data within the `glyf' table.        */+  /*                            Ignored for Type 2 font faces.             */+  /*                                                                       */+  /*    glyf_len             :: The length of the `glyf' table.  Needed    */+  /*                            for malformed `loca' tables.               */+  /*                                                                       */+  /*    font_program_size    :: Size in bytecodes of the face's font       */+  /*                            program.  0 if none defined.  Ignored for  */+  /*                            Type 2 fonts.                              */+  /*                                                                       */+  /*    font_program         :: The face's font program (bytecode stream)  */+  /*                            executed at load time, also used during    */+  /*                            glyph rendering.  Comes from the `fpgm'    */+  /*                            table.  Ignored for Type 2 font fonts.     */+  /*                                                                       */+  /*    cvt_program_size     :: The size in bytecodes of the face's cvt    */+  /*                            program.  Ignored for Type 2 fonts.        */+  /*                                                                       */+  /*    cvt_program          :: The face's cvt program (bytecode stream)   */+  /*                            executed each time an instance/size is     */+  /*                            changed/reset.  Comes from the `prep'      */+  /*                            table.  Ignored for Type 2 fonts.          */+  /*                                                                       */+  /*    cvt_size             :: Size of the control value table (in        */+  /*                            entries).   Ignored for Type 2 fonts.      */+  /*                                                                       */+  /*    cvt                  :: The face's original control value table.   */+  /*                            Coordinates are expressed in unscaled font */+  /*                            units.  Comes from the `cvt ' table.       */+  /*                            Ignored for Type 2 fonts.                  */+  /*                                                                       */+  /*    num_kern_pairs       :: The number of kerning pairs present in the */+  /*                            font file.  The engine only loads the      */+  /*                            first horizontal format 0 kern table it    */+  /*                            finds in the font file.  Ignored for       */+  /*                            Type 2 fonts.                              */+  /*                                                                       */+  /*    kern_table_index     :: The index of the kerning table in the font */+  /*                            kerning directory.  Ignored for Type 2     */+  /*                            fonts.                                     */+  /*                                                                       */+  /*    interpreter          :: A pointer to the TrueType bytecode         */+  /*                            interpreters field is also used to hook    */+  /*                            the debugger in `ttdebug'.                 */+  /*                                                                       */+  /*    unpatented_hinting   :: If true, use only unpatented methods in    */+  /*                            the bytecode interpreter.                  */+  /*                                                                       */+  /*    doblend              :: A boolean which is set if the font should  */+  /*                            be blended (this is for GX var).           */+  /*                                                                       */+  /*    blend                :: Contains the data needed to control GX     */+  /*                            variation tables (rather like Multiple     */+  /*                            Master data).                              */+  /*                                                                       */+  /*    extra                :: Reserved for third-party font drivers.     */+  /*                                                                       */+  /*    postscript_name      :: The PS name of the font.  Used by the      */+  /*                            postscript name service.                   */+  /*                                                                       */+  typedef struct  TT_FaceRec_+  {+    FT_FaceRec            root;++    TTC_HeaderRec         ttc_header;++    FT_ULong              format_tag;+    FT_UShort             num_tables;+    TT_Table              dir_tables;++    TT_Header             header;       /* TrueType header table          */+    TT_HoriHeader         horizontal;   /* TrueType horizontal header     */++    TT_MaxProfile         max_profile;+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    FT_ULong              max_components;  /* stubbed to 0 */+#endif++    FT_Bool               vertical_info;+    TT_VertHeader         vertical;     /* TT Vertical header, if present */++    FT_UShort             num_names;    /* number of name records  */+    TT_NameTableRec       name_table;   /* name table              */++    TT_OS2                os2;          /* TrueType OS/2 table            */+    TT_Postscript         postscript;   /* TrueType Postscript table      */++    FT_Byte*              cmap_table;   /* extracted `cmap' table */+    FT_ULong              cmap_size;++    TT_Loader_GotoTableFunc   goto_table;++    TT_Loader_StartGlyphFunc  access_glyph_frame;+    TT_Loader_EndGlyphFunc    forget_glyph_frame;+    TT_Loader_ReadGlyphFunc   read_glyph_header;+    TT_Loader_ReadGlyphFunc   read_simple_glyph;+    TT_Loader_ReadGlyphFunc   read_composite_glyph;++    /* a typeless pointer to the SFNT_Interface table used to load */+    /* the basic TrueType tables in the face object                */+    void*                 sfnt;++    /* a typeless pointer to the FT_Service_PsCMapsRec table used to */+    /* handle glyph names <-> unicode & Mac values                   */+    void*                 psnames;+++    /***********************************************************************/+    /*                                                                     */+    /* Optional TrueType/OpenType tables                                   */+    /*                                                                     */+    /***********************************************************************/++    /* horizontal device metrics */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    TT_HdmxRec            hdmx;+#endif++    /* grid-fitting and scaling table */+    TT_GaspRec            gasp;                 /* the `gasp' table */++    /* PCL 5 table */+    TT_PCLT               pclt;++    /* embedded bitmaps support */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    FT_ULong              num_sbit_strikes;+    TT_SBit_Strike        sbit_strikes;+#endif++    FT_ULong              num_sbit_scales;+    TT_SBit_Scale         sbit_scales;++    /* postscript names table */+    TT_Post_NamesRec      postscript_names;+++    /***********************************************************************/+    /*                                                                     */+    /* TrueType-specific fields (ignored by the OTF-Type2 driver)          */+    /*                                                                     */+    /***********************************************************************/++    /* the glyph locations */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    FT_UShort             num_locations_stub;+    FT_Long*              glyph_locations_stub;+#endif++    /* the font program, if any */+    FT_ULong              font_program_size;+    FT_Byte*              font_program;++    /* the cvt program, if any */+    FT_ULong              cvt_program_size;+    FT_Byte*              cvt_program;++    /* the original, unscaled, control value table */+    FT_ULong              cvt_size;+    FT_Short*             cvt;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    /* the format 0 kerning table, if any */+    FT_Int                num_kern_pairs;+    FT_Int                kern_table_index;+    TT_Kern0_Pair         kern_pairs;+#endif++    /* A pointer to the bytecode interpreter to use.  This is also */+    /* used to hook the debugger for the `ttdebug' utility.        */+    TT_Interpreter        interpreter;++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    /* Use unpatented hinting only. */+    FT_Bool               unpatented_hinting;+#endif++    /***********************************************************************/+    /*                                                                     */+    /* Other tables or fields. This is used by derivative formats like     */+    /* OpenType.                                                           */+    /*                                                                     */+    /***********************************************************************/++    FT_Generic            extra;++    const char*           postscript_name;++    /* since version 2.1.8, but was originally placed after */+    /* `glyph_locations_stub'                               */+    FT_ULong              glyf_len;++    /* since version 2.1.8, but was originally placed before `extra' */+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    FT_Bool               doblend;+    GX_Blend              blend;+#endif++    /* since version 2.2 */++    FT_Byte*              horz_metrics;+    FT_ULong              horz_metrics_size;++    FT_Byte*              vert_metrics;+    FT_ULong              vert_metrics_size;++    FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */ +    FT_Byte*              glyph_locations;++    FT_Byte*              hdmx_table;+    FT_ULong              hdmx_table_size;+    FT_UInt               hdmx_record_count;+    FT_ULong              hdmx_record_size;+    FT_Byte*              hdmx_record_sizes;++    FT_Byte*              sbit_table;+    FT_ULong              sbit_table_size;+    FT_UInt               sbit_num_strikes;++    FT_Byte*              kern_table;+    FT_ULong              kern_table_size;+    FT_UInt               num_kern_tables;+    FT_UInt32             kern_avail_bits;+    FT_UInt32             kern_order_bits;++#ifdef TT_CONFIG_OPTION_BDF+    TT_BDFRec             bdf;+#endif /* TT_CONFIG_OPTION_BDF */++    /* since 2.3.0 */+    FT_ULong              horz_metrics_offset;+    FT_ULong              vert_metrics_offset;++  } TT_FaceRec;+++  /*************************************************************************/+  /*                                                                       */+  /*  <Struct>                                                             */+  /*     TT_GlyphZoneRec                                                   */+  /*                                                                       */+  /*  <Description>                                                        */+  /*     A glyph zone is used to load, scale and hint glyph outline        */+  /*     coordinates.                                                      */+  /*                                                                       */+  /*  <Fields>                                                             */+  /*     memory       :: A handle to the memory manager.                   */+  /*                                                                       */+  /*     max_points   :: The maximal size in points of the zone.           */+  /*                                                                       */+  /*     max_contours :: Max size in links contours of the zone.           */+  /*                                                                       */+  /*     n_points     :: The current number of points in the zone.         */+  /*                                                                       */+  /*     n_contours   :: The current number of contours in the zone.       */+  /*                                                                       */+  /*     org          :: The original glyph coordinates (font              */+  /*                     units/scaled).                                    */+  /*                                                                       */+  /*     cur          :: The current glyph coordinates (scaled/hinted).    */+  /*                                                                       */+  /*     tags         :: The point control tags.                           */+  /*                                                                       */+  /*     contours     :: The contours end points.                          */+  /*                                                                       */+  /*     first_point  :: Offset of the current subglyph's first point.     */+  /*                                                                       */+  typedef struct  TT_GlyphZoneRec_+  {+    FT_Memory   memory;+    FT_UShort   max_points;+    FT_UShort   max_contours;+    FT_UShort   n_points;    /* number of points in zone    */+    FT_Short    n_contours;  /* number of contours          */++    FT_Vector*  org;         /* original point coordinates  */+    FT_Vector*  cur;         /* current point coordinates   */+    FT_Vector*  orus;        /* original (unscaled) point coordinates */++    FT_Byte*    tags;        /* current touch flags         */+    FT_UShort*  contours;    /* contour end points          */++    FT_UShort   first_point; /* offset of first (#0) point  */++  } TT_GlyphZoneRec, *TT_GlyphZone;+++  /* handle to execution context */+  typedef struct TT_ExecContextRec_*  TT_ExecContext;++  /* glyph loader structure */+  typedef struct  TT_LoaderRec_+  {+    FT_Face          face;+    FT_Size          size;+    FT_GlyphSlot     glyph;+    FT_GlyphLoader   gloader;++    FT_ULong         load_flags;+    FT_UInt          glyph_index;++    FT_Stream        stream;+    FT_Int           byte_len;++    FT_Short         n_contours;+    FT_BBox          bbox;+    FT_Int           left_bearing;+    FT_Int           advance;+    FT_Int           linear;+    FT_Bool          linear_def;+    FT_Bool          preserve_pps;+    FT_Vector        pp1;+    FT_Vector        pp2;++    FT_ULong         glyf_offset;++    /* the zone where we load our glyphs */+    TT_GlyphZoneRec  base;+    TT_GlyphZoneRec  zone;++    TT_ExecContext   exec;+    FT_Byte*         instructions;+    FT_ULong         ins_pos;++    /* for possible extensibility in other formats */+    void*            other;++    /* since version 2.1.8 */+    FT_Int           top_bearing;+    FT_Int           vadvance;+    FT_Vector        pp3;+    FT_Vector        pp4;++    /* since version 2.2.1 */+    FT_Byte*         cursor;+    FT_Byte*         limit;++  } TT_LoaderRec;+++FT_END_HEADER++#endif /* __TTTYPES_H__ */+++/* END */
+ include/freetype/t1tables.h view
@@ -0,0 +1,504 @@+/***************************************************************************/+/*                                                                         */+/*  t1tables.h                                                             */+/*                                                                         */+/*    Basic Type 1/Type 2 tables definitions and interface (specification  */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1TABLES_H__+#define __T1TABLES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    type1_tables                                                       */+  /*                                                                       */+  /* <Title>                                                               */+  /*    Type 1 Tables                                                      */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    Type~1 (PostScript) specific font tables.                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the definition of Type 1-specific tables,    */+  /*    including structures related to other PostScript font formats.     */+  /*                                                                       */+  /*************************************************************************/+++  /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */+  /* structures in order to support Multiple Master fonts.               */+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_FontInfoRec                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a Type~1 or Type~2 FontInfo dictionary.  */+  /*    Note that for Multiple Master fonts, each instance has its own     */+  /*    FontInfo dictionary.                                               */+  /*                                                                       */+  typedef struct  PS_FontInfoRec_+  {+    FT_String*  version;+    FT_String*  notice;+    FT_String*  full_name;+    FT_String*  family_name;+    FT_String*  weight;+    FT_Long     italic_angle;+    FT_Bool     is_fixed_pitch;+    FT_Short    underline_position;+    FT_UShort   underline_thickness;++  } PS_FontInfoRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_FontInfo                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a @PS_FontInfoRec structure.                           */+  /*                                                                       */+  typedef struct PS_FontInfoRec_*  PS_FontInfo;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    T1_FontInfo                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This type is equivalent to @PS_FontInfoRec.  It is deprecated but  */+  /*    kept to maintain source compatibility between various versions of  */+  /*    FreeType.                                                          */+  /*                                                                       */+  typedef PS_FontInfoRec  T1_FontInfo;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_PrivateRec                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a Type~1 or Type~2 private dictionary.   */+  /*    Note that for Multiple Master fonts, each instance has its own     */+  /*    Private dictionary.                                                */+  /*                                                                       */+  typedef struct  PS_PrivateRec_+  {+    FT_Int     unique_id;+    FT_Int     lenIV;++    FT_Byte    num_blue_values;+    FT_Byte    num_other_blues;+    FT_Byte    num_family_blues;+    FT_Byte    num_family_other_blues;++    FT_Short   blue_values[14];+    FT_Short   other_blues[10];++    FT_Short   family_blues      [14];+    FT_Short   family_other_blues[10];++    FT_Fixed   blue_scale;+    FT_Int     blue_shift;+    FT_Int     blue_fuzz;++    FT_UShort  standard_width[1];+    FT_UShort  standard_height[1];++    FT_Byte    num_snap_widths;+    FT_Byte    num_snap_heights;+    FT_Bool    force_bold;+    FT_Bool    round_stem_up;++    FT_Short   snap_widths [13];  /* including std width  */+    FT_Short   snap_heights[13];  /* including std height */++    FT_Fixed   expansion_factor;++    FT_Long    language_group;+    FT_Long    password;++    FT_Short   min_feature[2];++  } PS_PrivateRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    PS_Private                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a @PS_PrivateRec structure.                            */+  /*                                                                       */+  typedef struct PS_PrivateRec_*  PS_Private;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    T1_Private                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*   This type is equivalent to @PS_PrivateRec.  It is deprecated but    */+  /*   kept to maintain source compatibility between various versions of   */+  /*   FreeType.                                                           */+  /*                                                                       */+  typedef PS_PrivateRec  T1_Private;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    T1_Blend_Flags                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A set of flags used to indicate which fields are present in a      */+  /*    given blend dictionary (font info or private).  Used to support    */+  /*    Multiple Masters fonts.                                            */+  /*                                                                       */+  typedef enum  T1_Blend_Flags_+  {+    /*# required fields in a FontInfo blend dictionary */+    T1_BLEND_UNDERLINE_POSITION = 0,+    T1_BLEND_UNDERLINE_THICKNESS,+    T1_BLEND_ITALIC_ANGLE,++    /*# required fields in a Private blend dictionary */+    T1_BLEND_BLUE_VALUES,+    T1_BLEND_OTHER_BLUES,+    T1_BLEND_STANDARD_WIDTH,+    T1_BLEND_STANDARD_HEIGHT,+    T1_BLEND_STEM_SNAP_WIDTHS,+    T1_BLEND_STEM_SNAP_HEIGHTS,+    T1_BLEND_BLUE_SCALE,+    T1_BLEND_BLUE_SHIFT,+    T1_BLEND_FAMILY_BLUES,+    T1_BLEND_FAMILY_OTHER_BLUES,+    T1_BLEND_FORCE_BOLD,++    /*# never remove */+    T1_BLEND_MAX++  } T1_Blend_Flags;++  /* */+++  /*# backwards compatible definitions */+#define t1_blend_underline_position   T1_BLEND_UNDERLINE_POSITION+#define t1_blend_underline_thickness  T1_BLEND_UNDERLINE_THICKNESS+#define t1_blend_italic_angle         T1_BLEND_ITALIC_ANGLE+#define t1_blend_blue_values          T1_BLEND_BLUE_VALUES+#define t1_blend_other_blues          T1_BLEND_OTHER_BLUES+#define t1_blend_standard_widths      T1_BLEND_STANDARD_WIDTH+#define t1_blend_standard_height      T1_BLEND_STANDARD_HEIGHT+#define t1_blend_stem_snap_widths     T1_BLEND_STEM_SNAP_WIDTHS+#define t1_blend_stem_snap_heights    T1_BLEND_STEM_SNAP_HEIGHTS+#define t1_blend_blue_scale           T1_BLEND_BLUE_SCALE+#define t1_blend_blue_shift           T1_BLEND_BLUE_SHIFT+#define t1_blend_family_blues         T1_BLEND_FAMILY_BLUES+#define t1_blend_family_other_blues   T1_BLEND_FAMILY_OTHER_BLUES+#define t1_blend_force_bold           T1_BLEND_FORCE_BOLD+#define t1_blend_max                  T1_BLEND_MAX+++  /* maximum number of Multiple Masters designs, as defined in the spec */+#define T1_MAX_MM_DESIGNS     16++  /* maximum number of Multiple Masters axes, as defined in the spec */+#define T1_MAX_MM_AXIS        4++  /* maximum number of elements in a design map */+#define T1_MAX_MM_MAP_POINTS  20+++  /* this structure is used to store the BlendDesignMap entry for an axis */+  typedef struct  PS_DesignMap_+  {+    FT_Byte    num_points;+    FT_Long*   design_points;+    FT_Fixed*  blend_points;++  } PS_DesignMapRec, *PS_DesignMap;++  /* backwards-compatible definition */+  typedef PS_DesignMapRec  T1_DesignMap;+++  typedef struct  PS_BlendRec_+  {+    FT_UInt          num_designs;+    FT_UInt          num_axis;++    FT_String*       axis_names[T1_MAX_MM_AXIS];+    FT_Fixed*        design_pos[T1_MAX_MM_DESIGNS];+    PS_DesignMapRec  design_map[T1_MAX_MM_AXIS];++    FT_Fixed*        weight_vector;+    FT_Fixed*        default_weight_vector;++    PS_FontInfo      font_infos[T1_MAX_MM_DESIGNS + 1];+    PS_Private       privates  [T1_MAX_MM_DESIGNS + 1];++    FT_ULong         blend_bitflags;++    FT_BBox*         bboxes    [T1_MAX_MM_DESIGNS + 1];++    /* since 2.3.0 */++    /* undocumented, optional: the default design instance;   */+    /* corresponds to default_weight_vector --                */+    /* num_default_design_vector == 0 means it is not present */+    /* in the font and associated metrics files               */+    FT_UInt          default_design_vector[T1_MAX_MM_DESIGNS];+    FT_UInt          num_default_design_vector;++  } PS_BlendRec, *PS_Blend;+++  /* backwards-compatible definition */+  typedef PS_BlendRec  T1_Blend;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_FaceDictRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to represent data in a CID top-level dictionary.  */+  /*                                                                       */+  typedef struct  CID_FaceDictRec_+  {+    PS_PrivateRec  private_dict;++    FT_UInt        len_buildchar;+    FT_Fixed       forcebold_threshold;+    FT_Pos         stroke_width;+    FT_Fixed       expansion_factor;++    FT_Byte        paint_type;+    FT_Byte        font_type;+    FT_Matrix      font_matrix;+    FT_Vector      font_offset;++    FT_UInt        num_subrs;+    FT_ULong       subrmap_offset;+    FT_Int         sd_bytes;++  } CID_FaceDictRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_FaceDict                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a @CID_FaceDictRec structure.                          */+  /*                                                                       */+  typedef struct CID_FaceDictRec_*  CID_FaceDict;++  /* */+++  /* backwards-compatible definition */+  typedef CID_FaceDictRec  CID_FontDict;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_FaceInfoRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to represent CID Face information.                */+  /*                                                                       */+  typedef struct  CID_FaceInfoRec_+  {+    FT_String*      cid_font_name;+    FT_Fixed        cid_version;+    FT_Int          cid_font_type;++    FT_String*      registry;+    FT_String*      ordering;+    FT_Int          supplement;++    PS_FontInfoRec  font_info;+    FT_BBox         font_bbox;+    FT_ULong        uid_base;++    FT_Int          num_xuid;+    FT_ULong        xuid[16];++    FT_ULong        cidmap_offset;+    FT_Int          fd_bytes;+    FT_Int          gd_bytes;+    FT_ULong        cid_count;++    FT_Int          num_dicts;+    CID_FaceDict    font_dicts;++    FT_ULong        data_offset;++  } CID_FaceInfoRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_FaceInfo                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a @CID_FaceInfoRec structure.                          */+  /*                                                                       */+  typedef struct CID_FaceInfoRec_*  CID_FaceInfo;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_Info                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*   This type is equivalent to @CID_FaceInfoRec.  It is deprecated but  */+  /*   kept to maintain source compatibility between various versions of   */+  /*   FreeType.                                                           */+  /*                                                                       */+  typedef CID_FaceInfoRec  CID_Info;+++  /************************************************************************+   *+   * @function:+   *    FT_Has_PS_Glyph_Names+   *+   * @description:+   *    Return true if a given face provides reliable PostScript glyph+   *    names.  This is similar to using the @FT_HAS_GLYPH_NAMES macro,+   *    except that certain fonts (mostly TrueType) contain incorrect+   *    glyph name tables.+   *+   *    When this function returns true, the caller is sure that the glyph+   *    names returned by @FT_Get_Glyph_Name are reliable.+   *+   * @input:+   *    face ::+   *       face handle+   *+   * @return:+   *    Boolean.  True if glyph names are reliable.+   *+   */+  FT_EXPORT( FT_Int )+  FT_Has_PS_Glyph_Names( FT_Face  face );+++  /************************************************************************+   *+   * @function:+   *    FT_Get_PS_Font_Info+   *+   * @description:+   *    Retrieve the @PS_FontInfoRec structure corresponding to a given+   *    PostScript font.+   *+   * @input:+   *    face ::+   *       PostScript face handle.+   *+   * @output:+   *    afont_info ::+   *       Output font info structure pointer.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *    The string pointers within the font info structure are owned by+   *    the face and don't need to be freed by the caller.+   *+   *    If the font's format is not PostScript-based, this function will+   *    return the `FT_Err_Invalid_Argument' error code.+   *+   */+  FT_EXPORT( FT_Error )+  FT_Get_PS_Font_Info( FT_Face      face,+                       PS_FontInfo  afont_info );+++  /************************************************************************+   *+   * @function:+   *    FT_Get_PS_Font_Private+   *+   * @description:+   *    Retrieve the @PS_PrivateRec structure corresponding to a given+   *    PostScript font.+   *+   * @input:+   *    face ::+   *       PostScript face handle.+   *+   * @output:+   *    afont_private ::+   *       Output private dictionary structure pointer.+   *+   * @return:+   *    FreeType error code.  0~means success.+   *+   * @note:+   *    The string pointers within the @PS_PrivateRec structure are owned by+   *    the face and don't need to be freed by the caller.+   *+   *    If the font's format is not PostScript-based, this function returns+   *    the `FT_Err_Invalid_Argument' error code.+   *+   */+  FT_EXPORT( FT_Error )+  FT_Get_PS_Font_Private( FT_Face     face,+                          PS_Private  afont_private );++  /* */+++FT_END_HEADER++#endif /* __T1TABLES_H__ */+++/* END */
+ include/freetype/ttnameid.h view
@@ -0,0 +1,1247 @@+/***************************************************************************/+/*                                                                         */+/*  ttnameid.h                                                             */+/*                                                                         */+/*    TrueType name ID definitions (specification only).                   */+/*                                                                         */+/*  Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTNAMEID_H__+#define __TTNAMEID_H__+++#include <ft2build.h>+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    truetype_tables                                                    */+  /*                                                                       */+++  /*************************************************************************/+  /*                                                                       */+  /* Possible values for the `platform' identifier code in the name        */+  /* records of the TTF `name' table.                                      */+  /*                                                                       */+  /*************************************************************************/+++  /***********************************************************************+   *+   * @enum:+   *   TT_PLATFORM_XXX+   *+   * @description:+   *   A list of valid values for the `platform_id' identifier code in+   *   @FT_CharMapRec and @FT_SfntName structures.+   *+   * @values:+   *   TT_PLATFORM_APPLE_UNICODE ::+   *     Used by Apple to indicate a Unicode character map and/or name entry.+   *     See @TT_APPLE_ID_XXX for corresponding `encoding_id' values.  Note+   *     that name entries in this format are coded as big-endian UCS-2+   *     character codes _only_.+   *+   *   TT_PLATFORM_MACINTOSH ::+   *     Used by Apple to indicate a MacOS-specific charmap and/or name entry.+   *     See @TT_MAC_ID_XXX for corresponding `encoding_id' values.  Note that+   *     most TrueType fonts contain an Apple roman charmap to be usable on+   *     MacOS systems (even if they contain a Microsoft charmap as well).+   *+   *   TT_PLATFORM_ISO ::+   *     This value was used to specify ISO/IEC 10646 charmaps.  It is however+   *     now deprecated.  See @TT_ISO_ID_XXX for a list of corresponding+   *     `encoding_id' values.+   *+   *   TT_PLATFORM_MICROSOFT ::+   *     Used by Microsoft to indicate Windows-specific charmaps.  See+   *     @TT_MS_ID_XXX for a list of corresponding `encoding_id' values.+   *     Note that most fonts contain a Unicode charmap using+   *     (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS).+   *+   *   TT_PLATFORM_CUSTOM ::+   *     Used to indicate application-specific charmaps.+   *+   *   TT_PLATFORM_ADOBE ::+   *     This value isn't part of any font format specification, but is used+   *     by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec+   *     structure.  See @TT_ADOBE_ID_XXX.+   */++#define TT_PLATFORM_APPLE_UNICODE  0+#define TT_PLATFORM_MACINTOSH      1+#define TT_PLATFORM_ISO            2 /* deprecated */+#define TT_PLATFORM_MICROSOFT      3+#define TT_PLATFORM_CUSTOM         4+#define TT_PLATFORM_ADOBE          7 /* artificial */+++  /***********************************************************************+   *+   * @enum:+   *   TT_APPLE_ID_XXX+   *+   * @description:+   *   A list of valid values for the `encoding_id' for+   *   @TT_PLATFORM_APPLE_UNICODE charmaps and name entries.+   *+   * @values:+   *   TT_APPLE_ID_DEFAULT ::+   *     Unicode version 1.0.+   *+   *   TT_APPLE_ID_UNICODE_1_1 ::+   *     Unicode 1.1; specifies Hangul characters starting at U+34xx.+   *+   *   TT_APPLE_ID_ISO_10646 ::+   *     Deprecated (identical to preceding).+   *+   *   TT_APPLE_ID_UNICODE_2_0 ::+   *     Unicode 2.0 and beyond (UTF-16 BMP only).+   *+   *   TT_APPLE_ID_UNICODE_32 ::+   *     Unicode 3.1 and beyond, using UTF-32.+   *+   *   TT_APPLE_ID_VARIANT_SELECTOR ::+   *     From Adobe, not Apple.  Not a normal cmap.  Specifies variations+   *     on a real cmap.+   */++#define TT_APPLE_ID_DEFAULT           0 /* Unicode 1.0 */+#define TT_APPLE_ID_UNICODE_1_1       1 /* specify Hangul at U+34xx */+#define TT_APPLE_ID_ISO_10646         2 /* deprecated */+#define TT_APPLE_ID_UNICODE_2_0       3 /* or later */+#define TT_APPLE_ID_UNICODE_32        4 /* 2.0 or later, full repertoire */+#define TT_APPLE_ID_VARIANT_SELECTOR  5 /* variation selector data */+++  /***********************************************************************+   *+   * @enum:+   *   TT_MAC_ID_XXX+   *+   * @description:+   *   A list of valid values for the `encoding_id' for+   *   @TT_PLATFORM_MACINTOSH charmaps and name entries.+   *+   * @values:+   *   TT_MAC_ID_ROMAN ::+   *   TT_MAC_ID_JAPANESE ::+   *   TT_MAC_ID_TRADITIONAL_CHINESE ::+   *   TT_MAC_ID_KOREAN ::+   *   TT_MAC_ID_ARABIC ::+   *   TT_MAC_ID_HEBREW ::+   *   TT_MAC_ID_GREEK ::+   *   TT_MAC_ID_RUSSIAN ::+   *   TT_MAC_ID_RSYMBOL ::+   *   TT_MAC_ID_DEVANAGARI ::+   *   TT_MAC_ID_GURMUKHI ::+   *   TT_MAC_ID_GUJARATI ::+   *   TT_MAC_ID_ORIYA ::+   *   TT_MAC_ID_BENGALI ::+   *   TT_MAC_ID_TAMIL ::+   *   TT_MAC_ID_TELUGU ::+   *   TT_MAC_ID_KANNADA ::+   *   TT_MAC_ID_MALAYALAM ::+   *   TT_MAC_ID_SINHALESE ::+   *   TT_MAC_ID_BURMESE ::+   *   TT_MAC_ID_KHMER ::+   *   TT_MAC_ID_THAI ::+   *   TT_MAC_ID_LAOTIAN ::+   *   TT_MAC_ID_GEORGIAN ::+   *   TT_MAC_ID_ARMENIAN ::+   *   TT_MAC_ID_MALDIVIAN ::+   *   TT_MAC_ID_SIMPLIFIED_CHINESE ::+   *   TT_MAC_ID_TIBETAN ::+   *   TT_MAC_ID_MONGOLIAN ::+   *   TT_MAC_ID_GEEZ ::+   *   TT_MAC_ID_SLAVIC ::+   *   TT_MAC_ID_VIETNAMESE ::+   *   TT_MAC_ID_SINDHI ::+   *   TT_MAC_ID_UNINTERP ::+   */++#define TT_MAC_ID_ROMAN                 0+#define TT_MAC_ID_JAPANESE              1+#define TT_MAC_ID_TRADITIONAL_CHINESE   2+#define TT_MAC_ID_KOREAN                3+#define TT_MAC_ID_ARABIC                4+#define TT_MAC_ID_HEBREW                5+#define TT_MAC_ID_GREEK                 6+#define TT_MAC_ID_RUSSIAN               7+#define TT_MAC_ID_RSYMBOL               8+#define TT_MAC_ID_DEVANAGARI            9+#define TT_MAC_ID_GURMUKHI             10+#define TT_MAC_ID_GUJARATI             11+#define TT_MAC_ID_ORIYA                12+#define TT_MAC_ID_BENGALI              13+#define TT_MAC_ID_TAMIL                14+#define TT_MAC_ID_TELUGU               15+#define TT_MAC_ID_KANNADA              16+#define TT_MAC_ID_MALAYALAM            17+#define TT_MAC_ID_SINHALESE            18+#define TT_MAC_ID_BURMESE              19+#define TT_MAC_ID_KHMER                20+#define TT_MAC_ID_THAI                 21+#define TT_MAC_ID_LAOTIAN              22+#define TT_MAC_ID_GEORGIAN             23+#define TT_MAC_ID_ARMENIAN             24+#define TT_MAC_ID_MALDIVIAN            25+#define TT_MAC_ID_SIMPLIFIED_CHINESE   25+#define TT_MAC_ID_TIBETAN              26+#define TT_MAC_ID_MONGOLIAN            27+#define TT_MAC_ID_GEEZ                 28+#define TT_MAC_ID_SLAVIC               29+#define TT_MAC_ID_VIETNAMESE           30+#define TT_MAC_ID_SINDHI               31+#define TT_MAC_ID_UNINTERP             32+++  /***********************************************************************+   *+   * @enum:+   *   TT_ISO_ID_XXX+   *+   * @description:+   *   A list of valid values for the `encoding_id' for+   *   @TT_PLATFORM_ISO charmaps and name entries.+   *+   *   Their use is now deprecated.+   *+   * @values:+   *   TT_ISO_ID_7BIT_ASCII ::+   *     ASCII.+   *   TT_ISO_ID_10646 ::+   *     ISO/10646.+   *   TT_ISO_ID_8859_1 ::+   *     Also known as Latin-1.+   */++#define TT_ISO_ID_7BIT_ASCII  0+#define TT_ISO_ID_10646       1+#define TT_ISO_ID_8859_1      2+++  /***********************************************************************+   *+   * @enum:+   *   TT_MS_ID_XXX+   *+   * @description:+   *   A list of valid values for the `encoding_id' for+   *   @TT_PLATFORM_MICROSOFT charmaps and name entries.+   *+   * @values:+   *   TT_MS_ID_SYMBOL_CS ::+   *     Corresponds to Microsoft symbol encoding. See+   *     @FT_ENCODING_MS_SYMBOL.+   *+   *   TT_MS_ID_UNICODE_CS ::+   *     Corresponds to a Microsoft WGL4 charmap, matching Unicode.  See+   *     @FT_ENCODING_UNICODE.+   *+   *   TT_MS_ID_SJIS ::+   *     Corresponds to SJIS Japanese encoding.  See @FT_ENCODING_SJIS.+   *+   *   TT_MS_ID_GB2312 ::+   *     Corresponds to Simplified Chinese as used in Mainland China.  See+   *     @FT_ENCODING_GB2312.+   *+   *   TT_MS_ID_BIG_5 ::+   *     Corresponds to Traditional Chinese as used in Taiwan and Hong Kong.+   *     See @FT_ENCODING_BIG5.+   *+   *   TT_MS_ID_WANSUNG ::+   *     Corresponds to Korean Wansung encoding.  See @FT_ENCODING_WANSUNG.+   *+   *   TT_MS_ID_JOHAB ::+   *     Corresponds to Johab encoding.  See @FT_ENCODING_JOHAB.+   *+   *   TT_MS_ID_UCS_4 ::+   *     Corresponds to UCS-4 or UTF-32 charmaps.  This has been added to+   *     the OpenType specification version 1.4 (mid-2001.)+   */++#define TT_MS_ID_SYMBOL_CS    0+#define TT_MS_ID_UNICODE_CS   1+#define TT_MS_ID_SJIS         2+#define TT_MS_ID_GB2312       3+#define TT_MS_ID_BIG_5        4+#define TT_MS_ID_WANSUNG      5+#define TT_MS_ID_JOHAB        6+#define TT_MS_ID_UCS_4       10+++  /***********************************************************************+   *+   * @enum:+   *   TT_ADOBE_ID_XXX+   *+   * @description:+   *   A list of valid values for the `encoding_id' for+   *   @TT_PLATFORM_ADOBE charmaps.  This is a FreeType-specific extension!+   *+   * @values:+   *   TT_ADOBE_ID_STANDARD ::+   *     Adobe standard encoding.+   *   TT_ADOBE_ID_EXPERT ::+   *     Adobe expert encoding.+   *   TT_ADOBE_ID_CUSTOM ::+   *     Adobe custom encoding.+   *   TT_ADOBE_ID_LATIN_1 ::+   *     Adobe Latin~1 encoding.+   */++#define TT_ADOBE_ID_STANDARD  0+#define TT_ADOBE_ID_EXPERT    1+#define TT_ADOBE_ID_CUSTOM    2+#define TT_ADOBE_ID_LATIN_1   3+++  /*************************************************************************/+  /*                                                                       */+  /* Possible values of the language identifier field in the name records  */+  /* of the TTF `name' table if the `platform' identifier code is          */+  /* TT_PLATFORM_MACINTOSH.                                                */+  /*                                                                       */+  /* The canonical source for the Apple assigned Language ID's is at       */+  /*                                                                       */+  /*   http://fonts.apple.com/TTRefMan/RM06/Chap6name.html                 */+  /*                                                                       */+#define TT_MAC_LANGID_ENGLISH                       0+#define TT_MAC_LANGID_FRENCH                        1+#define TT_MAC_LANGID_GERMAN                        2+#define TT_MAC_LANGID_ITALIAN                       3+#define TT_MAC_LANGID_DUTCH                         4+#define TT_MAC_LANGID_SWEDISH                       5+#define TT_MAC_LANGID_SPANISH                       6+#define TT_MAC_LANGID_DANISH                        7+#define TT_MAC_LANGID_PORTUGUESE                    8+#define TT_MAC_LANGID_NORWEGIAN                     9+#define TT_MAC_LANGID_HEBREW                       10+#define TT_MAC_LANGID_JAPANESE                     11+#define TT_MAC_LANGID_ARABIC                       12+#define TT_MAC_LANGID_FINNISH                      13+#define TT_MAC_LANGID_GREEK                        14+#define TT_MAC_LANGID_ICELANDIC                    15+#define TT_MAC_LANGID_MALTESE                      16+#define TT_MAC_LANGID_TURKISH                      17+#define TT_MAC_LANGID_CROATIAN                     18+#define TT_MAC_LANGID_CHINESE_TRADITIONAL          19+#define TT_MAC_LANGID_URDU                         20+#define TT_MAC_LANGID_HINDI                        21+#define TT_MAC_LANGID_THAI                         22+#define TT_MAC_LANGID_KOREAN                       23+#define TT_MAC_LANGID_LITHUANIAN                   24+#define TT_MAC_LANGID_POLISH                       25+#define TT_MAC_LANGID_HUNGARIAN                    26+#define TT_MAC_LANGID_ESTONIAN                     27+#define TT_MAC_LANGID_LETTISH                      28+#define TT_MAC_LANGID_SAAMISK                      29+#define TT_MAC_LANGID_FAEROESE                     30+#define TT_MAC_LANGID_FARSI                        31+#define TT_MAC_LANGID_RUSSIAN                      32+#define TT_MAC_LANGID_CHINESE_SIMPLIFIED           33+#define TT_MAC_LANGID_FLEMISH                      34+#define TT_MAC_LANGID_IRISH                        35+#define TT_MAC_LANGID_ALBANIAN                     36+#define TT_MAC_LANGID_ROMANIAN                     37+#define TT_MAC_LANGID_CZECH                        38+#define TT_MAC_LANGID_SLOVAK                       39+#define TT_MAC_LANGID_SLOVENIAN                    40+#define TT_MAC_LANGID_YIDDISH                      41+#define TT_MAC_LANGID_SERBIAN                      42+#define TT_MAC_LANGID_MACEDONIAN                   43+#define TT_MAC_LANGID_BULGARIAN                    44+#define TT_MAC_LANGID_UKRAINIAN                    45+#define TT_MAC_LANGID_BYELORUSSIAN                 46+#define TT_MAC_LANGID_UZBEK                        47+#define TT_MAC_LANGID_KAZAKH                       48+#define TT_MAC_LANGID_AZERBAIJANI                  49+#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT  49+#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT    50+#define TT_MAC_LANGID_ARMENIAN                     51+#define TT_MAC_LANGID_GEORGIAN                     52+#define TT_MAC_LANGID_MOLDAVIAN                    53+#define TT_MAC_LANGID_KIRGHIZ                      54+#define TT_MAC_LANGID_TAJIKI                       55+#define TT_MAC_LANGID_TURKMEN                      56+#define TT_MAC_LANGID_MONGOLIAN                    57+#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT   57+#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT    58+#define TT_MAC_LANGID_PASHTO                       59+#define TT_MAC_LANGID_KURDISH                      60+#define TT_MAC_LANGID_KASHMIRI                     61+#define TT_MAC_LANGID_SINDHI                       62+#define TT_MAC_LANGID_TIBETAN                      63+#define TT_MAC_LANGID_NEPALI                       64+#define TT_MAC_LANGID_SANSKRIT                     65+#define TT_MAC_LANGID_MARATHI                      66+#define TT_MAC_LANGID_BENGALI                      67+#define TT_MAC_LANGID_ASSAMESE                     68+#define TT_MAC_LANGID_GUJARATI                     69+#define TT_MAC_LANGID_PUNJABI                      70+#define TT_MAC_LANGID_ORIYA                        71+#define TT_MAC_LANGID_MALAYALAM                    72+#define TT_MAC_LANGID_KANNADA                      73+#define TT_MAC_LANGID_TAMIL                        74+#define TT_MAC_LANGID_TELUGU                       75+#define TT_MAC_LANGID_SINHALESE                    76+#define TT_MAC_LANGID_BURMESE                      77+#define TT_MAC_LANGID_KHMER                        78+#define TT_MAC_LANGID_LAO                          79+#define TT_MAC_LANGID_VIETNAMESE                   80+#define TT_MAC_LANGID_INDONESIAN                   81+#define TT_MAC_LANGID_TAGALOG                      82+#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT           83+#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT          84+#define TT_MAC_LANGID_AMHARIC                      85+#define TT_MAC_LANGID_TIGRINYA                     86+#define TT_MAC_LANGID_GALLA                        87+#define TT_MAC_LANGID_SOMALI                       88+#define TT_MAC_LANGID_SWAHILI                      89+#define TT_MAC_LANGID_RUANDA                       90+#define TT_MAC_LANGID_RUNDI                        91+#define TT_MAC_LANGID_CHEWA                        92+#define TT_MAC_LANGID_MALAGASY                     93+#define TT_MAC_LANGID_ESPERANTO                    94+#define TT_MAC_LANGID_WELSH                       128+#define TT_MAC_LANGID_BASQUE                      129+#define TT_MAC_LANGID_CATALAN                     130+#define TT_MAC_LANGID_LATIN                       131+#define TT_MAC_LANGID_QUECHUA                     132+#define TT_MAC_LANGID_GUARANI                     133+#define TT_MAC_LANGID_AYMARA                      134+#define TT_MAC_LANGID_TATAR                       135+#define TT_MAC_LANGID_UIGHUR                      136+#define TT_MAC_LANGID_DZONGKHA                    137+#define TT_MAC_LANGID_JAVANESE                    138+#define TT_MAC_LANGID_SUNDANESE                   139+++#if 0  /* these seem to be errors that have been dropped */++#define TT_MAC_LANGID_SCOTTISH_GAELIC             140+#define TT_MAC_LANGID_IRISH_GAELIC                141++#endif+++  /* The following codes are new as of 2000-03-10 */+#define TT_MAC_LANGID_GALICIAN                    140+#define TT_MAC_LANGID_AFRIKAANS                   141+#define TT_MAC_LANGID_BRETON                      142+#define TT_MAC_LANGID_INUKTITUT                   143+#define TT_MAC_LANGID_SCOTTISH_GAELIC             144+#define TT_MAC_LANGID_MANX_GAELIC                 145+#define TT_MAC_LANGID_IRISH_GAELIC                146+#define TT_MAC_LANGID_TONGAN                      147+#define TT_MAC_LANGID_GREEK_POLYTONIC             148+#define TT_MAC_LANGID_GREELANDIC                  149+#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT    150+++  /*************************************************************************/+  /*                                                                       */+  /* Possible values of the language identifier field in the name records  */+  /* of the TTF `name' table if the `platform' identifier code is          */+  /* TT_PLATFORM_MICROSOFT.                                                */+  /*                                                                       */+  /* The canonical source for the MS assigned LCID's (seems to) be at      */+  /*                                                                       */+  /*   http://www.microsoft.com/globaldev/reference/lcid-all.mspx          */+  /*                                                                       */+  /* It used to be at various places, among them                           */+  /*                                                                       */+  /*   http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt              */+  /*   http://www.microsoft.com/globaldev/reference/loclanghome.asp        */+  /*   http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP      */+  /*   http://msdn.microsoft.com/library/en-us/passport25/                 */+  /*           NET_Passport_VBScript_Documentation/Single_Sign_In/         */+  /*           Advanced_Single_Sign_In/Localization_and_LCIDs.asp          */+  /*                                                                       */+  /* Hopefully, it seems now that the Globaldev site prevails...           */+  /*                                   (updated by Antoine, 2004-02-17)    */++#define TT_MS_LANGID_ARABIC_GENERAL                    0x0001+#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401+#define TT_MS_LANGID_ARABIC_IRAQ                       0x0801+#define TT_MS_LANGID_ARABIC_EGYPT                      0x0c01+#define TT_MS_LANGID_ARABIC_LIBYA                      0x1001+#define TT_MS_LANGID_ARABIC_ALGERIA                    0x1401+#define TT_MS_LANGID_ARABIC_MOROCCO                    0x1801+#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1c01+#define TT_MS_LANGID_ARABIC_OMAN                       0x2001+#define TT_MS_LANGID_ARABIC_YEMEN                      0x2401+#define TT_MS_LANGID_ARABIC_SYRIA                      0x2801+#define TT_MS_LANGID_ARABIC_JORDAN                     0x2c01+#define TT_MS_LANGID_ARABIC_LEBANON                    0x3001+#define TT_MS_LANGID_ARABIC_KUWAIT                     0x3401+#define TT_MS_LANGID_ARABIC_UAE                        0x3801+#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3c01+#define TT_MS_LANGID_ARABIC_QATAR                      0x4001+#define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402+#define TT_MS_LANGID_CATALAN_SPAIN                     0x0403+#define TT_MS_LANGID_CHINESE_GENERAL                   0x0004+#define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404+#define TT_MS_LANGID_CHINESE_PRC                       0x0804+#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0c04+#define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004++#if 1  /* this looks like the correct value */+#define TT_MS_LANGID_CHINESE_MACAU                     0x1404+#else  /* but beware, Microsoft may change its mind...+          the most recent Word reference has the following: */+#define TT_MS_LANGID_CHINESE_MACAU  TT_MS_LANGID_CHINESE_HONG_KONG+#endif++#if 0  /* used only with .NET `cultures'; commented out */+#define TT_MS_LANGID_CHINESE_TRADITIONAL               0x7C04+#endif++#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC              0x0405+#define TT_MS_LANGID_DANISH_DENMARK                    0x0406+#define TT_MS_LANGID_GERMAN_GERMANY                    0x0407+#define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807+#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0c07+#define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007+#define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407+#define TT_MS_LANGID_GREEK_GREECE                      0x0408++  /* don't ask what this one means... It is commented out currently. */+#if 0+#define TT_MS_LANGID_GREEK_GREECE2                     0x2008+#endif++#define TT_MS_LANGID_ENGLISH_GENERAL                   0x0009+#define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409+#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809+#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0c09+#define TT_MS_LANGID_ENGLISH_CANADA                    0x1009+#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND               0x1409+#define TT_MS_LANGID_ENGLISH_IRELAND                   0x1809+#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1c09+#define TT_MS_LANGID_ENGLISH_JAMAICA                   0x2009+#define TT_MS_LANGID_ENGLISH_CARIBBEAN                 0x2409+#define TT_MS_LANGID_ENGLISH_BELIZE                    0x2809+#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2c09+#define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009+#define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409+#define TT_MS_LANGID_ENGLISH_INDONESIA                 0x3809+#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3c09+#define TT_MS_LANGID_ENGLISH_INDIA                     0x4009+#define TT_MS_LANGID_ENGLISH_MALAYSIA                  0x4409+#define TT_MS_LANGID_ENGLISH_SINGAPORE                 0x4809+#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040a+#define TT_MS_LANGID_SPANISH_MEXICO                    0x080a+#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0c0a+#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100a+#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140a+#define TT_MS_LANGID_SPANISH_PANAMA                    0x180a+#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1c0a+#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200a+#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240a+#define TT_MS_LANGID_SPANISH_PERU                      0x280a+#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2c0a+#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300a+#define TT_MS_LANGID_SPANISH_CHILE                     0x340a+#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380a+#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3c0a+#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400a+#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440a+#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480a+#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4c0a+#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500a+#define TT_MS_LANGID_SPANISH_UNITED_STATES             0x540a+  /* The following ID blatantly violate MS specs by using a */+  /* sublanguage > 0x1F.                                    */+#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40aU+#define TT_MS_LANGID_FINNISH_FINLAND                   0x040b+#define TT_MS_LANGID_FRENCH_FRANCE                     0x040c+#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080c+#define TT_MS_LANGID_FRENCH_CANADA                     0x0c0c+#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100c+#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140c+#define TT_MS_LANGID_FRENCH_MONACO                     0x180c+#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1c0c+#define TT_MS_LANGID_FRENCH_REUNION                    0x200c+#define TT_MS_LANGID_FRENCH_CONGO                      0x240c+  /* which was formerly: */+#define TT_MS_LANGID_FRENCH_ZAIRE  TT_MS_LANGID_FRENCH_CONGO+#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280c+#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2c0c+#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300c+#define TT_MS_LANGID_FRENCH_MALI                       0x340c+#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380c+#define TT_MS_LANGID_FRENCH_HAITI                      0x3c0c+  /* and another violation of the spec (see 0xE40aU) */+#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40cU+#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040d+#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040e+#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040f+#define TT_MS_LANGID_ITALIAN_ITALY                     0x0410+#define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810+#define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411+#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA     0x0412+#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812+#define TT_MS_LANGID_DUTCH_NETHERLANDS                 0x0413+#define TT_MS_LANGID_DUTCH_BELGIUM                     0x0813+#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL           0x0414+#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK          0x0814+#define TT_MS_LANGID_POLISH_POLAND                     0x0415+#define TT_MS_LANGID_PORTUGUESE_BRAZIL                 0x0416+#define TT_MS_LANGID_PORTUGUESE_PORTUGAL               0x0816+#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND        0x0417+#define TT_MS_LANGID_ROMANIAN_ROMANIA                  0x0418+#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818+#define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419+#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819+#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041a+#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081a+#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0c1a++#if 0  /* this used to be this value, but it looks like we were wrong */+#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x101a+#else  /* current sources say */+#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA       0x101a+#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x141a+       /* and XPsp2 Platform SDK added (2004-07-26) */+       /* Names are shortened to be significant within 40 chars. */+#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN         0x181a+#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x181a+#endif++#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041b+#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041c+#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041d+#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081d+#define TT_MS_LANGID_THAI_THAILAND                     0x041e+#define TT_MS_LANGID_TURKISH_TURKEY                    0x041f+#define TT_MS_LANGID_URDU_PAKISTAN                     0x0420+#define TT_MS_LANGID_URDU_INDIA                        0x0820+#define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421+#define TT_MS_LANGID_UKRAINIAN_UKRAINE                 0x0422+#define TT_MS_LANGID_BELARUSIAN_BELARUS                0x0423+#define TT_MS_LANGID_SLOVENE_SLOVENIA                  0x0424+#define TT_MS_LANGID_ESTONIAN_ESTONIA                  0x0425+#define TT_MS_LANGID_LATVIAN_LATVIA                    0x0426+#define TT_MS_LANGID_LITHUANIAN_LITHUANIA              0x0427+#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827+#define TT_MS_LANGID_TAJIK_TAJIKISTAN                  0x0428+#define TT_MS_LANGID_FARSI_IRAN                        0x0429+#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042a+#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042b+#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042c+#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082c+#define TT_MS_LANGID_BASQUE_SPAIN                      0x042d+#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042e+#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042f+#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430+#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431+#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432+#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433+#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                0x0434+#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                 0x0435+#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA            0x0436+#define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437+#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438+#define TT_MS_LANGID_HINDI_INDIA                       0x0439+#define TT_MS_LANGID_MALTESE_MALTA                     0x043a+  /* Added by XPsp2 Platform SDK (2004-07-26) */+#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY              0x043b+#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN              0x083b+#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND             0x0C3b+#define TT_MS_LANGID_SAMI_LULE_NORWAY                  0x103b+#define TT_MS_LANGID_SAMI_LULE_SWEDEN                  0x143b+#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY              0x183b+#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN              0x1C3b+#define TT_MS_LANGID_SAMI_SKOLT_FINLAND                0x203b+#define TT_MS_LANGID_SAMI_INARI_FINLAND                0x243b+  /* ... and we also keep our old identifier... */+#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043b++#if 0 /* this seems to be a previous inversion */+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c+#else+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c+#endif++#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043d+#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043e+#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083e+#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043f+#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440+  /* alias declared in Windows 2000 */+#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \+          TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN++#define TT_MS_LANGID_SWAHILI_KENYA                     0x0441+#define TT_MS_LANGID_TURKMEN_TURKMENISTAN              0x0442+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC         0x0843+#define TT_MS_LANGID_TATAR_TATARSTAN                   0x0444+#define TT_MS_LANGID_BENGALI_INDIA                     0x0445+#define TT_MS_LANGID_BENGALI_BANGLADESH                0x0845+#define TT_MS_LANGID_PUNJABI_INDIA                     0x0446+#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN           0x0846+#define TT_MS_LANGID_GUJARATI_INDIA                    0x0447+#define TT_MS_LANGID_ORIYA_INDIA                       0x0448+#define TT_MS_LANGID_TAMIL_INDIA                       0x0449+#define TT_MS_LANGID_TELUGU_INDIA                      0x044a+#define TT_MS_LANGID_KANNADA_INDIA                     0x044b+#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044c+#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044d+#define TT_MS_LANGID_MARATHI_INDIA                     0x044e+#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044f+#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450+#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN      0x0850+#define TT_MS_LANGID_TIBETAN_CHINA                     0x0451+  /* Don't use the next constant!  It has            */+  /*   (1) the wrong spelling (Dzonghka)             */+  /*   (2) Microsoft doesn't officially define it -- */+  /*       at least it is not in the List of Local   */+  /*       ID Values.                                */+  /*   (3) Dzongkha is not the same language as      */+  /*       Tibetan, so merging it is wrong anyway.   */+  /*                                                 */+  /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW.    */+#define TT_MS_LANGID_DZONGHKA_BHUTAN                   0x0851++#if 0+  /* the following used to be defined */+#define TT_MS_LANGID_TIBETAN_BHUTAN                    0x0451+  /* ... but it was changed; */+#else+  /* So we will continue to #define it, but with the correct value */+#define TT_MS_LANGID_TIBETAN_BHUTAN   TT_MS_LANGID_DZONGHKA_BHUTAN+#endif++#define TT_MS_LANGID_WELSH_WALES                       0x0452+#define TT_MS_LANGID_KHMER_CAMBODIA                    0x0453+#define TT_MS_LANGID_LAO_LAOS                          0x0454+#define TT_MS_LANGID_BURMESE_MYANMAR                   0x0455+#define TT_MS_LANGID_GALICIAN_SPAIN                    0x0456+#define TT_MS_LANGID_KONKANI_INDIA                     0x0457+#define TT_MS_LANGID_MANIPURI_INDIA  /* Bengali */     0x0458+#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */         0x0459+#define TT_MS_LANGID_SINDHI_PAKISTAN                   0x0859+  /* Missing a LCID for Sindhi in Devanagari script */+#define TT_MS_LANGID_SYRIAC_SYRIA                      0x045a+#define TT_MS_LANGID_SINHALESE_SRI_LANKA               0x045b+#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045c+#define TT_MS_LANGID_INUKTITUT_CANADA                  0x045d+#define TT_MS_LANGID_AMHARIC_ETHIOPIA                  0x045e+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045f+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN           0x085f+  /* Missing a LCID for Tifinagh script */+#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */    0x0460+  /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */+  /* script is yet unclear... might be Arabic, Nagari or Sharada */+#define TT_MS_LANGID_KASHMIRI_SASIA                    0x0860+  /* ... and aliased (by MS) for compatibility reasons. */+#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA+#define TT_MS_LANGID_NEPALI_NEPAL                      0x0461+#define TT_MS_LANGID_NEPALI_INDIA                      0x0861+#define TT_MS_LANGID_FRISIAN_NETHERLANDS               0x0462+#define TT_MS_LANGID_PASHTO_AFGHANISTAN                0x0463+#define TT_MS_LANGID_FILIPINO_PHILIPPINES              0x0464+#define TT_MS_LANGID_DHIVEHI_MALDIVES                  0x0465+  /* alias declared in Windows 2000 */+#define TT_MS_LANGID_DIVEHI_MALDIVES  TT_MS_LANGID_DHIVEHI_MALDIVES+#define TT_MS_LANGID_EDO_NIGERIA                       0x0466+#define TT_MS_LANGID_FULFULDE_NIGERIA                  0x0467+#define TT_MS_LANGID_HAUSA_NIGERIA                     0x0468+#define TT_MS_LANGID_IBIBIO_NIGERIA                    0x0469+#define TT_MS_LANGID_YORUBA_NIGERIA                    0x046a+#define TT_MS_LANGID_QUECHUA_BOLIVIA                   0x046b+#define TT_MS_LANGID_QUECHUA_ECUADOR                   0x086b+#define TT_MS_LANGID_QUECHUA_PERU                      0x0c6b+#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA               0x046c+  /* Also spelled by XPsp2 Platform SDK (2004-07-26) */+#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \+          TT_MS_LANGID_SEPEDI_SOUTH_AFRICA+  /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */+#define TT_MS_LANGID_IGBO_NIGERIA                      0x0470+#define TT_MS_LANGID_KANURI_NIGERIA                    0x0471+#define TT_MS_LANGID_OROMO_ETHIOPIA                    0x0472+#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA                 0x0473+#define TT_MS_LANGID_TIGRIGNA_ERYTHREA                 0x0873+  /* also spelled in the `Passport SDK' list as: */+#define TT_MS_LANGID_TIGRIGNA_ERYTREA  TT_MS_LANGID_TIGRIGNA_ERYTHREA+#define TT_MS_LANGID_GUARANI_PARAGUAY                  0x0474+#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES            0x0475+#define TT_MS_LANGID_LATIN                             0x0476+#define TT_MS_LANGID_SOMALI_SOMALIA                    0x0477+  /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */+  /*       not written (but OTOH the peculiar writing system is worth     */+  /*       studying).                                                     */+#define TT_MS_LANGID_YI_CHINA                          0x0478+#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES   0x0479+  /* language codes from 0x047a to 0x047f are (still) unknown. */+#define TT_MS_LANGID_UIGHUR_CHINA                      0x0480+#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0481++#if 0  /* not deemed useful for fonts */+#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE            0x04ff+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* Possible values of the `name' identifier field in the name records of */+  /* the TTF `name' table.  These values are platform independent.         */+  /*                                                                       */+#define TT_NAME_ID_COPYRIGHT            0+#define TT_NAME_ID_FONT_FAMILY          1+#define TT_NAME_ID_FONT_SUBFAMILY       2+#define TT_NAME_ID_UNIQUE_ID            3+#define TT_NAME_ID_FULL_NAME            4+#define TT_NAME_ID_VERSION_STRING       5+#define TT_NAME_ID_PS_NAME              6+#define TT_NAME_ID_TRADEMARK            7++  /* the following values are from the OpenType spec */+#define TT_NAME_ID_MANUFACTURER         8+#define TT_NAME_ID_DESIGNER             9+#define TT_NAME_ID_DESCRIPTION          10+#define TT_NAME_ID_VENDOR_URL           11+#define TT_NAME_ID_DESIGNER_URL         12+#define TT_NAME_ID_LICENSE              13+#define TT_NAME_ID_LICENSE_URL          14+  /* number 15 is reserved */+#define TT_NAME_ID_PREFERRED_FAMILY     16+#define TT_NAME_ID_PREFERRED_SUBFAMILY  17+#define TT_NAME_ID_MAC_FULL_NAME        18++  /* The following code is new as of 2000-01-21 */+#define TT_NAME_ID_SAMPLE_TEXT          19++  /* This is new in OpenType 1.3 */+#define TT_NAME_ID_CID_FINDFONT_NAME    20++  /* This is new in OpenType 1.5 */+#define TT_NAME_ID_WWS_FAMILY           21+#define TT_NAME_ID_WWS_SUBFAMILY        22+++  /*************************************************************************/+  /*                                                                       */+  /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table.     */+  /*                                                                       */+  /* Updated 08-Nov-2008.                                                  */+  /*                                                                       */++  /* Bit  0   Basic Latin */+#define TT_UCR_BASIC_LATIN                     (1L <<  0) /* U+0020-U+007E */+  /* Bit  1   C1 Controls and Latin-1 Supplement */+#define TT_UCR_LATIN1_SUPPLEMENT               (1L <<  1) /* U+0080-U+00FF */+  /* Bit  2   Latin Extended-A */+#define TT_UCR_LATIN_EXTENDED_A                (1L <<  2) /* U+0100-U+017F */+  /* Bit  3   Latin Extended-B */+#define TT_UCR_LATIN_EXTENDED_B                (1L <<  3) /* U+0180-U+024F */+  /* Bit  4   IPA Extensions                 */+  /*          Phonetic Extensions            */+  /*          Phonetic Extensions Supplement */+#define TT_UCR_IPA_EXTENSIONS                  (1L <<  4) /* U+0250-U+02AF */+                                                          /* U+1D00-U+1D7F */+                                                          /* U+1D80-U+1DBF */+  /* Bit  5   Spacing Modifier Letters */+  /*          Modifier Tone Letters    */+#define TT_UCR_SPACING_MODIFIER                (1L <<  5) /* U+02B0-U+02FF */+                                                          /* U+A700-U+A71F */+  /* Bit  6   Combining Diacritical Marks            */+  /*          Combining Diacritical Marks Supplement */+#define TT_UCR_COMBINING_DIACRITICS            (1L <<  6) /* U+0300-U+036F */+                                                          /* U+1DC0-U+1DFF */+  /* Bit  7   Greek and Coptic */+#define TT_UCR_GREEK                           (1L <<  7) /* U+0370-U+03FF */+  /* Bit  8   Coptic */+#define TT_UCR_COPTIC                          (1L <<  8) /* U+2C80-U+2CFF */+  /* Bit  9   Cyrillic            */+  /*          Cyrillic Supplement */+  /*          Cyrillic Extended-A */+  /*          Cyrillic Extended-B */+#define TT_UCR_CYRILLIC                        (1L <<  9) /* U+0400-U+04FF */+                                                          /* U+0500-U+052F */+                                                          /* U+2DE0-U+2DFF */+                                                          /* U+A640-U+A69F */+  /* Bit 10   Armenian */+#define TT_UCR_ARMENIAN                        (1L << 10) /* U+0530-U+058F */+  /* Bit 11   Hebrew */+#define TT_UCR_HEBREW                          (1L << 11) /* U+0590-U+05FF */+  /* Bit 12   Vai */+#define TT_UCR_VAI                             (1L << 12) /* U+A500-U+A63F */+  /* Bit 13   Arabic            */+  /*          Arabic Supplement */+#define TT_UCR_ARABIC                          (1L << 13) /* U+0600-U+06FF */+                                                          /* U+0750-U+077F */+  /* Bit 14   NKo */+#define TT_UCR_NKO                             (1L << 14) /* U+07C0-U+07FF */+  /* Bit 15   Devanagari */+#define TT_UCR_DEVANAGARI                      (1L << 15) /* U+0900-U+097F */+  /* Bit 16   Bengali */+#define TT_UCR_BENGALI                         (1L << 16) /* U+0980-U+09FF */+  /* Bit 17   Gurmukhi */+#define TT_UCR_GURMUKHI                        (1L << 17) /* U+0A00-U+0A7F */+  /* Bit 18   Gujarati */+#define TT_UCR_GUJARATI                        (1L << 18) /* U+0A80-U+0AFF */+  /* Bit 19   Oriya */+#define TT_UCR_ORIYA                           (1L << 19) /* U+0B00-U+0B7F */+  /* Bit 20   Tamil */+#define TT_UCR_TAMIL                           (1L << 20) /* U+0B80-U+0BFF */+  /* Bit 21   Telugu */+#define TT_UCR_TELUGU                          (1L << 21) /* U+0C00-U+0C7F */+  /* Bit 22   Kannada */+#define TT_UCR_KANNADA                         (1L << 22) /* U+0C80-U+0CFF */+  /* Bit 23   Malayalam */+#define TT_UCR_MALAYALAM                       (1L << 23) /* U+0D00-U+0D7F */+  /* Bit 24   Thai */+#define TT_UCR_THAI                            (1L << 24) /* U+0E00-U+0E7F */+  /* Bit 25   Lao */+#define TT_UCR_LAO                             (1L << 25) /* U+0E80-U+0EFF */+  /* Bit 26   Georgian            */+  /*          Georgian Supplement */+#define TT_UCR_GEORGIAN                        (1L << 26) /* U+10A0-U+10FF */+                                                          /* U+2D00-U+2D2F */+  /* Bit 27   Balinese */+#define TT_UCR_BALINESE                        (1L << 27) /* U+1B00-U+1B7F */+  /* Bit 28   Hangul Jamo */+#define TT_UCR_HANGUL_JAMO                     (1L << 28) /* U+1100-U+11FF */+  /* Bit 29   Latin Extended Additional */+  /*          Latin Extended-C          */+  /*          Latin Extended-D          */+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL       (1L << 29) /* U+1E00-U+1EFF */+                                                          /* U+2C60-U+2C7F */+                                                          /* U+A720-U+A7FF */+  /* Bit 30   Greek Extended */+#define TT_UCR_GREEK_EXTENDED                  (1L << 30) /* U+1F00-U+1FFF */+  /* Bit 31   General Punctuation      */+  /*          Supplemental Punctuation */+#define TT_UCR_GENERAL_PUNCTUATION             (1L << 31) /* U+2000-U+206F */+                                                          /* U+2E00-U+2E7F */+  /* Bit 32   Superscripts And Subscripts */+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS         (1L <<  0) /* U+2070-U+209F */+  /* Bit 33   Currency Symbols */+#define TT_UCR_CURRENCY_SYMBOLS                (1L <<  1) /* U+20A0-U+20CF */+  /* Bit 34   Combining Diacritical Marks For Symbols */+#define TT_UCR_COMBINING_DIACRITICS_SYMB       (1L <<  2) /* U+20D0-U+20FF */+  /* Bit 35   Letterlike Symbols */+#define TT_UCR_LETTERLIKE_SYMBOLS              (1L <<  3) /* U+2100-U+214F */+  /* Bit 36   Number Forms */+#define TT_UCR_NUMBER_FORMS                    (1L <<  4) /* U+2150-U+218F */+  /* Bit 37   Arrows                           */+  /*          Supplemental Arrows-A            */+  /*          Supplemental Arrows-B            */+  /*          Miscellaneous Symbols and Arrows */+#define TT_UCR_ARROWS                          (1L <<  5) /* U+2190-U+21FF */+                                                          /* U+27F0-U+27FF */+                                                          /* U+2900-U+297F */+                                                          /* U+2B00-U+2BFF */+  /* Bit 38   Mathematical Operators               */+  /*          Supplemental Mathematical Operators  */+  /*          Miscellaneous Mathematical Symbols-A */+  /*          Miscellaneous Mathematical Symbols-B */+#define TT_UCR_MATHEMATICAL_OPERATORS          (1L <<  6) /* U+2200-U+22FF */+                                                          /* U+2A00-U+2AFF */+                                                          /* U+27C0-U+27EF */+                                                          /* U+2980-U+29FF */+  /* Bit 39 Miscellaneous Technical */+#define TT_UCR_MISCELLANEOUS_TECHNICAL         (1L <<  7) /* U+2300-U+23FF */+  /* Bit 40   Control Pictures */+#define TT_UCR_CONTROL_PICTURES                (1L <<  8) /* U+2400-U+243F */+  /* Bit 41   Optical Character Recognition */+#define TT_UCR_OCR                             (1L <<  9) /* U+2440-U+245F */+  /* Bit 42   Enclosed Alphanumerics */+#define TT_UCR_ENCLOSED_ALPHANUMERICS          (1L << 10) /* U+2460-U+24FF */+  /* Bit 43   Box Drawing */+#define TT_UCR_BOX_DRAWING                     (1L << 11) /* U+2500-U+257F */+  /* Bit 44   Block Elements */+#define TT_UCR_BLOCK_ELEMENTS                  (1L << 12) /* U+2580-U+259F */+  /* Bit 45   Geometric Shapes */+#define TT_UCR_GEOMETRIC_SHAPES                (1L << 13) /* U+25A0-U+25FF */+  /* Bit 46   Miscellaneous Symbols */+#define TT_UCR_MISCELLANEOUS_SYMBOLS           (1L << 14) /* U+2600-U+26FF */+  /* Bit 47   Dingbats */+#define TT_UCR_DINGBATS                        (1L << 15) /* U+2700-U+27BF */+  /* Bit 48   CJK Symbols and Punctuation */+#define TT_UCR_CJK_SYMBOLS                     (1L << 16) /* U+3000-U+303F */+  /* Bit 49   Hiragana */+#define TT_UCR_HIRAGANA                        (1L << 17) /* U+3040-U+309F */+  /* Bit 50   Katakana                     */+  /*          Katakana Phonetic Extensions */+#define TT_UCR_KATAKANA                        (1L << 18) /* U+30A0-U+30FF */+                                                          /* U+31F0-U+31FF */+  /* Bit 51   Bopomofo          */+  /*          Bopomofo Extended */+#define TT_UCR_BOPOMOFO                        (1L << 19) /* U+3100-U+312F */+                                                          /* U+31A0-U+31BF */+  /* Bit 52   Hangul Compatibility Jamo */+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO       (1L << 20) /* U+3130-U+318F */+  /* Bit 53   Phags-Pa */+#define TT_UCR_CJK_MISC                        (1L << 21) /* U+A840-U+A87F */+#define TT_UCR_KANBUN  TT_UCR_CJK_MISC /* deprecated */+#define TT_UCR_PHAGSPA+  /* Bit 54   Enclosed CJK Letters and Months */+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS     (1L << 22) /* U+3200-U+32FF */+  /* Bit 55   CJK Compatibility */+#define TT_UCR_CJK_COMPATIBILITY               (1L << 23) /* U+3300-U+33FF */+  /* Bit 56   Hangul Syllables */+#define TT_UCR_HANGUL                          (1L << 24) /* U+AC00-U+D7A3 */+  /* Bit 57   High Surrogates              */+  /*          High Private Use Surrogates  */+  /*          Low Surrogates               */+  /*                                       */+  /* According to OpenType specs v.1.3+,   */+  /* setting bit 57 implies that there is  */+  /* at least one codepoint beyond the     */+  /* Basic Multilingual Plane that is      */+  /* supported by this font.  So it really */+  /* means >= U+10000                      */+#define TT_UCR_SURROGATES                      (1L << 25) /* U+D800-U+DB7F */+                                                          /* U+DB80-U+DBFF */+                                                          /* U+DC00-U+DFFF */+#define TT_UCR_NON_PLANE_0  TT_UCR_SURROGATES+  /* Bit 58  Phoenician */+#define TT_UCR_PHOENICIAN                      (1L << 26) /*U+10900-U+1091F*/+  /* Bit 59   CJK Unified Ideographs             */+  /*          CJK Radicals Supplement            */+  /*          Kangxi Radicals                    */+  /*          Ideographic Description Characters */+  /*          CJK Unified Ideographs Extension A */+  /*          CJK Unified Ideographs Extension B */+  /*          Kanbun                             */+#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS          (1L << 27) /* U+4E00-U+9FFF */+                                                          /* U+2E80-U+2EFF */+                                                          /* U+2F00-U+2FDF */+                                                          /* U+2FF0-U+2FFF */+                                                          /* U+3400-U+4DB5 */+                                                          /*U+20000-U+2A6DF*/+                                                          /* U+3190-U+319F */+  /* Bit 60   Private Use */+#define TT_UCR_PRIVATE_USE                     (1L << 28) /* U+E000-U+F8FF */+  /* Bit 61   CJK Strokes                             */+  /*          CJK Compatibility Ideographs            */+  /*          CJK Compatibility Ideographs Supplement */+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS    (1L << 29) /* U+31C0-U+31EF */+                                                          /* U+F900-U+FAFF */+                                                          /*U+2F800-U+2FA1F*/+  /* Bit 62   Alphabetic Presentation Forms */+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS   (1L << 30) /* U+FB00-U+FB4F */+  /* Bit 63   Arabic Presentation Forms-A */+#define TT_UCR_ARABIC_PRESENTATIONS_A          (1L << 31) /* U+FB50-U+FDFF */+  /* Bit 64   Combining Half Marks */+#define TT_UCR_COMBINING_HALF_MARKS            (1L <<  0) /* U+FE20-U+FE2F */+  /* Bit 65   Vertical forms          */+  /*          CJK Compatibility Forms */+#define TT_UCR_CJK_COMPATIBILITY_FORMS         (1L <<  1) /* U+FE10-U+FE1F */+                                                          /* U+FE30-U+FE4F */+  /* Bit 66   Small Form Variants */+#define TT_UCR_SMALL_FORM_VARIANTS             (1L <<  2) /* U+FE50-U+FE6F */+  /* Bit 67   Arabic Presentation Forms-B */+#define TT_UCR_ARABIC_PRESENTATIONS_B          (1L <<  3) /* U+FE70-U+FEFE */+  /* Bit 68   Halfwidth and Fullwidth Forms */+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS       (1L <<  4) /* U+FF00-U+FFEF */+  /* Bit 69   Specials */+#define TT_UCR_SPECIALS                        (1L <<  5) /* U+FFF0-U+FFFD */+  /* Bit 70   Tibetan */+#define TT_UCR_TIBETAN                         (1L <<  6) /* U+0F00-U+0FFF */+  /* Bit 71   Syriac */+#define TT_UCR_SYRIAC                          (1L <<  7) /* U+0700-U+074F */+  /* Bit 72   Thaana */+#define TT_UCR_THAANA                          (1L <<  8) /* U+0780-U+07BF */+  /* Bit 73   Sinhala */+#define TT_UCR_SINHALA                         (1L <<  9) /* U+0D80-U+0DFF */+  /* Bit 74   Myanmar */+#define TT_UCR_MYANMAR                         (1L << 10) /* U+1000-U+109F */+  /* Bit 75   Ethiopic            */+  /*          Ethiopic Supplement */+  /*          Ethiopic Extended   */+#define TT_UCR_ETHIOPIC                        (1L << 11) /* U+1200-U+137F */+                                                          /* U+1380-U+139F */+                                                          /* U+2D80-U+2DDF */+  /* Bit 76   Cherokee */+#define TT_UCR_CHEROKEE                        (1L << 12) /* U+13A0-U+13FF */+  /* Bit 77   Unified Canadian Aboriginal Syllabics */+#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS   (1L << 13) /* U+1400-U+167F */+  /* Bit 78   Ogham */+#define TT_UCR_OGHAM                           (1L << 14) /* U+1680-U+169F */+  /* Bit 79   Runic */+#define TT_UCR_RUNIC                           (1L << 15) /* U+16A0-U+16FF */+  /* Bit 80   Khmer         */+  /*          Khmer Symbols */+#define TT_UCR_KHMER                           (1L << 16) /* U+1780-U+17FF */+                                                          /* U+19E0-U+19FF */+  /* Bit 81   Mongolian */+#define TT_UCR_MONGOLIAN                       (1L << 17) /* U+1800-U+18AF */+  /* Bit 82   Braille Patterns */+#define TT_UCR_BRAILLE                         (1L << 18) /* U+2800-U+28FF */+  /* Bit 83   Yi Syllables */+  /*          Yi Radicals  */+#define TT_UCR_YI                              (1L << 19) /* U+A000-U+A48F */+                                                          /* U+A490-U+A4CF */+  /* Bit 84   Tagalog  */+  /*          Hanunoo  */+  /*          Buhid    */+  /*          Tagbanwa */+#define TT_UCR_PHILIPPINE                      (1L << 20) /* U+1700-U+171F */+                                                          /* U+1720-U+173F */+                                                          /* U+1740-U+175F */+                                                          /* U+1760-U+177F */+  /* Bit 85   Old Italic */+#define TT_UCR_OLD_ITALIC                      (1L << 21) /*U+10300-U+1032F*/+  /* Bit 86   Gothic */+#define TT_UCR_GOTHIC                          (1L << 22) /*U+10330-U+1034F*/+  /* Bit 87   Deseret */+#define TT_UCR_DESERET                         (1L << 23) /*U+10400-U+1044F*/+  /* Bit 88   Byzantine Musical Symbols      */+  /*          Musical Symbols                */+  /*          Ancient Greek Musical Notation */+#define TT_UCR_MUSICAL_SYMBOLS                 (1L << 24) /*U+1D000-U+1D0FF*/+                                                          /*U+1D100-U+1D1FF*/+                                                          /*U+1D200-U+1D24F*/+  /* Bit 89   Mathematical Alphanumeric Symbols */+#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS       (1L << 25) /*U+1D400-U+1D7FF*/+  /* Bit 90   Private Use (plane 15) */+  /*          Private Use (plane 16) */+#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY       (1L << 26) /*U+F0000-U+FFFFD*/+                                                        /*U+100000-U+10FFFD*/+  /* Bit 91   Variation Selectors            */+  /*          Variation Selectors Supplement */+#define TT_UCR_VARIATION_SELECTORS             (1L << 27) /* U+FE00-U+FE0F */+                                                          /*U+E0100-U+E01EF*/+  /* Bit 92   Tags */+#define TT_UCR_TAGS                            (1L << 28) /*U+E0000-U+E007F*/+  /* Bit 93   Limbu */+#define TT_UCR_LIMBU                           (1L << 29) /* U+1900-U+194F */+  /* Bit 94   Tai Le */+#define TT_UCR_TAI_LE                          (1L << 30) /* U+1950-U+197F */+  /* Bit 95   New Tai Lue */+#define TT_UCR_NEW_TAI_LUE                     (1L << 31) /* U+1980-U+19DF */+  /* Bit 96   Buginese */+#define TT_UCR_BUGINESE                        (1L <<  0) /* U+1A00-U+1A1F */+  /* Bit 97   Glagolitic */+#define TT_UCR_GLAGOLITIC                      (1L <<  1) /* U+2C00-U+2C5F */+  /* Bit 98   Tifinagh */+#define TT_UCR_TIFINAGH                        (1L <<  2) /* U+2D30-U+2D7F */+  /* Bit 99   Yijing Hexagram Symbols */+#define TT_UCR_YIJING                          (1L <<  3) /* U+4DC0-U+4DFF */+  /* Bit 100  Syloti Nagri */+#define TT_UCR_SYLOTI_NAGRI                    (1L <<  4) /* U+A800-U+A82F */+  /* Bit 101  Linear B Syllabary */+  /*          Linear B Ideograms */+  /*          Aegean Numbers     */+#define TT_UCR_LINEAR_B                        (1L <<  5) /*U+10000-U+1007F*/+                                                          /*U+10080-U+100FF*/+                                                          /*U+10100-U+1013F*/+  /* Bit 102  Ancient Greek Numbers */+#define TT_UCR_ANCIENT_GREEK_NUMBERS           (1L <<  6) /*U+10140-U+1018F*/+  /* Bit 103  Ugaritic */+#define TT_UCR_UGARITIC                        (1L <<  7) /*U+10380-U+1039F*/+  /* Bit 104  Old Persian */+#define TT_UCR_OLD_PERSIAN                     (1L <<  8) /*U+103A0-U+103DF*/+  /* Bit 105  Shavian */+#define TT_UCR_SHAVIAN                         (1L <<  9) /*U+10450-U+1047F*/+  /* Bit 106  Osmanya */+#define TT_UCR_OSMANYA                         (1L << 10) /*U+10480-U+104AF*/+  /* Bit 107  Cypriot Syllabary */+#define TT_UCR_CYPRIOT_SYLLABARY               (1L << 11) /*U+10800-U+1083F*/+  /* Bit 108  Kharoshthi */+#define TT_UCR_KHAROSHTHI                      (1L << 12) /*U+10A00-U+10A5F*/+  /* Bit 109  Tai Xuan Jing Symbols */+#define TT_UCR_TAI_XUAN_JING                   (1L << 13) /*U+1D300-U+1D35F*/+  /* Bit 110  Cuneiform                         */+  /*          Cuneiform Numbers and Punctuation */+#define TT_UCR_CUNEIFORM                       (1L << 14) /*U+12000-U+123FF*/+                                                          /*U+12400-U+1247F*/+  /* Bit 111  Counting Rod Numerals */+#define TT_UCR_COUNTING_ROD_NUMERALS           (1L << 15) /*U+1D360-U+1D37F*/+  /* Bit 112  Sundanese */+#define TT_UCR_SUNDANESE                       (1L << 16) /* U+1B80-U+1BBF */+  /* Bit 113  Lepcha */+#define TT_UCR_LEPCHA                          (1L << 17) /* U+1C00-U+1C4F */+  /* Bit 114  Ol Chiki */+#define TT_UCR_OL_CHIKI                        (1L << 18) /* U+1C50-U+1C7F */+  /* Bit 115  Saurashtra */+#define TT_UCR_SAURASHTRA                      (1L << 19) /* U+A880-U+A8DF */+  /* Bit 116  Kayah Li */+#define TT_UCR_KAYAH_LI                        (1L << 20) /* U+A900-U+A92F */+  /* Bit 117  Rejang */+#define TT_UCR_REJANG                          (1L << 21) /* U+A930-U+A95F */+  /* Bit 118  Cham */+#define TT_UCR_CHAM                            (1L << 22) /* U+AA00-U+AA5F */+  /* Bit 119  Ancient Symbols */+#define TT_UCR_ANCIENT_SYMBOLS                 (1L << 23) /*U+10190-U+101CF*/+  /* Bit 120  Phaistos Disc */+#define TT_UCR_PHAISTOS_DISC                   (1L << 24) /*U+101D0-U+101FF*/+  /* Bit 121  Carian */+  /*          Lycian */+  /*          Lydian */+#define TT_UCR_OLD_ANATOLIAN                   (1L << 25) /*U+102A0-U+102DF*/+                                                          /*U+10280-U+1029F*/+                                                          /*U+10920-U+1093F*/+  /* Bit 122  Domino Tiles  */+  /*          Mahjong Tiles */+#define TT_UCR_GAME_TILES                      (1L << 26) /*U+1F030-U+1F09F*/+                                                          /*U+1F000-U+1F02F*/+  /* Bit 123-127 Reserved for process-internal usage */+++  /*************************************************************************/+  /*                                                                       */+  /* Some compilers have a very limited length of identifiers.             */+  /*                                                                       */+#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ )+#define HAVE_LIMIT_ON_IDENTS+#endif+++#ifndef HAVE_LIMIT_ON_IDENTS+++  /*************************************************************************/+  /*                                                                       */+  /* Here some alias #defines in order to be clearer.                      */+  /*                                                                       */+  /* These are not always #defined to stay within the 31~character limit   */+  /* which some compilers have.                                            */+  /*                                                                       */+  /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern  */+  /* Borland compilers (read: from BC++ 3.1 on) can increase this limit.   */+  /* If you get a warning with such a compiler, use the -i40 switch.       */+  /*                                                                       */+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      \+         TT_UCR_ARABIC_PRESENTATIONS_A+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      \+         TT_UCR_ARABIC_PRESENTATIONS_B++#define TT_UCR_COMBINING_DIACRITICAL_MARKS      \+         TT_UCR_COMBINING_DIACRITICS+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \+         TT_UCR_COMBINING_DIACRITICS_SYMB+++#endif /* !HAVE_LIMIT_ON_IDENTS */+++FT_END_HEADER++#endif /* __TTNAMEID_H__ */+++/* END */
+ include/freetype/tttables.h view
@@ -0,0 +1,759 @@+/***************************************************************************/+/*                                                                         */+/*  tttables.h                                                             */+/*                                                                         */+/*    Basic SFNT/TrueType tables definitions and interface                 */+/*    (specification only).                                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTTABLES_H__+#define __TTTABLES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    truetype_tables                                                    */+  /*                                                                       */+  /* <Title>                                                               */+  /*    TrueType Tables                                                    */+  /*                                                                       */+  /* <Abstract>                                                            */+  /*    TrueType specific table types and functions.                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This section contains the definition of TrueType-specific tables   */+  /*    as well as some routines used to access and process them.          */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Header                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType font header table.  All       */+  /*    fields follow the TrueType specification.                          */+  /*                                                                       */+  typedef struct  TT_Header_+  {+    FT_Fixed   Table_Version;+    FT_Fixed   Font_Revision;++    FT_Long    CheckSum_Adjust;+    FT_Long    Magic_Number;++    FT_UShort  Flags;+    FT_UShort  Units_Per_EM;++    FT_Long    Created [2];+    FT_Long    Modified[2];++    FT_Short   xMin;+    FT_Short   yMin;+    FT_Short   xMax;+    FT_Short   yMax;++    FT_UShort  Mac_Style;+    FT_UShort  Lowest_Rec_PPEM;++    FT_Short   Font_Direction;+    FT_Short   Index_To_Loc_Format;+    FT_Short   Glyph_Data_Format;++  } TT_Header;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_HoriHeader                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType horizontal header, the `hhea' */+  /*    table, as well as the corresponding horizontal metrics table,      */+  /*    i.e., the `hmtx' table.                                            */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    Version                :: The table version.                       */+  /*                                                                       */+  /*    Ascender               :: The font's ascender, i.e., the distance  */+  /*                              from the baseline to the top-most of all */+  /*                              glyph points found in the font.          */+  /*                                                                       */+  /*                              This value is invalid in many fonts, as  */+  /*                              it is usually set by the font designer,  */+  /*                              and often reflects only a portion of the */+  /*                              glyphs found in the font (maybe ASCII).  */+  /*                                                                       */+  /*                              You should use the `sTypoAscender' field */+  /*                              of the OS/2 table instead if you want    */+  /*                              the correct one.                         */+  /*                                                                       */+  /*    Descender              :: The font's descender, i.e., the distance */+  /*                              from the baseline to the bottom-most of  */+  /*                              all glyph points found in the font.  It  */+  /*                              is negative.                             */+  /*                                                                       */+  /*                              This value is invalid in many fonts, as  */+  /*                              it is usually set by the font designer,  */+  /*                              and often reflects only a portion of the */+  /*                              glyphs found in the font (maybe ASCII).  */+  /*                                                                       */+  /*                              You should use the `sTypoDescender'      */+  /*                              field of the OS/2 table instead if you   */+  /*                              want the correct one.                    */+  /*                                                                       */+  /*    Line_Gap               :: The font's line gap, i.e., the distance  */+  /*                              to add to the ascender and descender to  */+  /*                              get the BTB, i.e., the                   */+  /*                              baseline-to-baseline distance for the    */+  /*                              font.                                    */+  /*                                                                       */+  /*    advance_Width_Max      :: This field is the maximum of all advance */+  /*                              widths found in the font.  It can be     */+  /*                              used to compute the maximum width of an  */+  /*                              arbitrary string of text.                */+  /*                                                                       */+  /*    min_Left_Side_Bearing  :: The minimum left side bearing of all     */+  /*                              glyphs within the font.                  */+  /*                                                                       */+  /*    min_Right_Side_Bearing :: The minimum right side bearing of all    */+  /*                              glyphs within the font.                  */+  /*                                                                       */+  /*    xMax_Extent            :: The maximum horizontal extent (i.e., the */+  /*                              `width' of a glyph's bounding box) for   */+  /*                              all glyphs in the font.                  */+  /*                                                                       */+  /*    caret_Slope_Rise       :: The rise coefficient of the cursor's     */+  /*                              slope of the cursor (slope=rise/run).    */+  /*                                                                       */+  /*    caret_Slope_Run        :: The run coefficient of the cursor's      */+  /*                              slope.                                   */+  /*                                                                       */+  /*    Reserved               :: 8~reserved bytes.                        */+  /*                                                                       */+  /*    metric_Data_Format     :: Always~0.                                */+  /*                                                                       */+  /*    number_Of_HMetrics     :: Number of HMetrics entries in the `hmtx' */+  /*                              table -- this value can be smaller than  */+  /*                              the total number of glyphs in the font.  */+  /*                                                                       */+  /*    long_metrics           :: A pointer into the `hmtx' table.         */+  /*                                                                       */+  /*    short_metrics          :: A pointer into the `hmtx' table.         */+  /*                                                                       */+  /* <Note>                                                                */+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */+  /*               be identical except for the names of their fields which */+  /*               are different.                                          */+  /*                                                                       */+  /*               This ensures that a single function in the `ttload'     */+  /*               module is able to read both the horizontal and vertical */+  /*               headers.                                                */+  /*                                                                       */+  typedef struct  TT_HoriHeader_+  {+    FT_Fixed   Version;+    FT_Short   Ascender;+    FT_Short   Descender;+    FT_Short   Line_Gap;++    FT_UShort  advance_Width_Max;      /* advance width maximum */++    FT_Short   min_Left_Side_Bearing;  /* minimum left-sb       */+    FT_Short   min_Right_Side_Bearing; /* minimum right-sb      */+    FT_Short   xMax_Extent;            /* xmax extents          */+    FT_Short   caret_Slope_Rise;+    FT_Short   caret_Slope_Run;+    FT_Short   caret_Offset;++    FT_Short   Reserved[4];++    FT_Short   metric_Data_Format;+    FT_UShort  number_Of_HMetrics;++    /* The following fields are not defined by the TrueType specification */+    /* but they are used to connect the metrics header to the relevant    */+    /* `HMTX' table.                                                      */++    void*      long_metrics;+    void*      short_metrics;++  } TT_HoriHeader;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_VertHeader                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType vertical header, the `vhea'   */+  /*    table, as well as the corresponding vertical metrics table, i.e.,  */+  /*    the `vmtx' table.                                                  */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    Version                 :: The table version.                      */+  /*                                                                       */+  /*    Ascender                :: The font's ascender, i.e., the distance */+  /*                               from the baseline to the top-most of    */+  /*                               all glyph points found in the font.     */+  /*                                                                       */+  /*                               This value is invalid in many fonts, as */+  /*                               it is usually set by the font designer, */+  /*                               and often reflects only a portion of    */+  /*                               the glyphs found in the font (maybe     */+  /*                               ASCII).                                 */+  /*                                                                       */+  /*                               You should use the `sTypoAscender'      */+  /*                               field of the OS/2 table instead if you  */+  /*                               want the correct one.                   */+  /*                                                                       */+  /*    Descender               :: The font's descender, i.e., the         */+  /*                               distance from the baseline to the       */+  /*                               bottom-most of all glyph points found   */+  /*                               in the font.  It is negative.           */+  /*                                                                       */+  /*                               This value is invalid in many fonts, as */+  /*                               it is usually set by the font designer, */+  /*                               and often reflects only a portion of    */+  /*                               the glyphs found in the font (maybe     */+  /*                               ASCII).                                 */+  /*                                                                       */+  /*                               You should use the `sTypoDescender'     */+  /*                               field of the OS/2 table instead if you  */+  /*                               want the correct one.                   */+  /*                                                                       */+  /*    Line_Gap                :: The font's line gap, i.e., the distance */+  /*                               to add to the ascender and descender to */+  /*                               get the BTB, i.e., the                  */+  /*                               baseline-to-baseline distance for the   */+  /*                               font.                                   */+  /*                                                                       */+  /*    advance_Height_Max      :: This field is the maximum of all        */+  /*                               advance heights found in the font.  It  */+  /*                               can be used to compute the maximum      */+  /*                               height of an arbitrary string of text.  */+  /*                                                                       */+  /*    min_Top_Side_Bearing    :: The minimum top side bearing of all     */+  /*                               glyphs within the font.                 */+  /*                                                                       */+  /*    min_Bottom_Side_Bearing :: The minimum bottom side bearing of all  */+  /*                               glyphs within the font.                 */+  /*                                                                       */+  /*    yMax_Extent             :: The maximum vertical extent (i.e., the  */+  /*                               `height' of a glyph's bounding box) for */+  /*                               all glyphs in the font.                 */+  /*                                                                       */+  /*    caret_Slope_Rise        :: The rise coefficient of the cursor's    */+  /*                               slope of the cursor (slope=rise/run).   */+  /*                                                                       */+  /*    caret_Slope_Run         :: The run coefficient of the cursor's     */+  /*                               slope.                                  */+  /*                                                                       */+  /*    caret_Offset            :: The cursor's offset for slanted fonts.  */+  /*                               This value is `reserved' in vmtx        */+  /*                               version 1.0.                            */+  /*                                                                       */+  /*    Reserved                :: 8~reserved bytes.                       */+  /*                                                                       */+  /*    metric_Data_Format      :: Always~0.                               */+  /*                                                                       */+  /*    number_Of_HMetrics      :: Number of VMetrics entries in the       */+  /*                               `vmtx' table -- this value can be       */+  /*                               smaller than the total number of glyphs */+  /*                               in the font.                            */+  /*                                                                       */+  /*    long_metrics           :: A pointer into the `vmtx' table.         */+  /*                                                                       */+  /*    short_metrics          :: A pointer into the `vmtx' table.         */+  /*                                                                       */+  /* <Note>                                                                */+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */+  /*               be identical except for the names of their fields which */+  /*               are different.                                          */+  /*                                                                       */+  /*               This ensures that a single function in the `ttload'     */+  /*               module is able to read both the horizontal and vertical */+  /*               headers.                                                */+  /*                                                                       */+  typedef struct  TT_VertHeader_+  {+    FT_Fixed   Version;+    FT_Short   Ascender;+    FT_Short   Descender;+    FT_Short   Line_Gap;++    FT_UShort  advance_Height_Max;      /* advance height maximum */++    FT_Short   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */+    FT_Short   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */+    FT_Short   yMax_Extent;             /* xmax or ymax extents            */+    FT_Short   caret_Slope_Rise;+    FT_Short   caret_Slope_Run;+    FT_Short   caret_Offset;++    FT_Short   Reserved[4];++    FT_Short   metric_Data_Format;+    FT_UShort  number_Of_VMetrics;++    /* The following fields are not defined by the TrueType specification */+    /* but they're used to connect the metrics header to the relevant     */+    /* `HMTX' or `VMTX' table.                                            */++    void*      long_metrics;+    void*      short_metrics;++  } TT_VertHeader;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_OS2                                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType OS/2 table. This is the long  */+  /*    table version.  All fields comply to the TrueType specification.   */+  /*                                                                       */+  /*    Note that we now support old Mac fonts which do not include an     */+  /*    OS/2 table.  In this case, the `version' field is always set to    */+  /*    0xFFFF.                                                            */+  /*                                                                       */+  typedef struct  TT_OS2_+  {+    FT_UShort  version;                /* 0x0001 - more or 0xFFFF */+    FT_Short   xAvgCharWidth;+    FT_UShort  usWeightClass;+    FT_UShort  usWidthClass;+    FT_Short   fsType;+    FT_Short   ySubscriptXSize;+    FT_Short   ySubscriptYSize;+    FT_Short   ySubscriptXOffset;+    FT_Short   ySubscriptYOffset;+    FT_Short   ySuperscriptXSize;+    FT_Short   ySuperscriptYSize;+    FT_Short   ySuperscriptXOffset;+    FT_Short   ySuperscriptYOffset;+    FT_Short   yStrikeoutSize;+    FT_Short   yStrikeoutPosition;+    FT_Short   sFamilyClass;++    FT_Byte    panose[10];++    FT_ULong   ulUnicodeRange1;        /* Bits 0-31   */+    FT_ULong   ulUnicodeRange2;        /* Bits 32-63  */+    FT_ULong   ulUnicodeRange3;        /* Bits 64-95  */+    FT_ULong   ulUnicodeRange4;        /* Bits 96-127 */++    FT_Char    achVendID[4];++    FT_UShort  fsSelection;+    FT_UShort  usFirstCharIndex;+    FT_UShort  usLastCharIndex;+    FT_Short   sTypoAscender;+    FT_Short   sTypoDescender;+    FT_Short   sTypoLineGap;+    FT_UShort  usWinAscent;+    FT_UShort  usWinDescent;++    /* only version 1 tables: */++    FT_ULong   ulCodePageRange1;       /* Bits 0-31   */+    FT_ULong   ulCodePageRange2;       /* Bits 32-63  */++    /* only version 2 tables: */++    FT_Short   sxHeight;+    FT_Short   sCapHeight;+    FT_UShort  usDefaultChar;+    FT_UShort  usBreakChar;+    FT_UShort  usMaxContext;++  } TT_OS2;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_Postscript                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType PostScript table.  All fields */+  /*    comply to the TrueType specification.  This structure does not     */+  /*    reference the PostScript glyph names, which can be nevertheless    */+  /*    accessed with the `ttpost' module.                                 */+  /*                                                                       */+  typedef struct  TT_Postscript_+  {+    FT_Fixed  FormatType;+    FT_Fixed  italicAngle;+    FT_Short  underlinePosition;+    FT_Short  underlineThickness;+    FT_ULong  isFixedPitch;+    FT_ULong  minMemType42;+    FT_ULong  maxMemType42;+    FT_ULong  minMemType1;+    FT_ULong  maxMemType1;++    /* Glyph names follow in the file, but we don't   */+    /* load them by default.  See the ttpost.c file.  */++  } TT_Postscript;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_PCLT                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a TrueType PCLT table.  All fields       */+  /*    comply to the TrueType specification.                              */+  /*                                                                       */+  typedef struct  TT_PCLT_+  {+    FT_Fixed   Version;+    FT_ULong   FontNumber;+    FT_UShort  Pitch;+    FT_UShort  xHeight;+    FT_UShort  Style;+    FT_UShort  TypeFamily;+    FT_UShort  CapHeight;+    FT_UShort  SymbolSet;+    FT_Char    TypeFace[16];+    FT_Char    CharacterComplement[8];+    FT_Char    FileName[6];+    FT_Char    StrokeWeight;+    FT_Char    WidthType;+    FT_Byte    SerifStyle;+    FT_Byte    Reserved;++  } TT_PCLT;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_MaxProfile                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The maximum profile is a table containing many max values which    */+  /*    can be used to pre-allocate arrays.  This ensures that no memory   */+  /*    allocation occurs during a glyph load.                             */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    version               :: The version number.                       */+  /*                                                                       */+  /*    numGlyphs             :: The number of glyphs in this TrueType     */+  /*                             font.                                     */+  /*                                                                       */+  /*    maxPoints             :: The maximum number of points in a         */+  /*                             non-composite TrueType glyph.  See also   */+  /*                             the structure element                     */+  /*                             `maxCompositePoints'.                     */+  /*                                                                       */+  /*    maxContours           :: The maximum number of contours in a       */+  /*                             non-composite TrueType glyph.  See also   */+  /*                             the structure element                     */+  /*                             `maxCompositeContours'.                   */+  /*                                                                       */+  /*    maxCompositePoints    :: The maximum number of points in a         */+  /*                             composite TrueType glyph.  See also the   */+  /*                             structure element `maxPoints'.            */+  /*                                                                       */+  /*    maxCompositeContours  :: The maximum number of contours in a       */+  /*                             composite TrueType glyph.  See also the   */+  /*                             structure element `maxContours'.          */+  /*                                                                       */+  /*    maxZones              :: The maximum number of zones used for      */+  /*                             glyph hinting.                            */+  /*                                                                       */+  /*    maxTwilightPoints     :: The maximum number of points in the       */+  /*                             twilight zone used for glyph hinting.     */+  /*                                                                       */+  /*    maxStorage            :: The maximum number of elements in the     */+  /*                             storage area used for glyph hinting.      */+  /*                                                                       */+  /*    maxFunctionDefs       :: The maximum number of function            */+  /*                             definitions in the TrueType bytecode for  */+  /*                             this font.                                */+  /*                                                                       */+  /*    maxInstructionDefs    :: The maximum number of instruction         */+  /*                             definitions in the TrueType bytecode for  */+  /*                             this font.                                */+  /*                                                                       */+  /*    maxStackElements      :: The maximum number of stack elements used */+  /*                             during bytecode interpretation.           */+  /*                                                                       */+  /*    maxSizeOfInstructions :: The maximum number of TrueType opcodes    */+  /*                             used for glyph hinting.                   */+  /*                                                                       */+  /*    maxComponentElements  :: The maximum number of simple (i.e., non-  */+  /*                             composite) glyphs in a composite glyph.   */+  /*                                                                       */+  /*    maxComponentDepth     :: The maximum nesting depth of composite    */+  /*                             glyphs.                                   */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This structure is only used during font loading.                   */+  /*                                                                       */+  typedef struct  TT_MaxProfile_+  {+    FT_Fixed   version;+    FT_UShort  numGlyphs;+    FT_UShort  maxPoints;+    FT_UShort  maxContours;+    FT_UShort  maxCompositePoints;+    FT_UShort  maxCompositeContours;+    FT_UShort  maxZones;+    FT_UShort  maxTwilightPoints;+    FT_UShort  maxStorage;+    FT_UShort  maxFunctionDefs;+    FT_UShort  maxInstructionDefs;+    FT_UShort  maxStackElements;+    FT_UShort  maxSizeOfInstructions;+    FT_UShort  maxComponentElements;+    FT_UShort  maxComponentDepth;++  } TT_MaxProfile;+++  /*************************************************************************/+  /*                                                                       */+  /* <Enum>                                                                */+  /*    FT_Sfnt_Tag                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    An enumeration used to specify the index of an SFNT table.         */+  /*    Used in the @FT_Get_Sfnt_Table API function.                       */+  /*                                                                       */+  typedef enum  FT_Sfnt_Tag_+  {+    ft_sfnt_head = 0,    /* TT_Header     */+    ft_sfnt_maxp = 1,    /* TT_MaxProfile */+    ft_sfnt_os2  = 2,    /* TT_OS2        */+    ft_sfnt_hhea = 3,    /* TT_HoriHeader */+    ft_sfnt_vhea = 4,    /* TT_VertHeader */+    ft_sfnt_post = 5,    /* TT_Postscript */+    ft_sfnt_pclt = 6,    /* TT_PCLT       */++    sfnt_max   /* internal end mark */++  } FT_Sfnt_Tag;++  /* */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_Sfnt_Table                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return a pointer to a given SFNT table within a face.              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source.                                    */+  /*                                                                       */+  /*    tag  :: The index of the SFNT table.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A type-less pointer to the table.  This will be~0 in case of       */+  /*    error, or if the corresponding table was not found *OR* loaded     */+  /*    from the file.                                                     */+  /*                                                                       */+  /*    Use a typecast according to `tag' to access the structure          */+  /*    elements.                                                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The table is owned by the face object and disappears with it.      */+  /*                                                                       */+  /*    This function is only useful to access SFNT tables that are loaded */+  /*    by the sfnt, truetype, and opentype drivers.  See @FT_Sfnt_Tag for */+  /*    a list.                                                            */+  /*                                                                       */+  FT_EXPORT( void* )+  FT_Get_Sfnt_Table( FT_Face      face,+                     FT_Sfnt_Tag  tag );+++ /**************************************************************************+  *+  * @function:+  *   FT_Load_Sfnt_Table+  *+  * @description:+  *   Load any font table into client memory.+  *+  * @input:+  *   face ::+  *     A handle to the source face.+  *+  *   tag ::+  *     The four-byte tag of the table to load.  Use the value~0 if you want+  *     to access the whole font file.  Otherwise, you can use one of the+  *     definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new+  *     one with @FT_MAKE_TAG.+  *+  *   offset ::+  *     The starting offset in the table (or file if tag == 0).+  *+  * @output:+  *   buffer ::+  *     The target buffer address.  The client must ensure that the memory+  *     array is big enough to hold the data.+  *+  * @inout:+  *   length ::+  *     If the `length' parameter is NULL, then try to load the whole table.+  *     Return an error code if it fails.+  *+  *     Else, if `*length' is~0, exit immediately while returning the+  *     table's (or file) full size in it.+  *+  *     Else the number of bytes to read from the table or file, from the+  *     starting offset.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   If you need to determine the table's length you should first call this+  *   function with `*length' set to~0, as in the following example:+  *+  *     {+  *       FT_ULong  length = 0;+  *+  *+  *       error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );+  *       if ( error ) { ... table does not exist ... }+  *+  *       buffer = malloc( length );+  *       if ( buffer == NULL ) { ... not enough memory ... }+  *+  *       error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );+  *       if ( error ) { ... could not load table ... }+  *     }+  */+  FT_EXPORT( FT_Error )+  FT_Load_Sfnt_Table( FT_Face    face,+                      FT_ULong   tag,+                      FT_Long    offset,+                      FT_Byte*   buffer,+                      FT_ULong*  length );+++ /**************************************************************************+  *+  * @function:+  *   FT_Sfnt_Table_Info+  *+  * @description:+  *   Return information on an SFNT table.+  *+  * @input:+  *   face ::+  *     A handle to the source face.+  *+  *   table_index ::+  *     The index of an SFNT table.  The function returns+  *     FT_Err_Table_Missing for an invalid value.+  *+  * @output:+  *   tag ::+  *     The name tag of the SFNT table.+  *+  *   length ::+  *     The length of the SFNT table.+  *+  * @return:+  *   FreeType error code.  0~means success.+  *+  * @note:+  *   SFNT tables with length zero are treated as missing.+  *+  */+  FT_EXPORT( FT_Error )+  FT_Sfnt_Table_Info( FT_Face    face,+                      FT_UInt    table_index,+                      FT_ULong  *tag,+                      FT_ULong  *length );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_CMap_Language_ID                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return TrueType/sfnt specific cmap language ID.  Definitions of    */+  /*    language ID values are in `freetype/ttnameid.h'.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    charmap ::                                                         */+  /*      The target charmap.                                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The language ID of `charmap'.  If `charmap' doesn't belong to a    */+  /*    TrueType/sfnt face, just return~0 as the default value.            */+  /*                                                                       */+  FT_EXPORT( FT_ULong )+  FT_Get_CMap_Language_ID( FT_CharMap  charmap );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Get_CMap_Format                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Return TrueType/sfnt specific cmap format.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    charmap ::                                                         */+  /*      The target charmap.                                              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The format of `charmap'.  If `charmap' doesn't belong to a         */+  /*    TrueType/sfnt face, return -1.                                     */+  /*                                                                       */+  FT_EXPORT( FT_Long )+  FT_Get_CMap_Format( FT_CharMap  charmap );++  /* */+++FT_END_HEADER++#endif /* __TTTABLES_H__ */+++/* END */
+ include/freetype/tttags.h view
@@ -0,0 +1,107 @@+/***************************************************************************/+/*                                                                         */+/*  tttags.h                                                               */+/*                                                                         */+/*    Tags for TrueType and OpenType tables (specification only).          */+/*                                                                         */+/*  Copyright 1996-2001, 2004, 2005, 2007, 2008 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTAGS_H__+#define __TTAGS_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++#define TTAG_avar  FT_MAKE_TAG( 'a', 'v', 'a', 'r' )+#define TTAG_BASE  FT_MAKE_TAG( 'B', 'A', 'S', 'E' )+#define TTAG_bdat  FT_MAKE_TAG( 'b', 'd', 'a', 't' )+#define TTAG_BDF   FT_MAKE_TAG( 'B', 'D', 'F', ' ' )+#define TTAG_bhed  FT_MAKE_TAG( 'b', 'h', 'e', 'd' )+#define TTAG_bloc  FT_MAKE_TAG( 'b', 'l', 'o', 'c' )+#define TTAG_bsln  FT_MAKE_TAG( 'b', 's', 'l', 'n' )+#define TTAG_CFF   FT_MAKE_TAG( 'C', 'F', 'F', ' ' )+#define TTAG_CID   FT_MAKE_TAG( 'C', 'I', 'D', ' ' )+#define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )+#define TTAG_cvar  FT_MAKE_TAG( 'c', 'v', 'a', 'r' )+#define TTAG_cvt   FT_MAKE_TAG( 'c', 'v', 't', ' ' )+#define TTAG_DSIG  FT_MAKE_TAG( 'D', 'S', 'I', 'G' )+#define TTAG_EBDT  FT_MAKE_TAG( 'E', 'B', 'D', 'T' )+#define TTAG_EBLC  FT_MAKE_TAG( 'E', 'B', 'L', 'C' )+#define TTAG_EBSC  FT_MAKE_TAG( 'E', 'B', 'S', 'C' )+#define TTAG_feat  FT_MAKE_TAG( 'f', 'e', 'a', 't' )+#define TTAG_FOND  FT_MAKE_TAG( 'F', 'O', 'N', 'D' )+#define TTAG_fpgm  FT_MAKE_TAG( 'f', 'p', 'g', 'm' )+#define TTAG_fvar  FT_MAKE_TAG( 'f', 'v', 'a', 'r' )+#define TTAG_gasp  FT_MAKE_TAG( 'g', 'a', 's', 'p' )+#define TTAG_GDEF  FT_MAKE_TAG( 'G', 'D', 'E', 'F' )+#define TTAG_glyf  FT_MAKE_TAG( 'g', 'l', 'y', 'f' )+#define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )+#define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )+#define TTAG_gvar  FT_MAKE_TAG( 'g', 'v', 'a', 'r' )+#define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )+#define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )+#define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )+#define TTAG_hmtx  FT_MAKE_TAG( 'h', 'm', 't', 'x' )+#define TTAG_JSTF  FT_MAKE_TAG( 'J', 'S', 'T', 'F' )+#define TTAG_just  FT_MAKE_TAG( 'j', 'u', 's', 't' )+#define TTAG_kern  FT_MAKE_TAG( 'k', 'e', 'r', 'n' )+#define TTAG_lcar  FT_MAKE_TAG( 'l', 'c', 'a', 'r' )+#define TTAG_loca  FT_MAKE_TAG( 'l', 'o', 'c', 'a' )+#define TTAG_LTSH  FT_MAKE_TAG( 'L', 'T', 'S', 'H' )+#define TTAG_LWFN  FT_MAKE_TAG( 'L', 'W', 'F', 'N' )+#define TTAG_MATH  FT_MAKE_TAG( 'M', 'A', 'T', 'H' )+#define TTAG_maxp  FT_MAKE_TAG( 'm', 'a', 'x', 'p' )+#define TTAG_META  FT_MAKE_TAG( 'M', 'E', 'T', 'A' )+#define TTAG_MMFX  FT_MAKE_TAG( 'M', 'M', 'F', 'X' )+#define TTAG_MMSD  FT_MAKE_TAG( 'M', 'M', 'S', 'D' )+#define TTAG_mort  FT_MAKE_TAG( 'm', 'o', 'r', 't' )+#define TTAG_morx  FT_MAKE_TAG( 'm', 'o', 'r', 'x' )+#define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )+#define TTAG_opbd  FT_MAKE_TAG( 'o', 'p', 'b', 'd' )+#define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )+#define TTAG_OTTO  FT_MAKE_TAG( 'O', 'T', 'T', 'O' )+#define TTAG_PCLT  FT_MAKE_TAG( 'P', 'C', 'L', 'T' )+#define TTAG_POST  FT_MAKE_TAG( 'P', 'O', 'S', 'T' )+#define TTAG_post  FT_MAKE_TAG( 'p', 'o', 's', 't' )+#define TTAG_prep  FT_MAKE_TAG( 'p', 'r', 'e', 'p' )+#define TTAG_prop  FT_MAKE_TAG( 'p', 'r', 'o', 'p' )+#define TTAG_sfnt  FT_MAKE_TAG( 's', 'f', 'n', 't' )+#define TTAG_SING  FT_MAKE_TAG( 'S', 'I', 'N', 'G' )+#define TTAG_trak  FT_MAKE_TAG( 't', 'r', 'a', 'k' )+#define TTAG_true  FT_MAKE_TAG( 't', 'r', 'u', 'e' )+#define TTAG_ttc   FT_MAKE_TAG( 't', 't', 'c', ' ' )+#define TTAG_ttcf  FT_MAKE_TAG( 't', 't', 'c', 'f' )+#define TTAG_TYP1  FT_MAKE_TAG( 'T', 'Y', 'P', '1' )+#define TTAG_typ1  FT_MAKE_TAG( 't', 'y', 'p', '1' )+#define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )+#define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )+#define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )+++FT_END_HEADER++#endif /* __TTAGS_H__ */+++/* END */
+ include/freetype/ttunpat.h view
@@ -0,0 +1,59 @@+/***************************************************************************/+/*                                                                         */+/*  ttunpat.h                                                              */+/*                                                                         */+/*    Definitions for the unpatented TrueType hinting system               */+/*                                                                         */+/*  Copyright 2003, 2006 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  Written by Graham Asher <graham.asher@btinternet.com>                  */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTUNPAT_H__+#define __TTUNPAT_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif+++FT_BEGIN_HEADER+++ /***************************************************************************+  *+  * @constant:+  *   FT_PARAM_TAG_UNPATENTED_HINTING+  *+  * @description:+  *   A constant used as the tag of an @FT_Parameter structure to indicate+  *   that unpatented methods only should be used by the TrueType bytecode+  *   interpreter for a typeface opened by @FT_Open_Face.+  *+  */+#define FT_PARAM_TAG_UNPATENTED_HINTING  FT_MAKE_TAG( 'u', 'n', 'p', 'a' )++ /* */++FT_END_HEADER+++#endif /* __TTUNPAT_H__ */+++/* END */
+ include/ft2build.h view
@@ -0,0 +1,39 @@+/***************************************************************************/+/*                                                                         */+/*  ft2build.h                                                             */+/*                                                                         */+/*    FreeType 2 build and setup macros.                                   */+/*    (Generic version)                                                    */+/*                                                                         */+/*  Copyright 1996-2001, 2006 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file corresponds to the default `ft2build.h' file for            */+  /* FreeType 2.  It uses the `freetype' include root.                     */+  /*                                                                       */+  /* Note that specific platforms might use a different configuration.     */+  /* See builds/unix/ft2unix.h for an example.                             */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FT2_BUILD_GENERIC_H__+#define __FT2_BUILD_GENERIC_H__++#include <freetype/config/ftheader.h>++#endif /* __FT2_BUILD_GENERIC_H__ */+++/* END */
+ objs/ftmodule.h view
@@ -0,0 +1,20 @@+/* This is a generated file. */+FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )+FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )+FT_USE_MODULE( FT_Module_Class, sfnt_module_class )+FT_USE_MODULE( FT_Module_Class, autofit_module_class )+FT_USE_MODULE( FT_Module_Class, pshinter_module_class )+FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )+FT_USE_MODULE( FT_Module_Class, psaux_module_class )+FT_USE_MODULE( FT_Module_Class, psnames_module_class )+/* EOF */
+ src/autofit/afangles.c view
@@ -0,0 +1,292 @@+/***************************************************************************/+/*                                                                         */+/*  afangles.c                                                             */+/*                                                                         */+/*    Routines used to compute vector angles with limited accuracy         */+/*    and very high speed.  It also contains sorting routines (body).      */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "aftypes.h"+++#if 0++  FT_LOCAL_DEF( FT_Int )+  af_corner_is_flat( FT_Pos  x_in,+                     FT_Pos  y_in,+                     FT_Pos  x_out,+                     FT_Pos  y_out )+  {+    FT_Pos  ax = x_in;+    FT_Pos  ay = y_in;++    FT_Pos  d_in, d_out, d_corner;+++    if ( ax < 0 )+      ax = -ax;+    if ( ay < 0 )+      ay = -ay;+    d_in = ax + ay;++    ax = x_out;+    if ( ax < 0 )+      ax = -ax;+    ay = y_out;+    if ( ay < 0 )+      ay = -ay;+    d_out = ax + ay;++    ax = x_out + x_in;+    if ( ax < 0 )+      ax = -ax;+    ay = y_out + y_in;+    if ( ay < 0 )+      ay = -ay;+    d_corner = ax + ay;++    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );+  }+++  FT_LOCAL_DEF( FT_Int )+  af_corner_orientation( FT_Pos  x_in,+                         FT_Pos  y_in,+                         FT_Pos  x_out,+                         FT_Pos  y_out )+  {+    FT_Pos  delta;+++    delta = x_in * y_out - y_in * x_out;++    if ( delta == 0 )+      return 0;+    else+      return 1 - 2 * ( delta < 0 );+  }++#endif+++  /*+   *  We are not using `af_angle_atan' anymore, but we keep the source+   *  code below just in case...+   */+++#if 0+++  /*+   *  The trick here is to realize that we don't need a very accurate angle+   *  approximation.  We are going to use the result of `af_angle_atan' to+   *  only compare the sign of angle differences, or check whether its+   *  magnitude is very small.+   *+   *  The approximation+   *+   *    dy * PI / (|dx|+|dy|)+   *+   *  should be enough, and much faster to compute.+   */+  FT_LOCAL_DEF( AF_Angle )+  af_angle_atan( FT_Fixed  dx,+                 FT_Fixed  dy )+  {+    AF_Angle  angle;+    FT_Fixed  ax = dx;+    FT_Fixed  ay = dy;+++    if ( ax < 0 )+      ax = -ax;+    if ( ay < 0 )+      ay = -ay;++    ax += ay;++    if ( ax == 0 )+      angle = 0;+    else+    {+      angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );+      if ( dx < 0 )+      {+        if ( angle >= 0 )+          angle = AF_ANGLE_PI - angle;+        else+          angle = -AF_ANGLE_PI - angle;+      }+    }++    return angle;+  }+++#elif 0+++  /* the following table has been automatically generated with */+  /* the `mather.py' Python script                             */++#define AF_ATAN_BITS  8++  static const FT_Byte  af_arctan[1L << AF_ATAN_BITS] =+  {+     0,  0,  1,  1,  1,  2,  2,  2,+     3,  3,  3,  3,  4,  4,  4,  5,+     5,  5,  6,  6,  6,  7,  7,  7,+     8,  8,  8,  9,  9,  9, 10, 10,+    10, 10, 11, 11, 11, 12, 12, 12,+    13, 13, 13, 14, 14, 14, 14, 15,+    15, 15, 16, 16, 16, 17, 17, 17,+    18, 18, 18, 18, 19, 19, 19, 20,+    20, 20, 21, 21, 21, 21, 22, 22,+    22, 23, 23, 23, 24, 24, 24, 24,+    25, 25, 25, 26, 26, 26, 26, 27,+    27, 27, 28, 28, 28, 28, 29, 29,+    29, 30, 30, 30, 30, 31, 31, 31,+    31, 32, 32, 32, 33, 33, 33, 33,+    34, 34, 34, 34, 35, 35, 35, 35,+    36, 36, 36, 36, 37, 37, 37, 38,+    38, 38, 38, 39, 39, 39, 39, 40,+    40, 40, 40, 41, 41, 41, 41, 42,+    42, 42, 42, 42, 43, 43, 43, 43,+    44, 44, 44, 44, 45, 45, 45, 45,+    46, 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, 54, 54,+    54, 54, 54, 55, 55, 55, 55, 55,+    56, 56, 56, 56, 56, 57, 57, 57,+    57, 57, 57, 58, 58, 58, 58, 58,+    59, 59, 59, 59, 59, 59, 60, 60,+    60, 60, 60, 61, 61, 61, 61, 61,+    61, 62, 62, 62, 62, 62, 62, 63,+    63, 63, 63, 63, 63, 64, 64, 64+  };+++  FT_LOCAL_DEF( AF_Angle )+  af_angle_atan( FT_Fixed  dx,+                 FT_Fixed  dy )+  {+    AF_Angle  angle;+++    /* check trivial cases */+    if ( dy == 0 )+    {+      angle = 0;+      if ( dx < 0 )+        angle = AF_ANGLE_PI;+      return angle;+    }+    else if ( dx == 0 )+    {+      angle = AF_ANGLE_PI2;+      if ( dy < 0 )+        angle = -AF_ANGLE_PI2;+      return angle;+    }++    angle = 0;+    if ( dx < 0 )+    {+      dx = -dx;+      dy = -dy;+      angle = AF_ANGLE_PI;+    }++    if ( dy < 0 )+    {+      FT_Pos  tmp;+++      tmp = dx;+      dx  = -dy;+      dy  = tmp;+      angle -= AF_ANGLE_PI2;+    }++    if ( dx == 0 && dy == 0 )+      return 0;++    if ( dx == dy )+      angle += AF_ANGLE_PI4;+    else if ( dx > dy )+      angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )];+    else+      angle += AF_ANGLE_PI2 -+               af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )];++    if ( angle > AF_ANGLE_PI )+      angle -= AF_ANGLE_2PI;++    return angle;+  }+++#endif /* 0 */+++  FT_LOCAL_DEF( void )+  af_sort_pos( FT_UInt  count,+               FT_Pos*  table )+  {+    FT_UInt  i, j;+    FT_Pos   swap;+++    for ( i = 1; i < count; i++ )+    {+      for ( j = i; j > 0; j-- )+      {+        if ( table[j] > table[j - 1] )+          break;++        swap         = table[j];+        table[j]     = table[j - 1];+        table[j - 1] = swap;+      }+    }+  }+++  FT_LOCAL_DEF( void )+  af_sort_widths( FT_UInt   count,+                  AF_Width  table )+  {+    FT_UInt      i, j;+    AF_WidthRec  swap;+++    for ( i = 1; i < count; i++ )+    {+      for ( j = i; j > 0; j-- )+      {+        if ( table[j].org > table[j - 1].org )+          break;++        swap         = table[j];+        table[j]     = table[j - 1];+        table[j - 1] = swap;+      }+    }+  }+++/* END */
+ src/autofit/afangles.h view
@@ -0,0 +1,7 @@+/*+ *  afangles.h+ *+ *  This is a dummy file, used to please the build system.  It is never+ *  included by the auto-fitter sources.+ *+ */
+ src/autofit/afcjk.c view
@@ -0,0 +1,1512 @@+/***************************************************************************/+/*                                                                         */+/*  afcjk.c                                                                */+/*                                                                         */+/*    Auto-fitter hinting routines for CJK script (body).                  */+/*                                                                         */+/*  Copyright 2006, 2007, 2008, 2009, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*+   *  The algorithm is based on akito's autohint patch, available here:+   *+   *  http://www.kde.gr.jp/~akito/patch/freetype2/+   *+   */++#include "aftypes.h"+#include "aflatin.h"+++#ifdef AF_CONFIG_OPTION_CJK++#include "afcjk.h"+#include "aferrors.h"+++#ifdef AF_USE_WARPER+#include "afwarp.h"+#endif+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****              C J K   G L O B A L   M E T R I C S              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( FT_Error )+  af_cjk_metrics_init( AF_LatinMetrics  metrics,+                       FT_Face          face )+  {+    FT_CharMap  oldmap = face->charmap;+++    metrics->units_per_em = face->units_per_EM;++    /* TODO are there blues? */++    if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )+      face->charmap = NULL;+    else+    {+      /* latin's version would suffice */+      af_latin_metrics_init_widths( metrics, face, 0x7530 );+      af_latin_metrics_check_digits( metrics, face );+    }++    FT_Set_Charmap( face, oldmap );++    return AF_Err_Ok;+  }+++  static void+  af_cjk_metrics_scale_dim( AF_LatinMetrics  metrics,+                            AF_Scaler        scaler,+                            AF_Dimension     dim )+  {+    AF_LatinAxis  axis;+++    axis = &metrics->axis[dim];++    if ( dim == AF_DIMENSION_HORZ )+    {+      axis->scale = scaler->x_scale;+      axis->delta = scaler->x_delta;+    }+    else+    {+      axis->scale = scaler->y_scale;+      axis->delta = scaler->y_delta;+    }+  }+++  FT_LOCAL_DEF( void )+  af_cjk_metrics_scale( AF_LatinMetrics  metrics,+                        AF_Scaler        scaler )+  {+    metrics->root.scaler = *scaler;++    af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );+    af_cjk_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****              C J K   G L Y P H   A N A L Y S I S              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static FT_Error+  af_cjk_hints_compute_segments( AF_GlyphHints  hints,+                                 AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    FT_Error      error;+    AF_Segment    seg;+++    error = af_latin_hints_compute_segments( hints, dim );+    if ( error )+      return error;++    /* a segment is round if it doesn't have successive */+    /* on-curve points.                                 */+    for ( seg = segments; seg < segment_limit; seg++ )+    {+      AF_Point  pt   = seg->first;+      AF_Point  last = seg->last;+      AF_Flags  f0   = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);+      AF_Flags  f1;+++      seg->flags &= ~AF_EDGE_ROUND;++      for ( ; pt != last; f0 = f1 )+      {+        pt = pt->next;+        f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);++        if ( !f0 && !f1 )+          break;++        if ( pt == last )+          seg->flags |= AF_EDGE_ROUND;+      }+    }++    return AF_Err_Ok;+  }+++  static void+  af_cjk_hints_link_segments( AF_GlyphHints  hints,+                              AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    AF_Direction  major_dir     = axis->major_dir;+    AF_Segment    seg1, seg2;+    FT_Pos        len_threshold;+    FT_Pos        dist_threshold;+++    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );++    dist_threshold = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale+                                                  : hints->y_scale;+    dist_threshold = FT_DivFix( 64 * 3, dist_threshold );++    /* now compare each segment to the others */+    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      /* the fake segments are for metrics hinting only */+      if ( seg1->first == seg1->last )+        continue;++      if ( seg1->dir != major_dir )+        continue;++      for ( seg2 = segments; seg2 < segment_limit; seg2++ )+        if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 )+        {+          FT_Pos  dist = seg2->pos - seg1->pos;+++          if ( dist < 0 )+            continue;++          {+            FT_Pos  min = seg1->min_coord;+            FT_Pos  max = seg1->max_coord;+            FT_Pos  len;+++            if ( min < seg2->min_coord )+              min = seg2->min_coord;++            if ( max > seg2->max_coord )+              max = seg2->max_coord;++            len = max - min;+            if ( len >= len_threshold )+            {+              if ( dist * 8 < seg1->score * 9                        &&+                   ( dist * 8 < seg1->score * 7 || seg1->len < len ) )+              {+                seg1->score = dist;+                seg1->len   = len;+                seg1->link  = seg2;+              }++              if ( dist * 8 < seg2->score * 9                        &&+                   ( dist * 8 < seg2->score * 7 || seg2->len < len ) )+              {+                seg2->score = dist;+                seg2->len   = len;+                seg2->link  = seg1;+              }+            }+          }+        }+    }++    /*+     *  now compute the `serif' segments+     *+     *  In Hanzi, some strokes are wider on one or both of the ends.+     *  We either identify the stems on the ends as serifs or remove+     *  the linkage, depending on the length of the stems.+     *+     */++    {+      AF_Segment  link1, link2;+++      for ( seg1 = segments; seg1 < segment_limit; seg1++ )+      {+        link1 = seg1->link;+        if ( !link1 || link1->link != seg1 || link1->pos <= seg1->pos )+          continue;++        if ( seg1->score >= dist_threshold )+          continue;++        for ( seg2 = segments; seg2 < segment_limit; seg2++ )+        {+          if ( seg2->pos > seg1->pos || seg1 == seg2 )+            continue;++          link2 = seg2->link;+          if ( !link2 || link2->link != seg2 || link2->pos < link1->pos )+            continue;++          if ( seg1->pos == seg2->pos && link1->pos == link2->pos )+            continue;++          if ( seg2->score <= seg1->score || seg1->score * 4 <= seg2->score )+            continue;++          /* seg2 < seg1 < link1 < link2 */++          if ( seg1->len >= seg2->len * 3 )+          {+            AF_Segment  seg;+++            for ( seg = segments; seg < segment_limit; seg++ )+            {+              AF_Segment  link = seg->link;+++              if ( link == seg2 )+              {+                seg->link  = 0;+                seg->serif = link1;+              }+              else if ( link == link2 )+              {+                seg->link  = 0;+                seg->serif = seg1;+              }+            }+          }+          else+          {+            seg1->link = link1->link = 0;++            break;+          }+        }+      }+    }++    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      seg2 = seg1->link;++      if ( seg2 )+      {+        seg2->num_linked++;+        if ( seg2->link != seg1 )+        {+          seg1->link = 0;++          if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 )+            seg1->serif = seg2->link;+          else+            seg2->num_linked--;+        }+      }+    }+  }+++  static FT_Error+  af_cjk_hints_compute_edges( AF_GlyphHints  hints,+                              AF_Dimension   dim )+  {+    AF_AxisHints  axis   = &hints->axis[dim];+    FT_Error      error  = AF_Err_Ok;+    FT_Memory     memory = hints->memory;+    AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];++    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    AF_Segment    seg;++    FT_Fixed      scale;+    FT_Pos        edge_distance_threshold;+++    axis->num_edges = 0;++    scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale+                                         : hints->y_scale;++    /*********************************************************************/+    /*                                                                   */+    /* We begin by generating a sorted table of edges for the current    */+    /* direction.  To do so, we simply scan each segment and try to find */+    /* an edge in our table that corresponds to its position.            */+    /*                                                                   */+    /* If no edge is found, we create and insert a new edge in the       */+    /* sorted table.  Otherwise, we simply add the segment to the edge's */+    /* list which is then processed in the second step to compute the    */+    /* edge's properties.                                                */+    /*                                                                   */+    /* Note that the edges table is sorted along the segment/edge        */+    /* position.                                                         */+    /*                                                                   */+    /*********************************************************************/++    edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,+                                         scale );+    if ( edge_distance_threshold > 64 / 4 )+      edge_distance_threshold = FT_DivFix( 64 / 4, scale );+    else+      edge_distance_threshold = laxis->edge_distance_threshold;++    for ( seg = segments; seg < segment_limit; seg++ )+    {+      AF_Edge  found = 0;+      FT_Pos   best  = 0xFFFFU;+      FT_Int   ee;+++      /* look for an edge corresponding to the segment */+      for ( ee = 0; ee < axis->num_edges; ee++ )+      {+        AF_Edge  edge = axis->edges + ee;+        FT_Pos   dist;+++        if ( edge->dir != seg->dir )+          continue;++        dist = seg->pos - edge->fpos;+        if ( dist < 0 )+          dist = -dist;++        if ( dist < edge_distance_threshold && dist < best )+        {+          AF_Segment  link = seg->link;+++          /* check whether all linked segments of the candidate edge */+          /* can make a single edge.                                 */+          if ( link )+          {+            AF_Segment  seg1 = edge->first;+            AF_Segment  link1;+            FT_Pos      dist2 = 0;+++            do+            {+              link1 = seg1->link;+              if ( link1 )+              {+                dist2 = AF_SEGMENT_DIST( link, link1 );+                if ( dist2 >= edge_distance_threshold )+                  break;+              }++            } while ( ( seg1 = seg1->edge_next ) != edge->first );++            if ( dist2 >= edge_distance_threshold )+              continue;+          }++          best  = dist;+          found = edge;+        }+      }++      if ( !found )+      {+        AF_Edge  edge;+++        /* insert a new edge in the list and */+        /* sort according to the position    */+        error = af_axis_hints_new_edge( axis, seg->pos,+                                        (AF_Direction)seg->dir,+                                        memory, &edge );+        if ( error )+          goto Exit;++        /* add the segment to the new edge's list */+        FT_ZERO( edge );++        edge->first    = seg;+        edge->last     = seg;+        edge->fpos     = seg->pos;+        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );+        seg->edge_next = seg;+        edge->dir      = seg->dir;+      }+      else+      {+        /* if an edge was found, simply add the segment to the edge's */+        /* list                                                       */+        seg->edge_next         = found->first;+        found->last->edge_next = seg;+        found->last            = seg;+      }+    }++    /*********************************************************************/+    /*                                                                   */+    /* Good, we now compute each edge's properties according to segments */+    /* found on its position.  Basically, these are as follows.          */+    /*                                                                   */+    /*  - edge's main direction                                          */+    /*  - stem edge, serif edge or both (which defaults to stem then)    */+    /*  - rounded edge, straight or both (which defaults to straight)    */+    /*  - link for edge                                                  */+    /*                                                                   */+    /*********************************************************************/++    /* first of all, set the `edge' field in each segment -- this is     */+    /* required in order to compute edge links                           */+    /*                                                                   */+    /* Note that removing this loop and setting the `edge' field of each */+    /* segment directly in the code above slows down execution speed for */+    /* some reasons on platforms like the Sun.                           */++    {+      AF_Edge  edges      = axis->edges;+      AF_Edge  edge_limit = edges + axis->num_edges;+      AF_Edge  edge;+++      for ( edge = edges; edge < edge_limit; edge++ )+      {+        seg = edge->first;+        if ( seg )+          do+          {+            seg->edge = edge;+            seg       = seg->edge_next;++          } while ( seg != edge->first );+      }++      /* now compute each edge properties */+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        FT_Int  is_round    = 0;  /* does it contain round segments?    */+        FT_Int  is_straight = 0;  /* does it contain straight segments? */+++        seg = edge->first;++        do+        {+          FT_Bool  is_serif;+++          /* check for roundness of segment */+          if ( seg->flags & AF_EDGE_ROUND )+            is_round++;+          else+            is_straight++;++          /* check for links -- if seg->serif is set, then seg->link must */+          /* be ignored                                                   */+          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );++          if ( seg->link || is_serif )+          {+            AF_Edge     edge2;+            AF_Segment  seg2;+++            edge2 = edge->link;+            seg2  = seg->link;++            if ( is_serif )+            {+              seg2  = seg->serif;+              edge2 = edge->serif;+            }++            if ( edge2 )+            {+              FT_Pos  edge_delta;+              FT_Pos  seg_delta;+++              edge_delta = edge->fpos - edge2->fpos;+              if ( edge_delta < 0 )+                edge_delta = -edge_delta;++              seg_delta = AF_SEGMENT_DIST( seg, seg2 );++              if ( seg_delta < edge_delta )+                edge2 = seg2->edge;+            }+            else+              edge2 = seg2->edge;++            if ( is_serif )+            {+              edge->serif   = edge2;+              edge2->flags |= AF_EDGE_SERIF;+            }+            else+              edge->link  = edge2;+          }++          seg = seg->edge_next;++        } while ( seg != edge->first );++        /* set the round/straight flags */+        edge->flags = AF_EDGE_NORMAL;++        if ( is_round > 0 && is_round >= is_straight )+          edge->flags |= AF_EDGE_ROUND;++        /* get rid of serifs if link is set                 */+        /* XXX: This gets rid of many unpleasant artefacts! */+        /*      Example: the `c' in cour.pfa at size 13     */++        if ( edge->serif && edge->link )+          edge->serif = 0;+      }+    }++  Exit:+    return error;+  }+++  static FT_Error+  af_cjk_hints_detect_features( AF_GlyphHints  hints,+                                AF_Dimension   dim )+  {+    FT_Error  error;+++    error = af_cjk_hints_compute_segments( hints, dim );+    if ( !error )+    {+      af_cjk_hints_link_segments( hints, dim );++      error = af_cjk_hints_compute_edges( hints, dim );+    }+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_cjk_hints_init( AF_GlyphHints    hints,+                     AF_LatinMetrics  metrics )+  {+    FT_Render_Mode  mode;+    FT_UInt32       scaler_flags, other_flags;+++    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );++    /*+     *  correct x_scale and y_scale when needed, since they may have+     *  been modified af_cjk_scale_dim above+     */+    hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;+    hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;+    hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;+    hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;++    /* compute flags depending on render mode, etc. */+    mode = metrics->root.scaler.render_mode;++#ifdef AF_USE_WARPER+    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )+      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;+#endif++    scaler_flags = hints->scaler_flags;+    other_flags  = 0;++    /*+     *  We snap the width of vertical stems for the monochrome and+     *  horizontal LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )+      other_flags |= AF_LATIN_HINTS_HORZ_SNAP;++    /*+     *  We snap the width of horizontal stems for the monochrome and+     *  vertical LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )+      other_flags |= AF_LATIN_HINTS_VERT_SNAP;++    /*+     *  We adjust stems to full pixels only if we don't use the `light' mode.+     */+    if ( mode != FT_RENDER_MODE_LIGHT )+      other_flags |= AF_LATIN_HINTS_STEM_ADJUST;++    if ( mode == FT_RENDER_MODE_MONO )+      other_flags |= AF_LATIN_HINTS_MONO;++    scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE;++    hints->scaler_flags = scaler_flags;+    hints->other_flags  = other_flags;++    return 0;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****          C J K   G L Y P H   G R I D - F I T T I N G          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* snap a given width in scaled coordinates to one of the */+  /* current standard widths                                */++  static FT_Pos+  af_cjk_snap_width( AF_Width  widths,+                     FT_Int    count,+                     FT_Pos    width )+  {+    int     n;+    FT_Pos  best      = 64 + 32 + 2;+    FT_Pos  reference = width;+    FT_Pos  scaled;+++    for ( n = 0; n < count; n++ )+    {+      FT_Pos  w;+      FT_Pos  dist;+++      w = widths[n].cur;+      dist = width - w;+      if ( dist < 0 )+        dist = -dist;+      if ( dist < best )+      {+        best      = dist;+        reference = w;+      }+    }++    scaled = FT_PIX_ROUND( reference );++    if ( width >= reference )+    {+      if ( width < scaled + 48 )+        width = reference;+    }+    else+    {+      if ( width > scaled - 48 )+        width = reference;+    }++    return width;+  }+++  /* compute the snapped width of a given stem */++  static FT_Pos+  af_cjk_compute_stem_width( AF_GlyphHints  hints,+                             AF_Dimension   dim,+                             FT_Pos         width,+                             AF_Edge_Flags  base_flags,+                             AF_Edge_Flags  stem_flags )+  {+    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;+    AF_LatinAxis     axis     = & metrics->axis[dim];+    FT_Pos           dist     = width;+    FT_Int           sign     = 0;+    FT_Int           vertical = ( dim == AF_DIMENSION_VERT );++    FT_UNUSED( base_flags );+    FT_UNUSED( stem_flags );+++    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) )+      return width;++    if ( dist < 0 )+    {+      dist = -width;+      sign = 1;+    }++    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||+         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )+    {+      /* smooth hinting process: very lightly quantize the stem width */++      if ( axis->width_count > 0 )+      {+        if ( FT_ABS( dist - axis->widths[0].cur ) < 40 )+        {+          dist = axis->widths[0].cur;+          if ( dist < 48 )+            dist = 48;++          goto Done_Width;+        }+      }++      if ( dist < 54 )+        dist += ( 54 - dist ) / 2 ;+      else if ( dist < 3 * 64 )+      {+        FT_Pos  delta;+++        delta  = dist & 63;+        dist  &= -64;++        if ( delta < 10 )+          dist += delta;+        else if ( delta < 22 )+          dist += 10;+        else if ( delta < 42 )+          dist += delta;+        else if ( delta < 54 )+          dist += 54;+        else+          dist += delta;+      }+    }+    else+    {+      /* strong hinting process: snap the stem width to integer pixels */++      dist = af_cjk_snap_width( axis->widths, axis->width_count, dist );++      if ( vertical )+      {+        /* in the case of vertical hinting, always round */+        /* the stem heights to integer pixels            */++        if ( dist >= 64 )+          dist = ( dist + 16 ) & ~63;+        else+          dist = 64;+      }+      else+      {+        if ( AF_LATIN_HINTS_DO_MONO( hints ) )+        {+          /* monochrome horizontal hinting: snap widths to integer pixels */+          /* with a different threshold                                   */++          if ( dist < 64 )+            dist = 64;+          else+            dist = ( dist + 32 ) & ~63;+        }+        else+        {+          /* for horizontal anti-aliased hinting, we adopt a more subtle */+          /* approach: we strengthen small stems, round stems whose size */+          /* is between 1 and 2 pixels to an integer, otherwise nothing  */++          if ( dist < 48 )+            dist = ( dist + 64 ) >> 1;++          else if ( dist < 128 )+            dist = ( dist + 22 ) & ~63;+          else+            /* round otherwise to prevent color fringes in LCD mode */+            dist = ( dist + 32 ) & ~63;+        }+      }+    }++  Done_Width:+    if ( sign )+      dist = -dist;++    return dist;+  }+++  /* align one stem edge relative to the previous stem edge */++  static void+  af_cjk_align_linked_edge( AF_GlyphHints  hints,+                            AF_Dimension   dim,+                            AF_Edge        base_edge,+                            AF_Edge        stem_edge )+  {+    FT_Pos  dist = stem_edge->opos - base_edge->opos;++    FT_Pos  fitted_width = af_cjk_compute_stem_width(+                             hints, dim, dist,+                             (AF_Edge_Flags)base_edge->flags,+                             (AF_Edge_Flags)stem_edge->flags );+++    stem_edge->pos = base_edge->pos + fitted_width;+  }+++  static void+  af_cjk_align_serif_edge( AF_GlyphHints  hints,+                           AF_Edge        base,+                           AF_Edge        serif )+  {+    FT_UNUSED( hints );++    serif->pos = base->pos + ( serif->opos - base->opos );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                    E D G E   H I N T I N G                      ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#define AF_LIGHT_MODE_MAX_HORZ_GAP    9+#define AF_LIGHT_MODE_MAX_VERT_GAP   15+#define AF_LIGHT_MODE_MAX_DELTA_ABS  14+++  static FT_Pos+  af_hint_normal_stem( AF_GlyphHints  hints,+                       AF_Edge        edge,+                       AF_Edge        edge2,+                       FT_Pos         anchor,+                       AF_Dimension   dim )+  {+    FT_Pos  org_len, cur_len, org_center;+    FT_Pos  cur_pos1, cur_pos2;+    FT_Pos  d_off1, u_off1, d_off2, u_off2, delta;+    FT_Pos  offset;+    FT_Pos  threshold = 64;+++    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) )+    {+      if ( ( edge->flags  & AF_EDGE_ROUND ) &&+           ( edge2->flags & AF_EDGE_ROUND ) )+      {+        if ( dim == AF_DIMENSION_VERT )+          threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP;+        else+          threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP;+      }+      else+      {+        if ( dim == AF_DIMENSION_VERT )+          threshold = 64 - AF_LIGHT_MODE_MAX_HORZ_GAP / 3;+        else+          threshold = 64 - AF_LIGHT_MODE_MAX_VERT_GAP / 3;+      }+    }++    org_len    = edge2->opos - edge->opos;+    cur_len    = af_cjk_compute_stem_width( hints, dim, org_len,+                                            (AF_Edge_Flags)edge->flags,+                                            (AF_Edge_Flags)edge2->flags );++    org_center = ( edge->opos + edge2->opos ) / 2 + anchor;+    cur_pos1   = org_center - cur_len / 2;+    cur_pos2   = cur_pos1 + cur_len;+    d_off1     = cur_pos1 - FT_PIX_FLOOR( cur_pos1 );+    d_off2     = cur_pos2 - FT_PIX_FLOOR( cur_pos2 );+    u_off1     = 64 - d_off1;+    u_off2     = 64 - d_off2;+    delta      = 0;+++    if ( d_off1 == 0 || d_off2 == 0 )+      goto Exit;++    if ( cur_len <= threshold )+    {+      if ( d_off2 < cur_len )+      {+        if ( u_off1 <= d_off2 )+          delta =  u_off1;+        else+          delta = -d_off2;+      }++      goto Exit;+    }++    if ( threshold < 64 )+    {+      if ( d_off1 >= threshold || u_off1 >= threshold ||+           d_off2 >= threshold || u_off2 >= threshold )+        goto Exit;+    }++    offset = cur_len % 64;++    if ( offset < 32 )+    {+      if ( u_off1 <= offset || d_off2 <= offset )+        goto Exit;+    }+    else+      offset = 64 - threshold;++    d_off1 = threshold - u_off1;+    u_off1 = u_off1    - offset;+    u_off2 = threshold - d_off2;+    d_off2 = d_off2    - offset;++    if ( d_off1 <= u_off1 )+      u_off1 = -d_off1;++    if ( d_off2 <= u_off2 )+      u_off2 = -d_off2;++    if ( FT_ABS( u_off1 ) <= FT_ABS( u_off2 ) )+      delta = u_off1;+    else+      delta = u_off2;++  Exit:++#if 1+    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) )+    {+      if ( delta > AF_LIGHT_MODE_MAX_DELTA_ABS )+        delta = AF_LIGHT_MODE_MAX_DELTA_ABS;+      else if ( delta < -AF_LIGHT_MODE_MAX_DELTA_ABS )+        delta = -AF_LIGHT_MODE_MAX_DELTA_ABS;+    }+#endif++    cur_pos1 += delta;++    if ( edge->opos < edge2->opos )+    {+      edge->pos  = cur_pos1;+      edge2->pos = cur_pos1 + cur_len;+    }+    else+    {+      edge->pos  = cur_pos1 + cur_len;+      edge2->pos = cur_pos1;+    }++    return delta;+  }+++  static void+  af_cjk_hint_edges( AF_GlyphHints  hints,+                     AF_Dimension   dim )+  {+    AF_AxisHints  axis       = &hints->axis[dim];+    AF_Edge       edges      = axis->edges;+    AF_Edge       edge_limit = edges + axis->num_edges;+    FT_PtrDist    n_edges;+    AF_Edge       edge;+    AF_Edge       anchor   = 0;+    FT_Pos        delta    = 0;+    FT_Int        skipped  = 0;+++    /* now we align all stem edges. */+    for ( edge = edges; edge < edge_limit; edge++ )+    {+      AF_Edge  edge2;+++      if ( edge->flags & AF_EDGE_DONE )+        continue;++      /* skip all non-stem edges */+      edge2 = edge->link;+      if ( !edge2 )+      {+        skipped++;+        continue;+      }++      /* now align the stem */++      if ( edge2 < edge )+      {+        af_cjk_align_linked_edge( hints, dim, edge2, edge );+        edge->flags |= AF_EDGE_DONE;+        continue;+      }++      if ( dim != AF_DIMENSION_VERT && !anchor )+      {++#if 0+        if ( fixedpitch )+        {+          AF_Edge     left  = edge;+          AF_Edge     right = edge_limit - 1;+          AF_EdgeRec  left1, left2, right1, right2;+          FT_Pos      target, center1, center2;+          FT_Pos      delta1, delta2, d1, d2;+++          while ( right > left && !right->link )+            right--;++          left1  = *left;+          left2  = *left->link;+          right1 = *right->link;+          right2 = *right;++          delta  = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;+          target = left->opos + ( right->opos - left->opos ) / 2 + delta - 16;++          delta1  = delta;+          delta1 += af_hint_normal_stem( hints, left, left->link,+                                         delta1, 0 );++          if ( left->link != right )+            af_hint_normal_stem( hints, right->link, right, delta1, 0 );++          center1 = left->pos + ( right->pos - left->pos ) / 2;++          if ( center1 >= target )+            delta2 = delta - 32;+          else+            delta2 = delta + 32;++          delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 );++          if ( delta1 != delta2 )+          {+            if ( left->link != right )+              af_hint_normal_stem( hints, &right1, &right2, delta2, 0 );++            center2 = left1.pos + ( right2.pos - left1.pos ) / 2;++            d1 = center1 - target;+            d2 = center2 - target;++            if ( FT_ABS( d2 ) < FT_ABS( d1 ) )+            {+              left->pos       = left1.pos;+              left->link->pos = left2.pos;++              if ( left->link != right )+              {+                right->link->pos = right1.pos;+                right->pos       = right2.pos;+              }++              delta1 = delta2;+            }+          }++          delta               = delta1;+          right->link->flags |= AF_EDGE_DONE;+          right->flags       |= AF_EDGE_DONE;+        }+        else++#endif /* 0 */++          delta = af_hint_normal_stem( hints, edge, edge2, 0,+                                       AF_DIMENSION_HORZ );+      }+      else+        af_hint_normal_stem( hints, edge, edge2, delta, dim );++#if 0+      printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n",+               edge - edges, edge2 - edges,+               ( edge->pos - edge->opos ) / 64.0,+               ( edge2->pos - edge2->opos ) / 64.0 );+#endif++      anchor = edge;+      edge->flags  |= AF_EDGE_DONE;+      edge2->flags |= AF_EDGE_DONE;+    }++    /* make sure that lowercase m's maintain their symmetry */++    /* In general, lowercase m's have six vertical edges if they are sans */+    /* serif, or twelve if they are with serifs.  This implementation is  */+    /* based on that assumption, and seems to work very well with most    */+    /* faces.  However, if for a certain face this assumption is not      */+    /* true, the m is just rendered like before.  In addition, any stem   */+    /* correction will only be applied to symmetrical glyphs (even if the */+    /* glyph is not an m), so the potential for unwanted distortion is    */+    /* relatively low.                                                    */++    /* We don't handle horizontal edges since we can't easily assure that */+    /* the third (lowest) stem aligns with the base line; it might end up */+    /* one pixel higher or lower.                                         */++    n_edges = edge_limit - edges;+    if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )+    {+      AF_Edge  edge1, edge2, edge3;+      FT_Pos   dist1, dist2, span;+++      if ( n_edges == 6 )+      {+        edge1 = edges;+        edge2 = edges + 2;+        edge3 = edges + 4;+      }+      else+      {+        edge1 = edges + 1;+        edge2 = edges + 5;+        edge3 = edges + 9;+      }++      dist1 = edge2->opos - edge1->opos;+      dist2 = edge3->opos - edge2->opos;++      span = dist1 - dist2;+      if ( span < 0 )+        span = -span;++      if ( edge1->link == edge1 + 1 &&+           edge2->link == edge2 + 1 &&+           edge3->link == edge3 + 1 && span < 8 )+      {+        delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );+        edge3->pos -= delta;+        if ( edge3->link )+          edge3->link->pos -= delta;++        /* move the serifs along with the stem */+        if ( n_edges == 12 )+        {+          ( edges + 8 )->pos -= delta;+          ( edges + 11 )->pos -= delta;+        }++        edge3->flags |= AF_EDGE_DONE;+        if ( edge3->link )+          edge3->link->flags |= AF_EDGE_DONE;+      }+    }++    if ( !skipped )+      return;++    /*+     *  now hint the remaining edges (serifs and single) in order+     *  to complete our processing+     */+    for ( edge = edges; edge < edge_limit; edge++ )+    {+      if ( edge->flags & AF_EDGE_DONE )+        continue;++      if ( edge->serif )+      {+        af_cjk_align_serif_edge( hints, edge->serif, edge );+        edge->flags |= AF_EDGE_DONE;+        skipped--;+      }+    }++    if ( !skipped )+      return;++    for ( edge = edges; edge < edge_limit; edge++ )+    {+      AF_Edge  before, after;+++      if ( edge->flags & AF_EDGE_DONE )+        continue;++      before = after = edge;++      while ( --before >= edges )+        if ( before->flags & AF_EDGE_DONE )+          break;++      while ( ++after < edge_limit )+        if ( after->flags & AF_EDGE_DONE )+          break;++      if ( before >= edges || after < edge_limit )+      {+        if ( before < edges )+          af_cjk_align_serif_edge( hints, after, edge );+        else if ( after >= edge_limit )+          af_cjk_align_serif_edge( hints, before, edge );+        else+        {+          if ( after->fpos == before->fpos )+            edge->pos = before->pos;+          else+            edge->pos = before->pos ++                        FT_MulDiv( edge->fpos - before->fpos,+                                   after->pos - before->pos,+                                   after->fpos - before->fpos );+        }+      }+    }+  }+++  static void+  af_cjk_align_edge_points( AF_GlyphHints  hints,+                            AF_Dimension   dim )+  {+    AF_AxisHints  axis       = & hints->axis[dim];+    AF_Edge       edges      = axis->edges;+    AF_Edge       edge_limit = edges + axis->num_edges;+    AF_Edge       edge;+    FT_Bool       snapping;+++    snapping = FT_BOOL( ( dim == AF_DIMENSION_HORZ             &&+                          AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) )  ||+                        ( dim == AF_DIMENSION_VERT             &&+                          AF_LATIN_HINTS_DO_VERT_SNAP( hints ) )  );++    for ( edge = edges; edge < edge_limit; edge++ )+    {+      /* move the points of each segment     */+      /* in each edge to the edge's position */+      AF_Segment  seg = edge->first;+++      if ( snapping )+      {+        do+        {+          AF_Point  point = seg->first;+++          for (;;)+          {+            if ( dim == AF_DIMENSION_HORZ )+            {+              point->x      = edge->pos;+              point->flags |= AF_FLAG_TOUCH_X;+            }+            else+            {+              point->y      = edge->pos;+              point->flags |= AF_FLAG_TOUCH_Y;+            }++            if ( point == seg->last )+              break;++            point = point->next;+          }++          seg = seg->edge_next;++        } while ( seg != edge->first );+      }+      else+      {+        FT_Pos  delta = edge->pos - edge->opos;+++        do+        {+          AF_Point  point = seg->first;+++          for (;;)+          {+            if ( dim == AF_DIMENSION_HORZ )+            {+              point->x     += delta;+              point->flags |= AF_FLAG_TOUCH_X;+            }+            else+            {+              point->y     += delta;+              point->flags |= AF_FLAG_TOUCH_Y;+            }++            if ( point == seg->last )+              break;++            point = point->next;+          }++          seg = seg->edge_next;++        } while ( seg != edge->first );+      }+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  af_cjk_hints_apply( AF_GlyphHints    hints,+                      FT_Outline*      outline,+                      AF_LatinMetrics  metrics )+  {+    FT_Error  error;+    int       dim;++    FT_UNUSED( metrics );+++    error = af_glyph_hints_reload( hints, outline );+    if ( error )+      goto Exit;++    /* analyze glyph outline */+    if ( AF_HINTS_DO_HORIZONTAL( hints ) )+    {+      error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ );+      if ( error )+        goto Exit;+    }++    if ( AF_HINTS_DO_VERTICAL( hints ) )+    {+      error = af_cjk_hints_detect_features( hints, AF_DIMENSION_VERT );+      if ( error )+        goto Exit;+    }++    /* grid-fit the outline */+    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+    {+      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||+           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )+      {++#ifdef AF_USE_WARPER+        if ( dim == AF_DIMENSION_HORZ                                  &&+             metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL )+        {+          AF_WarperRec  warper;+          FT_Fixed      scale;+          FT_Pos        delta;+++          af_warper_compute( &warper, hints, dim, &scale, &delta );+          af_glyph_hints_scale_dim( hints, dim, scale, delta );+          continue;+        }+#endif /* AF_USE_WARPER */++        af_cjk_hint_edges( hints, (AF_Dimension)dim );+        af_cjk_align_edge_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );+      }+    }++#if 0+    af_glyph_hints_dump_points( hints );+    af_glyph_hints_dump_segments( hints );+    af_glyph_hints_dump_edges( hints );+#endif++    af_glyph_hints_save( hints, outline );++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                C J K   S C R I P T   C L A S S                *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  static const AF_Script_UniRangeRec  af_cjk_uniranges[] =+  {+#if 0+    AF_UNIRANGE_REC(  0x0100UL,  0xFFFFUL ),  /* why this? */+#endif+    AF_UNIRANGE_REC(  0x2E80UL,  0x2EFFUL ),  /* CJK Radicals Supplement                 */+    AF_UNIRANGE_REC(  0x2F00UL,  0x2FDFUL ),  /* Kangxi Radicals                         */+    AF_UNIRANGE_REC(  0x3000UL,  0x303FUL ),  /* CJK Symbols and Punctuation             */+    AF_UNIRANGE_REC(  0x3040UL,  0x309FUL ),  /* Hiragana                                */+    AF_UNIRANGE_REC(  0x30A0UL,  0x30FFUL ),  /* Katakana                                */+    AF_UNIRANGE_REC(  0x3100UL,  0x312FUL ),  /* Bopomofo                                */+    AF_UNIRANGE_REC(  0x3130UL,  0x318FUL ),  /* Hangul Compatibility Jamo               */+    AF_UNIRANGE_REC(  0x31A0UL,  0x31BFUL ),  /* Bopomofo Extended                       */+    AF_UNIRANGE_REC(  0x31C0UL,  0x31EFUL ),  /* CJK Strokes                             */+    AF_UNIRANGE_REC(  0x31F0UL,  0x31FFUL ),  /* Katakana Phonetic Extensions            */+    AF_UNIRANGE_REC(  0x3200UL,  0x32FFUL ),  /* Enclosed CJK Letters and Months         */+    AF_UNIRANGE_REC(  0x3300UL,  0x33FFUL ),  /* CJK Compatibility                       */+    AF_UNIRANGE_REC(  0x3400UL,  0x4DBFUL ),  /* CJK Unified Ideographs Extension A      */+    AF_UNIRANGE_REC(  0x4DC0UL,  0x4DFFUL ),  /* Yijing Hexagram Symbols                 */+    AF_UNIRANGE_REC(  0x4E00UL,  0x9FFFUL ),  /* CJK Unified Ideographs                  */+    AF_UNIRANGE_REC(  0xF900UL,  0xFAFFUL ),  /* CJK Compatibility Ideographs            */+    AF_UNIRANGE_REC(  0xFE30UL,  0xFE4FUL ),  /* CJK Compatibility Forms                 */+    AF_UNIRANGE_REC(  0xFF00UL,  0xFFEFUL ),  /* Halfwidth and Fullwidth Forms           */+    AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ),  /* CJK Unified Ideographs Extension B      */+    AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ),  /* CJK Compatibility Ideographs Supplement */+    AF_UNIRANGE_REC(       0UL,       0UL )+  };+++  AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class,+    AF_SCRIPT_CJK,+    af_cjk_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) af_cjk_metrics_init,+    (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   af_cjk_hints_init,+    (AF_Script_ApplyHintsFunc)  af_cjk_hints_apply+  )++#else /* !AF_CONFIG_OPTION_CJK */++  static const AF_Script_UniRangeRec  af_cjk_uniranges[] =+  {+    AF_UNIRANGE_REC( 0UL, 0UL )+  };+++  AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class,+    AF_SCRIPT_CJK,+    af_cjk_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) NULL,+    (AF_Script_ScaleMetricsFunc)NULL,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   NULL,+    (AF_Script_ApplyHintsFunc)  NULL+  )++#endif /* !AF_CONFIG_OPTION_CJK */+++/* END */
+ src/autofit/afcjk.h view
@@ -0,0 +1,57 @@+/***************************************************************************/+/*                                                                         */+/*  afcjk.h                                                                */+/*                                                                         */+/*    Auto-fitter hinting routines for CJK script (specification).         */+/*                                                                         */+/*  Copyright 2006, 2007 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFCJK_H__+#define __AFCJK_H__++#include "afhints.h"+++FT_BEGIN_HEADER+++  /* the CJK-specific script class */++  AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class)+++  FT_LOCAL( FT_Error )+  af_cjk_metrics_init( AF_LatinMetrics  metrics,+                       FT_Face          face );++  FT_LOCAL( void )+  af_cjk_metrics_scale( AF_LatinMetrics  metrics,+                        AF_Scaler        scaler );++  FT_LOCAL( FT_Error )+  af_cjk_hints_init( AF_GlyphHints    hints,+                     AF_LatinMetrics  metrics );++  FT_LOCAL( FT_Error )+  af_cjk_hints_apply( AF_GlyphHints    hints,+                      FT_Outline*      outline,+                      AF_LatinMetrics  metrics );++/* */++FT_END_HEADER++#endif /* __AFCJK_H__ */+++/* END */
+ src/autofit/afdummy.c view
@@ -0,0 +1,60 @@+/***************************************************************************/+/*                                                                         */+/*  afdummy.c                                                              */+/*                                                                         */+/*    Auto-fitter dummy routines to be used if no hinting should be        */+/*    performed (body).                                                    */+/*                                                                         */+/*  Copyright 2003, 2004, 2005 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afdummy.h"+#include "afhints.h"+++  static FT_Error+  af_dummy_hints_init( AF_GlyphHints     hints,+                       AF_ScriptMetrics  metrics )+  {+    af_glyph_hints_rescale( hints,+                            metrics );+    return 0;+  }+++  static FT_Error+  af_dummy_hints_apply( AF_GlyphHints  hints,+                        FT_Outline*    outline )+  {+    FT_UNUSED( hints );+    FT_UNUSED( outline );++    return 0;+  }+++  AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class,+    AF_SCRIPT_NONE,+    NULL,++    sizeof( AF_ScriptMetricsRec ),++    (AF_Script_InitMetricsFunc) NULL,+    (AF_Script_ScaleMetricsFunc)NULL,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   af_dummy_hints_init,+    (AF_Script_ApplyHintsFunc)  af_dummy_hints_apply+  )+++/* END */
+ src/autofit/afdummy.h view
@@ -0,0 +1,42 @@+/***************************************************************************/+/*                                                                         */+/*  afdummy.h                                                              */+/*                                                                         */+/*    Auto-fitter dummy routines to be used if no hinting should be        */+/*    performed (specification).                                           */+/*                                                                         */+/*  Copyright 2003, 2004, 2005 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFDUMMY_H__+#define __AFDUMMY_H__++#include "aftypes.h"+++FT_BEGIN_HEADER++ /*  A dummy script metrics class used when no hinting should+  *  be performed.  This is the default for non-latin glyphs!+  */++  AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class)++/* */++FT_END_HEADER+++#endif /* __AFDUMMY_H__ */+++/* END */
+ src/autofit/aferrors.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  aferrors.h                                                             */+/*                                                                         */+/*    Autofitter error codes (specification only).                         */+/*                                                                         */+/*  Copyright 2005 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the Autofitter error enumeration          */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __AFERRORS_H__+#define __AFERRORS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  AF_Err_+#define FT_ERR_BASE    FT_Mod_Err_Autofit++#include FT_ERRORS_H++#endif /* __AFERRORS_H__ */++/* END */
+ src/autofit/afglobal.c view
@@ -0,0 +1,323 @@+/***************************************************************************/+/*                                                                         */+/*  afglobal.c                                                             */+/*                                                                         */+/*    Auto-fitter routines to compute global hinting values (body).        */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by            */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afglobal.h"+#include "afdummy.h"+#include "aflatin.h"+#include "afcjk.h"+#include "afindic.h"+#include "afpic.h"++#include "aferrors.h"++#ifdef FT_OPTION_AUTOFIT2+#include "aflatin2.h"+#endif++#ifndef FT_CONFIG_OPTION_PIC++/* when updating this table, don't forget to update +  AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */++  /* populate this list when you add new scripts */+  static AF_ScriptClass const  af_script_classes[] =+  {+    &af_dummy_script_class,+#ifdef FT_OPTION_AUTOFIT2+    &af_latin2_script_class,+#endif+    &af_latin_script_class,+    &af_cjk_script_class,+    &af_indic_script_class, +    NULL  /* do not remove */+  };++#endif /* FT_CONFIG_OPTION_PIC */++  /* index of default script in `af_script_classes' */+#define AF_SCRIPT_LIST_DEFAULT  2+  /* a bit mask indicating an uncovered glyph       */+#define AF_SCRIPT_LIST_NONE     0x7F+  /* if this flag is set, we have an ASCII digit    */+#define AF_DIGIT                0x80+++  /*+   *  Note that glyph_scripts[] is used to map each glyph into+   *  an index into the `af_script_classes' array.+   *+   */+  typedef struct  AF_FaceGlobalsRec_+  {+    FT_Face           face;+    FT_Long           glyph_count;    /* same as face->num_glyphs */+    FT_Byte*          glyph_scripts;++    AF_ScriptMetrics  metrics[AF_SCRIPT_MAX];++  } AF_FaceGlobalsRec;+++  /* Compute the script index of each glyph within a given face. */++  static FT_Error+  af_face_globals_compute_script_coverage( AF_FaceGlobals  globals )+  {+    FT_Error    error       = AF_Err_Ok;+    FT_Face     face        = globals->face;+    FT_CharMap  old_charmap = face->charmap;+    FT_Byte*    gscripts    = globals->glyph_scripts;+    FT_UInt     ss, i;+++    /* the value 255 means `uncovered glyph' */+    FT_MEM_SET( globals->glyph_scripts,+                AF_SCRIPT_LIST_NONE,+                globals->glyph_count );++    error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );+    if ( error )+    {+     /*+      *  Ignore this error; we simply use the default script.+      *  XXX: Shouldn't we rather disable hinting?+      */+      error = AF_Err_Ok;+      goto Exit;+    }++    /* scan each script in a Unicode charmap */+    for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ )+    {+      AF_ScriptClass      clazz = AF_SCRIPT_CLASSES_GET[ss];+      AF_Script_UniRange  range;+++      if ( clazz->script_uni_ranges == NULL )+        continue;++      /*+       *  Scan all unicode points in the range and set the corresponding+       *  glyph script index.+       */+      for ( range = clazz->script_uni_ranges; range->first != 0; range++ )+      {+        FT_ULong  charcode = range->first;+        FT_UInt   gindex;+++        gindex = FT_Get_Char_Index( face, charcode );++        if ( gindex != 0                             &&+             gindex < (FT_ULong)globals->glyph_count &&+             gscripts[gindex] == AF_SCRIPT_LIST_NONE )+        {+          gscripts[gindex] = (FT_Byte)ss;+        }++        for (;;)+        {+          charcode = FT_Get_Next_Char( face, charcode, &gindex );++          if ( gindex == 0 || charcode > range->last )+            break;++          if ( gindex < (FT_ULong)globals->glyph_count &&+               gscripts[gindex] == AF_SCRIPT_LIST_NONE )+          {+            gscripts[gindex] = (FT_Byte)ss;+          }+        }+      }+    }++    /* mark ASCII digits */+    for ( i = 0x30; i <= 0x39; i++ )+    {+      FT_UInt  gindex = FT_Get_Char_Index( face, i );+++      if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count )+        gscripts[gindex] |= AF_DIGIT;+    }++  Exit:+    /*+     *  By default, all uncovered glyphs are set to the latin script.+     *  XXX: Shouldn't we disable hinting or do something similar?+     */+    {+      FT_Long  nn;+++      for ( nn = 0; nn < globals->glyph_count; nn++ )+      {+        if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_LIST_NONE )+        {+          gscripts[nn] &= ~AF_SCRIPT_LIST_NONE;+          gscripts[nn] |= AF_SCRIPT_LIST_DEFAULT;+        }+      }+    }++    FT_Set_Charmap( face, old_charmap );+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_face_globals_new( FT_Face          face,+                       AF_FaceGlobals  *aglobals )+  {+    FT_Error        error;+    FT_Memory       memory;+    AF_FaceGlobals  globals = NULL;+++    memory = face->memory;++    if ( !FT_ALLOC( globals, sizeof ( *globals ) ++                             face->num_glyphs * sizeof ( FT_Byte ) ) )+    {+      globals->face          = face;+      globals->glyph_count   = face->num_glyphs;+      globals->glyph_scripts = (FT_Byte*)( globals + 1 );++      error = af_face_globals_compute_script_coverage( globals );+      if ( error )+      {+        af_face_globals_free( globals );+        globals = NULL;+      }+    }++    *aglobals = globals;+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_face_globals_free( AF_FaceGlobals  globals )+  {+    if ( globals )+    {+      FT_Memory  memory = globals->face->memory;+      FT_UInt    nn;+++      for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ )+      {+        if ( globals->metrics[nn] )+        {+          AF_ScriptClass  clazz = AF_SCRIPT_CLASSES_GET[nn];+++          FT_ASSERT( globals->metrics[nn]->clazz == clazz );++          if ( clazz->script_metrics_done )+            clazz->script_metrics_done( globals->metrics[nn] );++          FT_FREE( globals->metrics[nn] );+        }+      }++      globals->glyph_count   = 0;+      globals->glyph_scripts = NULL;  /* no need to free this one! */+      globals->face          = NULL;++      FT_FREE( globals );+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  af_face_globals_get_metrics( AF_FaceGlobals     globals,+                               FT_UInt            gindex,+                               FT_UInt            options,+                               AF_ScriptMetrics  *ametrics )+  {+    AF_ScriptMetrics  metrics = NULL;+    FT_UInt           gidx;+    AF_ScriptClass    clazz;+    FT_UInt           script     = options & 15;+    const FT_Offset   script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) /+                                     sizeof ( AF_SCRIPT_CLASSES_GET[0] );+    FT_Error          error      = AF_Err_Ok;+++    if ( gindex >= (FT_ULong)globals->glyph_count )+    {+      error = AF_Err_Invalid_Argument;+      goto Exit;+    }++    gidx = script;+    if ( gidx == 0 || gidx + 1 >= script_max )+      gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE;++    clazz = AF_SCRIPT_CLASSES_GET[gidx];+    if ( script == 0 )+      script = clazz->script;++    metrics = globals->metrics[clazz->script];+    if ( metrics == NULL )+    {+      /* create the global metrics object when needed */+      FT_Memory  memory = globals->face->memory;+++      if ( FT_ALLOC( metrics, clazz->script_metrics_size ) )+        goto Exit;++      metrics->clazz = clazz;++      if ( clazz->script_metrics_init )+      {+        error = clazz->script_metrics_init( metrics, globals->face );+        if ( error )+        {+          if ( clazz->script_metrics_done )+            clazz->script_metrics_done( metrics );++          FT_FREE( metrics );+          goto Exit;+        }+      }++      globals->metrics[clazz->script] = metrics;+    }++  Exit:+    *ametrics = metrics;++    return error;+  }+++  FT_LOCAL_DEF( FT_Bool )+  af_face_globals_is_digit( AF_FaceGlobals  globals,+                            FT_UInt         gindex )+  {+    if ( gindex < (FT_ULong)globals->glyph_count )+      return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT );++    return (FT_Bool)0;+  }+++/* END */
+ src/autofit/afglobal.h view
@@ -0,0 +1,71 @@+/***************************************************************************/+/*                                                                         */+/*  afglobal.h                                                             */+/*                                                                         */+/*    Auto-fitter routines to compute global hinting values                */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2007, 2009 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AF_GLOBAL_H__+#define __AF_GLOBAL_H__+++#include "aftypes.h"+++FT_BEGIN_HEADER+++  /************************************************************************/+  /************************************************************************/+  /*****                                                              *****/+  /*****                  F A C E   G L O B A L S                     *****/+  /*****                                                              *****/+  /************************************************************************/+  /************************************************************************/+++  /*+   *  model the global hints data for a given face, decomposed into+   *  script-specific items+   */+  typedef struct AF_FaceGlobalsRec_*   AF_FaceGlobals;+++  FT_LOCAL( FT_Error )+  af_face_globals_new( FT_Face          face,+                       AF_FaceGlobals  *aglobals );++  FT_LOCAL( FT_Error )+  af_face_globals_get_metrics( AF_FaceGlobals     globals,+                               FT_UInt            gindex,+                               FT_UInt            options,+                               AF_ScriptMetrics  *ametrics );++  FT_LOCAL( void )+  af_face_globals_free( AF_FaceGlobals  globals );++  FT_LOCAL_DEF( FT_Bool )+  af_face_globals_is_digit( AF_FaceGlobals  globals,+                            FT_UInt         gindex );++  /* */+++FT_END_HEADER++#endif /* __AF_GLOBALS_H__ */+++/* END */
+ src/autofit/afhints.c view
@@ -0,0 +1,1142 @@+/***************************************************************************/+/*                                                                         */+/*  afhints.c                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines (body).                                 */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afhints.h"+#include "aferrors.h"+#include FT_INTERNAL_CALC_H+++  FT_LOCAL_DEF( FT_Error )+  af_axis_hints_new_segment( AF_AxisHints  axis,+                             FT_Memory     memory,+                             AF_Segment   *asegment )+  {+    FT_Error    error   = AF_Err_Ok;+    AF_Segment  segment = NULL;+++    if ( axis->num_segments >= axis->max_segments )+    {+      FT_Int  old_max = axis->max_segments;+      FT_Int  new_max = old_max;+      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );+++      if ( old_max >= big_max )+      {+        error = AF_Err_Out_Of_Memory;+        goto Exit;+      }++      new_max += ( new_max >> 2 ) + 4;+      if ( new_max < old_max || new_max > big_max )+        new_max = big_max;++      if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )+        goto Exit;++      axis->max_segments = new_max;+    }++    segment = axis->segments + axis->num_segments++;++  Exit:+    *asegment = segment;+    return error;+  }+++  FT_LOCAL( FT_Error )+  af_axis_hints_new_edge( AF_AxisHints  axis,+                          FT_Int        fpos,+                          AF_Direction  dir,+                          FT_Memory     memory,+                          AF_Edge      *aedge )+  {+    FT_Error  error = AF_Err_Ok;+    AF_Edge   edge  = NULL;+    AF_Edge   edges;+++    if ( axis->num_edges >= axis->max_edges )+    {+      FT_Int  old_max = axis->max_edges;+      FT_Int  new_max = old_max;+      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );+++      if ( old_max >= big_max )+      {+        error = AF_Err_Out_Of_Memory;+        goto Exit;+      }++      new_max += ( new_max >> 2 ) + 4;+      if ( new_max < old_max || new_max > big_max )+        new_max = big_max;++      if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )+        goto Exit;++      axis->max_edges = new_max;+    }++    edges = axis->edges;+    edge  = edges + axis->num_edges;++    while ( edge > edges )+    {+      if ( edge[-1].fpos < fpos )+        break;++      /* we want the edge with same position and minor direction */+      /* to appear before those in the major one in the list     */+      if ( edge[-1].fpos == fpos && dir == axis->major_dir )+        break;++      edge[0] = edge[-1];+      edge--;+    }++    axis->num_edges++;++    FT_ZERO( edge );+    edge->fpos = (FT_Short)fpos;+    edge->dir  = (FT_Char)dir;++  Exit:+    *aedge = edge;+    return error;+  }+++#ifdef AF_DEBUG++#include FT_CONFIG_STANDARD_LIBRARY_H++  static const char*+  af_dir_str( AF_Direction  dir )+  {+    const char*  result;+++    switch ( dir )+    {+    case AF_DIR_UP:+      result = "up";+      break;+    case AF_DIR_DOWN:+      result = "down";+      break;+    case AF_DIR_LEFT:+      result = "left";+      break;+    case AF_DIR_RIGHT:+      result = "right";+      break;+    default:+      result = "none";+    }++    return result;+  }+++#define AF_INDEX_NUM( ptr, base )  ( (ptr) ? ( (ptr) - (base) ) : -1 )+++  void+  af_glyph_hints_dump_points( AF_GlyphHints  hints )+  {+    AF_Point  points = hints->points;+    AF_Point  limit  = points + hints->num_points;+    AF_Point  point;+++    printf( "Table of points:\n" );+    printf(   "  [ index |  xorg |  yorg |  xscale |  yscale "+              "|  xfit  |  yfit  |  flags ]\n" );++    for ( point = points; point < limit; point++ )+    {+      printf( "  [ %5d | %5d | %5d | %-5.2f | %-5.2f "+              "| %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",+              point - points,+              point->fx,+              point->fy,+              point->ox/64.0,+              point->oy/64.0,+              point->x/64.0,+              point->y/64.0,+              ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',+              ( point->flags & AF_FLAG_INFLECTION )         ? 'i' : ' ',+              ( point->flags & AF_FLAG_EXTREMA_X )          ? '<' : ' ',+              ( point->flags & AF_FLAG_EXTREMA_Y )          ? 'v' : ' ',+              ( point->flags & AF_FLAG_ROUND_X )            ? '(' : ' ',+              ( point->flags & AF_FLAG_ROUND_Y )            ? 'u' : ' ');+    }+    printf( "\n" );+  }+++  static const char*+  af_edge_flags_to_string( AF_Edge_Flags  flags )+  {+    static char  temp[32];+    int          pos = 0;+++    if ( flags & AF_EDGE_ROUND )+    {+      ft_memcpy( temp + pos, "round", 5 );+      pos += 5;+    }+    if ( flags & AF_EDGE_SERIF )+    {+      if ( pos > 0 )+        temp[pos++] = ' ';+      ft_memcpy( temp + pos, "serif", 5 );+      pos += 5;+    }+    if ( pos == 0 )+      return "normal";++    temp[pos] = 0;++    return temp;+  }+++  /* A function to dump the array of linked segments. */+  void+  af_glyph_hints_dump_segments( AF_GlyphHints  hints )+  {+    FT_Int  dimension;+++    for ( dimension = 1; dimension >= 0; dimension-- )+    {+      AF_AxisHints  axis     = &hints->axis[dimension];+      AF_Segment    segments = axis->segments;+      AF_Segment    limit    = segments + axis->num_segments;+      AF_Segment    seg;+++      printf ( "Table of %s segments:\n",+               dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );+      printf ( "  [ index |  pos  |  dir  | link | serif |"+               " height  | extra | flags    ]\n" );++      for ( seg = segments; seg < limit; seg++ )+      {+        printf ( "  [ %5d | %5.2g | %5s | %4d | %5d | %5d | %5d | %s ]\n",+                 seg - segments,+                 dimension == AF_DIMENSION_HORZ ? (int)seg->first->ox / 64.0+                                                : (int)seg->first->oy / 64.0,+                 af_dir_str( (AF_Direction)seg->dir ),+                 AF_INDEX_NUM( seg->link, segments ),+                 AF_INDEX_NUM( seg->serif, segments ),+                 seg->height,+                 seg->height - ( seg->max_coord - seg->min_coord ),+                 af_edge_flags_to_string( seg->flags ) );+      }+      printf( "\n" );+    }+  }+++  void+  af_glyph_hints_dump_edges( AF_GlyphHints  hints )+  {+    FT_Int  dimension;+++    for ( dimension = 1; dimension >= 0; dimension-- )+    {+      AF_AxisHints  axis  = &hints->axis[dimension];+      AF_Edge       edges = axis->edges;+      AF_Edge       limit = edges + axis->num_edges;+      AF_Edge       edge;+++      /*+       *  note: AF_DIMENSION_HORZ corresponds to _vertical_ edges+       *        since they have constant a X coordinate.+       */+      printf ( "Table of %s edges:\n",+               dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );+      printf ( "  [ index |  pos  |  dir  | link |"+               " serif | blue | opos  |  pos  | flags   ]\n" );++      for ( edge = edges; edge < limit; edge++ )+      {+        printf ( "  [ %5d | %5.2g | %5s | %4d |"+                 " %5d |   %c  | %5.2f | %5.2f | %s ]\n",+                 edge - edges,+                 (int)edge->opos / 64.0,+                 af_dir_str( (AF_Direction)edge->dir ),+                 AF_INDEX_NUM( edge->link, edges ),+                 AF_INDEX_NUM( edge->serif, edges ),+                 edge->blue_edge ? 'y' : 'n',+                 edge->opos / 64.0,+                 edge->pos / 64.0,+                 af_edge_flags_to_string( edge->flags ) );+      }+      printf( "\n" );+    }+  }++#else /* !AF_DEBUG */++  /* these empty stubs are only used to link the `ftgrid' test program */+  /* when debugging is disabled                                        */++  void+  af_glyph_hints_dump_points( AF_GlyphHints  hints )+  {+    FT_UNUSED( hints );+  }+++  void+  af_glyph_hints_dump_segments( AF_GlyphHints  hints )+  {+    FT_UNUSED( hints );+  }+++  void+  af_glyph_hints_dump_edges( AF_GlyphHints  hints )+  {+    FT_UNUSED( hints );+  }++#endif /* !AF_DEBUG */+++  /* compute the direction value of a given vector */+  FT_LOCAL_DEF( AF_Direction )+  af_direction_compute( FT_Pos  dx,+                        FT_Pos  dy )+  {+    FT_Pos        ll, ss;  /* long and short arm lengths */+    AF_Direction  dir;     /* candidate direction        */+++    if ( dy >= dx )+    {+      if ( dy >= -dx )+      {+        dir = AF_DIR_UP;+        ll  = dy;+        ss  = dx;+      }+      else+      {+        dir = AF_DIR_LEFT;+        ll  = -dx;+        ss  = dy;+      }+    }+    else /* dy < dx */+    {+      if ( dy >= -dx )+      {+        dir = AF_DIR_RIGHT;+        ll  = dx;+        ss  = dy;+      }+      else+      {+        dir = AF_DIR_DOWN;+        ll  = dy;+        ss  = dx;+      }+    }++    ss *= 14;+    if ( FT_ABS( ll ) <= FT_ABS( ss ) )+      dir = AF_DIR_NONE;++    return dir;+  }+++  FT_LOCAL_DEF( void )+  af_glyph_hints_init( AF_GlyphHints  hints,+                       FT_Memory      memory )+  {+    FT_ZERO( hints );+    hints->memory = memory;+  }+++  FT_LOCAL_DEF( void )+  af_glyph_hints_done( AF_GlyphHints  hints )+  {+    if ( hints && hints->memory )+    {+      FT_Memory  memory = hints->memory;+      int        dim;+++      /*+       *  note that we don't need to free the segment and edge+       *  buffers, since they are really within the hints->points array+       */+      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+      {+        AF_AxisHints  axis = &hints->axis[dim];+++        axis->num_segments = 0;+        axis->max_segments = 0;+        FT_FREE( axis->segments );++        axis->num_edges    = 0;+        axis->max_edges    = 0;+        FT_FREE( axis->edges );+      }++      FT_FREE( hints->contours );+      hints->max_contours = 0;+      hints->num_contours = 0;++      FT_FREE( hints->points );+      hints->num_points = 0;+      hints->max_points = 0;++      hints->memory = NULL;+    }+  }+++  FT_LOCAL_DEF( void )+  af_glyph_hints_rescale( AF_GlyphHints     hints,+                          AF_ScriptMetrics  metrics )+  {+    hints->metrics      = metrics;+    hints->scaler_flags = metrics->scaler.flags;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_glyph_hints_reload( AF_GlyphHints  hints,+                         FT_Outline*    outline )+  {+    FT_Error   error   = AF_Err_Ok;+    AF_Point   points;+    FT_UInt    old_max, new_max;+    FT_Fixed   x_scale = hints->x_scale;+    FT_Fixed   y_scale = hints->y_scale;+    FT_Pos     x_delta = hints->x_delta;+    FT_Pos     y_delta = hints->y_delta;+    FT_Memory  memory  = hints->memory;+++    hints->num_points   = 0;+    hints->num_contours = 0;++    hints->axis[0].num_segments = 0;+    hints->axis[0].num_edges    = 0;+    hints->axis[1].num_segments = 0;+    hints->axis[1].num_edges    = 0;++    /* first of all, reallocate the contours array when necessary */+    new_max = (FT_UInt)outline->n_contours;+    old_max = hints->max_contours;+    if ( new_max > old_max )+    {+      new_max = ( new_max + 3 ) & ~3;++      if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )+        goto Exit;++      hints->max_contours = new_max;+    }++    /*+     *  then reallocate the points arrays if necessary --+     *  note that we reserve two additional point positions, used to+     *  hint metrics appropriately+     */+    new_max = (FT_UInt)( outline->n_points + 2 );+    old_max = hints->max_points;+    if ( new_max > old_max )+    {+      new_max = ( new_max + 2 + 7 ) & ~7;++      if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )+        goto Exit;++      hints->max_points = new_max;+    }++    hints->num_points   = outline->n_points;+    hints->num_contours = outline->n_contours;++    /* We can't rely on the value of `FT_Outline.flags' to know the fill   */+    /* direction used for a glyph, given that some fonts are broken (e.g., */+    /* the Arphic ones).  We thus recompute it each time we need to.       */+    /*                                                                     */+    hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;+    hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;++    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )+    {+      hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;+      hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;+    }++    hints->x_scale = x_scale;+    hints->y_scale = y_scale;+    hints->x_delta = x_delta;+    hints->y_delta = y_delta;++    hints->xmin_delta = 0;+    hints->xmax_delta = 0;++    points = hints->points;+    if ( hints->num_points == 0 )+      goto Exit;++    {+      AF_Point  point;+      AF_Point  point_limit = points + hints->num_points;+++      /* compute coordinates & Bezier flags, next and prev */+      {+        FT_Vector*  vec           = outline->points;+        char*       tag           = outline->tags;+        AF_Point    end           = points + outline->contours[0];+        AF_Point    prev          = end;+        FT_Int      contour_index = 0;+++        for ( point = points; point < point_limit; point++, vec++, tag++ )+        {+          point->fx = (FT_Short)vec->x;+          point->fy = (FT_Short)vec->y;+          point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;+          point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;++          switch ( FT_CURVE_TAG( *tag ) )+          {+          case FT_CURVE_TAG_CONIC:+            point->flags = AF_FLAG_CONIC;+            break;+          case FT_CURVE_TAG_CUBIC:+            point->flags = AF_FLAG_CUBIC;+            break;+          default:+            point->flags = 0;+          }++          point->prev = prev;+          prev->next  = point;+          prev        = point;++          if ( point == end )+          {+            if ( ++contour_index < outline->n_contours )+            {+              end  = points + outline->contours[contour_index];+              prev = end;+            }+          }+        }+      }++      /* set-up the contours array */+      {+        AF_Point*  contour       = hints->contours;+        AF_Point*  contour_limit = contour + hints->num_contours;+        short*     end           = outline->contours;+        short      idx           = 0;+++        for ( ; contour < contour_limit; contour++, end++ )+        {+          contour[0] = points + idx;+          idx        = (short)( end[0] + 1 );+        }+      }++      /* compute directions of in & out vectors */+      {+        AF_Point      first  = points;+        AF_Point      prev   = NULL;+        FT_Pos        in_x   = 0;+        FT_Pos        in_y   = 0;+        AF_Direction  in_dir = AF_DIR_NONE;+++        for ( point = points; point < point_limit; point++ )+        {+          AF_Point  next;+          FT_Pos    out_x, out_y;+++          if ( point == first )+          {+            prev   = first->prev;+            in_x   = first->fx - prev->fx;+            in_y   = first->fy - prev->fy;+            in_dir = af_direction_compute( in_x, in_y );+            first  = prev + 1;+          }++          point->in_dir = (FT_Char)in_dir;++          next  = point->next;+          out_x = next->fx - point->fx;+          out_y = next->fy - point->fy;++          in_dir         = af_direction_compute( out_x, out_y );+          point->out_dir = (FT_Char)in_dir;++          if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )+          {+          Is_Weak_Point:+            point->flags |= AF_FLAG_WEAK_INTERPOLATION;+          }+          else if ( point->out_dir == point->in_dir )+          {+            if ( point->out_dir != AF_DIR_NONE )+              goto Is_Weak_Point;++            if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) )+              goto Is_Weak_Point;+          }+          else if ( point->in_dir == -point->out_dir )+            goto Is_Weak_Point;++          in_x = out_x;+          in_y = out_y;+          prev = point;+        }+      }+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_glyph_hints_save( AF_GlyphHints  hints,+                       FT_Outline*    outline )+  {+    AF_Point    point = hints->points;+    AF_Point    limit = point + hints->num_points;+    FT_Vector*  vec   = outline->points;+    char*       tag   = outline->tags;+++    for ( ; point < limit; point++, vec++, tag++ )+    {+      vec->x = point->x;+      vec->y = point->y;++      if ( point->flags & AF_FLAG_CONIC )+        tag[0] = FT_CURVE_TAG_CONIC;+      else if ( point->flags & AF_FLAG_CUBIC )+        tag[0] = FT_CURVE_TAG_CUBIC;+      else+        tag[0] = FT_CURVE_TAG_ON;+    }+  }+++  /****************************************************************+   *+   *                     EDGE POINT GRID-FITTING+   *+   ****************************************************************/+++  FT_LOCAL_DEF( void )+  af_glyph_hints_align_edge_points( AF_GlyphHints  hints,+                                    AF_Dimension   dim )+  {+    AF_AxisHints  axis          = & hints->axis[dim];+    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    AF_Segment    seg;+++    if ( dim == AF_DIMENSION_HORZ )+    {+      for ( seg = segments; seg < segment_limit; seg++ )+      {+        AF_Edge   edge = seg->edge;+        AF_Point  point, first, last;+++        if ( edge == NULL )+          continue;++        first = seg->first;+        last  = seg->last;+        point = first;+        for (;;)+        {+          point->x      = edge->pos;+          point->flags |= AF_FLAG_TOUCH_X;++          if ( point == last )+            break;++          point = point->next;++        }+      }+    }+    else+    {+      for ( seg = segments; seg < segment_limit; seg++ )+      {+        AF_Edge   edge = seg->edge;+        AF_Point  point, first, last;+++        if ( edge == NULL )+          continue;++        first = seg->first;+        last  = seg->last;+        point = first;+        for (;;)+        {+          point->y      = edge->pos;+          point->flags |= AF_FLAG_TOUCH_Y;++          if ( point == last )+            break;++          point = point->next;+        }+      }+    }+  }+++  /****************************************************************+   *+   *                    STRONG POINT INTERPOLATION+   *+   ****************************************************************/+++  /* hint the strong points -- this is equivalent to the TrueType `IP' */+  /* hinting instruction                                               */++  FT_LOCAL_DEF( void )+  af_glyph_hints_align_strong_points( AF_GlyphHints  hints,+                                      AF_Dimension   dim )+  {+    AF_Point      points      = hints->points;+    AF_Point      point_limit = points + hints->num_points;+    AF_AxisHints  axis        = &hints->axis[dim];+    AF_Edge       edges       = axis->edges;+    AF_Edge       edge_limit  = edges + axis->num_edges;+    AF_Flags      touch_flag;+++    if ( dim == AF_DIMENSION_HORZ )+      touch_flag = AF_FLAG_TOUCH_X;+    else+      touch_flag  = AF_FLAG_TOUCH_Y;++    if ( edges < edge_limit )+    {+      AF_Point  point;+      AF_Edge   edge;+++      for ( point = points; point < point_limit; point++ )+      {+        FT_Pos  u, ou, fu;  /* point position */+        FT_Pos  delta;+++        if ( point->flags & touch_flag )+          continue;++        /* if this point is candidate to weak interpolation, we       */+        /* interpolate it after all strong points have been processed */++        if (  ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&+             !( point->flags & AF_FLAG_INFLECTION )         )+          continue;++        if ( dim == AF_DIMENSION_VERT )+        {+          u  = point->fy;+          ou = point->oy;+        }+        else+        {+          u  = point->fx;+          ou = point->ox;+        }++        fu = u;++        /* is the point before the first edge? */+        edge  = edges;+        delta = edge->fpos - u;+        if ( delta >= 0 )+        {+          u = edge->pos - ( edge->opos - ou );+          goto Store_Point;+        }++        /* is the point after the last edge? */+        edge  = edge_limit - 1;+        delta = u - edge->fpos;+        if ( delta >= 0 )+        {+          u = edge->pos + ( ou - edge->opos );+          goto Store_Point;+        }++        {+          FT_PtrDist  min, max, mid;+          FT_Pos      fpos;+++          /* find enclosing edges */+          min = 0;+          max = edge_limit - edges;++#if 1+          /* for small edge counts, a linear search is better */+          if ( max <= 8 )+          {+            FT_PtrDist  nn;++            for ( nn = 0; nn < max; nn++ )+              if ( edges[nn].fpos >= u )+                break;++            if ( edges[nn].fpos == u )+            {+              u = edges[nn].pos;+              goto Store_Point;+            }+            min = nn;+          }+          else+#endif+          while ( min < max )+          {+            mid  = ( max + min ) >> 1;+            edge = edges + mid;+            fpos = edge->fpos;++            if ( u < fpos )+              max = mid;+            else if ( u > fpos )+              min = mid + 1;+            else+            {+              /* we are on the edge */+              u = edge->pos;+              goto Store_Point;+            }+          }++          {+            AF_Edge  before = edges + min - 1;+            AF_Edge  after  = edges + min + 0;+++            /* assert( before && after && before != after ) */+            if ( before->scale == 0 )+              before->scale = FT_DivFix( after->pos - before->pos,+                                         after->fpos - before->fpos );++            u = before->pos + FT_MulFix( fu - before->fpos,+                                         before->scale );+          }+        }++      Store_Point:+        /* save the point position */+        if ( dim == AF_DIMENSION_HORZ )+          point->x = u;+        else+          point->y = u;++        point->flags |= touch_flag;+      }+    }+  }+++  /****************************************************************+   *+   *                    WEAK POINT INTERPOLATION+   *+   ****************************************************************/+++  static void+  af_iup_shift( AF_Point  p1,+                AF_Point  p2,+                AF_Point  ref )+  {+    AF_Point  p;+    FT_Pos    delta = ref->u - ref->v;++    if ( delta == 0 )+      return;++    for ( p = p1; p < ref; p++ )+      p->u = p->v + delta;++    for ( p = ref + 1; p <= p2; p++ )+      p->u = p->v + delta;+  }+++  static void+  af_iup_interp( AF_Point  p1,+                 AF_Point  p2,+                 AF_Point  ref1,+                 AF_Point  ref2 )+  {+    AF_Point  p;+    FT_Pos    u;+    FT_Pos    v1 = ref1->v;+    FT_Pos    v2 = ref2->v;+    FT_Pos    d1 = ref1->u - v1;+    FT_Pos    d2 = ref2->u - v2;+++    if ( p1 > p2 )+      return;++    if ( v1 == v2 )+    {+      for ( p = p1; p <= p2; p++ )+      {+        u = p->v;++        if ( u <= v1 )+          u += d1;+        else+          u += d2;++        p->u = u;+      }+      return;+    }++    if ( v1 < v2 )+    {+      for ( p = p1; p <= p2; p++ )+      {+        u = p->v;++        if ( u <= v1 )+          u += d1;+        else if ( u >= v2 )+          u += d2;+        else+          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );++        p->u = u;+      }+    }+    else+    {+      for ( p = p1; p <= p2; p++ )+      {+        u = p->v;++        if ( u <= v2 )+          u += d2;+        else if ( u >= v1 )+          u += d1;+        else+          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );++        p->u = u;+      }+    }+  }+++  FT_LOCAL_DEF( void )+  af_glyph_hints_align_weak_points( AF_GlyphHints  hints,+                                    AF_Dimension   dim )+  {+    AF_Point   points        = hints->points;+    AF_Point   point_limit   = points + hints->num_points;+    AF_Point*  contour       = hints->contours;+    AF_Point*  contour_limit = contour + hints->num_contours;+    AF_Flags   touch_flag;+    AF_Point   point;+    AF_Point   end_point;+    AF_Point   first_point;+++    /* PASS 1: Move segment points to edge positions */++    if ( dim == AF_DIMENSION_HORZ )+    {+      touch_flag = AF_FLAG_TOUCH_X;++      for ( point = points; point < point_limit; point++ )+      {+        point->u = point->x;+        point->v = point->ox;+      }+    }+    else+    {+      touch_flag = AF_FLAG_TOUCH_Y;++      for ( point = points; point < point_limit; point++ )+      {+        point->u = point->y;+        point->v = point->oy;+      }+    }++    point = points;++    for ( ; contour < contour_limit; contour++ )+    {+      AF_Point  first_touched, last_touched;+++      point       = *contour;+      end_point   = point->prev;+      first_point = point;++      /* find first touched point */+      for (;;)+      {+        if ( point > end_point )  /* no touched point in contour */+          goto NextContour;++        if ( point->flags & touch_flag )+          break;++        point++;+      }++      first_touched = point;+      last_touched  = point;++      for (;;)+      {+        FT_ASSERT( point <= end_point &&+                   ( point->flags & touch_flag ) != 0 );++        /* skip any touched neighbhours */+        while ( point < end_point && ( point[1].flags & touch_flag ) != 0 )+          point++;++        last_touched = point;++        /* find the next touched point, if any */+        point ++;+        for (;;)+        {+          if ( point > end_point )+            goto EndContour;++          if ( ( point->flags & touch_flag ) != 0 )+            break;++          point++;+        }++        /* interpolate between last_touched and point */+        af_iup_interp( last_touched + 1, point - 1,+                       last_touched, point );+      }++    EndContour:+      /* special case: only one point was touched */+      if ( last_touched == first_touched )+      {+        af_iup_shift( first_point, end_point, first_touched );+      }+      else /* interpolate the last part */+      {+        if ( last_touched < end_point )+          af_iup_interp( last_touched + 1, end_point,+                         last_touched, first_touched );++        if ( first_touched > points )+          af_iup_interp( first_point, first_touched - 1,+                         last_touched, first_touched );+      }++    NextContour:+      ;+    }++    /* now save the interpolated values back to x/y */+    if ( dim == AF_DIMENSION_HORZ )+    {+      for ( point = points; point < point_limit; point++ )+        point->x = point->u;+    }+    else+    {+      for ( point = points; point < point_limit; point++ )+        point->y = point->u;+    }+  }+++#ifdef AF_USE_WARPER++  FT_LOCAL_DEF( void )+  af_glyph_hints_scale_dim( AF_GlyphHints  hints,+                            AF_Dimension   dim,+                            FT_Fixed       scale,+                            FT_Pos         delta )+  {+    AF_Point  points       = hints->points;+    AF_Point  points_limit = points + hints->num_points;+    AF_Point  point;+++    if ( dim == AF_DIMENSION_HORZ )+    {+      for ( point = points; point < points_limit; point++ )+        point->x = FT_MulFix( point->fx, scale ) + delta;+    }+    else+    {+      for ( point = points; point < points_limit; point++ )+        point->y = FT_MulFix( point->fy, scale ) + delta;+    }+  }++#endif /* AF_USE_WARPER */++/* END */
+ src/autofit/afhints.h view
@@ -0,0 +1,332 @@+/***************************************************************************/+/*                                                                         */+/*  afhints.h                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines (specification).                        */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFHINTS_H__+#define __AFHINTS_H__++#include "aftypes.h"++#define xxAF_SORT_SEGMENTS++FT_BEGIN_HEADER++ /*+  *  The definition of outline glyph hints.  These are shared by all+  *  script analysis routines (until now).+  */++  typedef enum  AF_Dimension_+  {+    AF_DIMENSION_HORZ = 0,  /* x coordinates,                    */+                            /* i.e., vertical segments & edges   */+    AF_DIMENSION_VERT = 1,  /* y coordinates,                    */+                            /* i.e., horizontal segments & edges */++    AF_DIMENSION_MAX  /* do not remove */++  } AF_Dimension;+++  /* hint directions -- the values are computed so that two vectors are */+  /* in opposite directions iff `dir1 + dir2 == 0'                      */+  typedef enum  AF_Direction_+  {+    AF_DIR_NONE  =  4,+    AF_DIR_RIGHT =  1,+    AF_DIR_LEFT  = -1,+    AF_DIR_UP    =  2,+    AF_DIR_DOWN  = -2++  } AF_Direction;+++  /* point hint flags */+  typedef enum  AF_Flags_+  {+    AF_FLAG_NONE = 0,++    /* point type flags */+    AF_FLAG_CONIC   = 1 << 0,+    AF_FLAG_CUBIC   = 1 << 1,+    AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,++    /* point extremum flags */+    AF_FLAG_EXTREMA_X = 1 << 2,+    AF_FLAG_EXTREMA_Y = 1 << 3,++    /* point roundness flags */+    AF_FLAG_ROUND_X = 1 << 4,+    AF_FLAG_ROUND_Y = 1 << 5,++    /* point touch flags */+    AF_FLAG_TOUCH_X = 1 << 6,+    AF_FLAG_TOUCH_Y = 1 << 7,++    /* candidates for weak interpolation have this flag set */+    AF_FLAG_WEAK_INTERPOLATION = 1 << 8,++    /* all inflection points in the outline have this flag set */+    AF_FLAG_INFLECTION = 1 << 9++  } AF_Flags;+++  /* edge hint flags */+  typedef enum  AF_Edge_Flags_+  {+    AF_EDGE_NORMAL = 0,+    AF_EDGE_ROUND  = 1 << 0,+    AF_EDGE_SERIF  = 1 << 1,+    AF_EDGE_DONE   = 1 << 2++  } AF_Edge_Flags;+++  typedef struct AF_PointRec_*    AF_Point;+  typedef struct AF_SegmentRec_*  AF_Segment;+  typedef struct AF_EdgeRec_*     AF_Edge;+++  typedef struct  AF_PointRec_+  {+    FT_UShort  flags;    /* point flags used by hinter   */+    FT_Char    in_dir;   /* direction of inwards vector  */+    FT_Char    out_dir;  /* direction of outwards vector */++    FT_Pos     ox, oy;   /* original, scaled position                   */+    FT_Short   fx, fy;   /* original, unscaled position (font units)    */+    FT_Pos     x, y;     /* current position                            */+    FT_Pos     u, v;     /* current (x,y) or (y,x) depending on context */++    AF_Point   next;     /* next point in contour     */+    AF_Point   prev;     /* previous point in contour */++  } AF_PointRec;+++  typedef struct  AF_SegmentRec_+  {+    FT_Byte     flags;       /* edge/segment flags for this segment */+    FT_Char     dir;         /* segment direction                   */+    FT_Short    pos;         /* position of segment                 */+    FT_Short    min_coord;   /* minimum coordinate of segment       */+    FT_Short    max_coord;   /* maximum coordinate of segment       */+    FT_Short    height;      /* the hinted segment height           */++    AF_Edge     edge;        /* the segment's parent edge           */+    AF_Segment  edge_next;   /* link to next segment in parent edge */++    AF_Segment  link;        /* (stem) link segment        */+    AF_Segment  serif;       /* primary segment for serifs */+    FT_Pos      num_linked;  /* number of linked segments  */+    FT_Pos      score;       /* used during stem matching  */+    FT_Pos      len;         /* used during stem matching  */++    AF_Point    first;       /* first point in edge segment             */+    AF_Point    last;        /* last point in edge segment              */+    AF_Point*   contour;     /* ptr to first point of segment's contour */++  } AF_SegmentRec;+++  typedef struct  AF_EdgeRec_+  {+    FT_Short    fpos;       /* original, unscaled position (font units) */+    FT_Pos      opos;       /* original, scaled position                */+    FT_Pos      pos;        /* current position                         */++    FT_Byte     flags;      /* edge flags                                   */+    FT_Char     dir;        /* edge direction                               */+    FT_Fixed    scale;      /* used to speed up interpolation between edges */+    AF_Width    blue_edge;  /* non-NULL if this is a blue edge              */++    AF_Edge     link;+    AF_Edge     serif;+    FT_Short    num_linked;++    FT_Int      score;++    AF_Segment  first;+    AF_Segment  last;++  } AF_EdgeRec;+++  typedef struct  AF_AxisHintsRec_+  {+    FT_Int        num_segments;+    FT_Int        max_segments;+    AF_Segment    segments;+#ifdef AF_SORT_SEGMENTS+    FT_Int        mid_segments;+#endif++    FT_Int        num_edges;+    FT_Int        max_edges;+    AF_Edge       edges;++    AF_Direction  major_dir;++  } AF_AxisHintsRec, *AF_AxisHints;+++  typedef struct  AF_GlyphHintsRec_+  {+    FT_Memory         memory;++    FT_Fixed          x_scale;+    FT_Pos            x_delta;++    FT_Fixed          y_scale;+    FT_Pos            y_delta;++    FT_Pos            edge_distance_threshold;++    FT_Int            max_points;+    FT_Int            num_points;+    AF_Point          points;++    FT_Int            max_contours;+    FT_Int            num_contours;+    AF_Point*         contours;++    AF_AxisHintsRec   axis[AF_DIMENSION_MAX];++    FT_UInt32         scaler_flags;  /* copy of scaler flags     */+    FT_UInt32         other_flags;   /* free for script-specific */+                                     /* implementations          */+    AF_ScriptMetrics  metrics;++    FT_Pos            xmin_delta;    /* used for warping */+    FT_Pos            xmax_delta;+    +  } AF_GlyphHintsRec;+++#define AF_HINTS_TEST_SCALER( h, f )  ( (h)->scaler_flags & (f) )+#define AF_HINTS_TEST_OTHER( h, f )   ( (h)->other_flags  & (f) )+++#ifdef AF_DEBUG++#define AF_HINTS_DO_HORIZONTAL( h )                                     \+          ( !_af_debug_disable_horz_hints                            && \+            !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )++#define AF_HINTS_DO_VERTICAL( h )                                     \+          ( !_af_debug_disable_vert_hints                          && \+            !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )++#define AF_HINTS_DO_ADVANCE( h )                                \+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )++#define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )++#else /* !AF_DEBUG */++#define AF_HINTS_DO_HORIZONTAL( h )                                \+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL )++#define AF_HINTS_DO_VERTICAL( h )                                \+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )++#define AF_HINTS_DO_ADVANCE( h )                                \+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )++#define AF_HINTS_DO_BLUES( h )  1++#endif /* !AF_DEBUG */+++  FT_LOCAL( AF_Direction )+  af_direction_compute( FT_Pos  dx,+                        FT_Pos  dy );+++  FT_LOCAL( FT_Error )+  af_axis_hints_new_segment( AF_AxisHints  axis,+                             FT_Memory     memory,+                             AF_Segment   *asegment );++  FT_LOCAL( FT_Error)+  af_axis_hints_new_edge( AF_AxisHints  axis,+                          FT_Int        fpos,+                          AF_Direction  dir,+                          FT_Memory     memory,+                          AF_Edge      *edge );++  FT_LOCAL( void )+  af_glyph_hints_init( AF_GlyphHints  hints,+                       FT_Memory      memory );++++  /*+   *  recompute all AF_Point in a AF_GlyphHints from the definitions+   *  in a source outline+   */+  FT_LOCAL( void )+  af_glyph_hints_rescale( AF_GlyphHints     hints,+                          AF_ScriptMetrics  metrics );++  FT_LOCAL( FT_Error )+  af_glyph_hints_reload( AF_GlyphHints  hints,+                         FT_Outline*    outline );++  FT_LOCAL( void )+  af_glyph_hints_save( AF_GlyphHints  hints,+                       FT_Outline*    outline );++  FT_LOCAL( void )+  af_glyph_hints_align_edge_points( AF_GlyphHints  hints,+                                    AF_Dimension   dim );++  FT_LOCAL( void )+  af_glyph_hints_align_strong_points( AF_GlyphHints  hints,+                                      AF_Dimension   dim );++  FT_LOCAL( void )+  af_glyph_hints_align_weak_points( AF_GlyphHints  hints,+                                    AF_Dimension   dim );++#ifdef AF_USE_WARPER+  FT_LOCAL( void )+  af_glyph_hints_scale_dim( AF_GlyphHints  hints,+                            AF_Dimension   dim,+                            FT_Fixed       scale,+                            FT_Pos         delta );+#endif++  FT_LOCAL( void )+  af_glyph_hints_done( AF_GlyphHints  hints );++/* */++#define AF_SEGMENT_LEN( seg )          ( (seg)->max_coord - (seg)->min_coord )++#define AF_SEGMENT_DIST( seg1, seg2 )  ( ( (seg1)->pos > (seg2)->pos )   \+                                           ? (seg1)->pos - (seg2)->pos   \+                                           : (seg2)->pos - (seg1)->pos )+++FT_END_HEADER++#endif /* __AFHINTS_H__ */+++/* END */
+ src/autofit/afindic.c view
@@ -0,0 +1,130 @@+/***************************************************************************/+/*                                                                         */+/*  afindic.c                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines for Indic scripts (body).               */+/*                                                                         */+/*  Copyright 2007 by                                                      */+/*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "aftypes.h"+#include "aflatin.h"+++#ifdef AF_CONFIG_OPTION_INDIC++#include "afindic.h"+#include "aferrors.h"+#include "afcjk.h"+++#ifdef AF_USE_WARPER+#include "afwarp.h"+#endif+++  static FT_Error+  af_indic_metrics_init( AF_LatinMetrics  metrics,+                         FT_Face          face )+  {+    /* use CJK routines */+    return af_cjk_metrics_init( metrics, face );+  }+++  static void+  af_indic_metrics_scale( AF_LatinMetrics  metrics,+                          AF_Scaler        scaler )+  {+    /* use CJK routines */+    af_cjk_metrics_scale( metrics, scaler );+  }+++  static FT_Error+  af_indic_hints_init( AF_GlyphHints    hints,+                       AF_LatinMetrics  metrics )+  {+    /* use CJK routines */+    return af_cjk_hints_init( hints, metrics );+  }+++  static FT_Error+  af_indic_hints_apply( AF_GlyphHints    hints,+                        FT_Outline*      outline,+                        AF_LatinMetrics  metrics)+  {+    /* use CJK routines */+    return af_cjk_hints_apply( hints, outline, metrics );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                I N D I C   S C R I P T   C L A S S            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  static const AF_Script_UniRangeRec  af_indic_uniranges[] =+  {+#if 0+    AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ),  /* why this? */+#endif+    AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL),    /* Indic Range */+    AF_UNIRANGE_REC(      0UL,      0UL)+  };+++  AF_DEFINE_SCRIPT_CLASS(af_indic_script_class,+    AF_SCRIPT_INDIC,+    af_indic_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) af_indic_metrics_init,+    (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   af_indic_hints_init,+    (AF_Script_ApplyHintsFunc)  af_indic_hints_apply+  )++#else /* !AF_CONFIG_OPTION_INDIC */++  static const AF_Script_UniRangeRec  af_indic_uniranges[] =+  {+    { 0, 0 }+  };+++  AF_DEFINE_SCRIPT_CLASS(af_indic_script_class,+    AF_SCRIPT_INDIC,+    af_indic_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) NULL,+    (AF_Script_ScaleMetricsFunc)NULL,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   NULL,+    (AF_Script_ApplyHintsFunc)  NULL+  )++#endif /* !AF_CONFIG_OPTION_INDIC */+++/* END */
+ src/autofit/afindic.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  afindic.h                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines for Indic scripts (specification).      */+/*                                                                         */+/*  Copyright 2007 by                                                      */+/*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFINDIC_H__+#define __AFINDIC_H__++#include "afhints.h"+++FT_BEGIN_HEADER+++  /* the Indic-specific script class */++  AF_DECLARE_SCRIPT_CLASS(af_indic_script_class)+++/* */++FT_END_HEADER++#endif /* __AFINDIC_H__ */+++/* END */
+ src/autofit/aflatin.c view
@@ -0,0 +1,2224 @@+/***************************************************************************/+/*                                                                         */+/*  aflatin.c                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines for latin script (body).                */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by            */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_ADVANCES_H++#include "aflatin.h"+#include "aferrors.h"+++#ifdef AF_USE_WARPER+#include "afwarp.h"+#endif+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****            L A T I N   G L O B A L   M E T R I C S            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  af_latin_metrics_init_widths( AF_LatinMetrics  metrics,+                                FT_Face          face,+                                FT_ULong         charcode )+  {+    /* scan the array of segments in each direction */+    AF_GlyphHintsRec  hints[1];+++    af_glyph_hints_init( hints, face->memory );++    metrics->axis[AF_DIMENSION_HORZ].width_count = 0;+    metrics->axis[AF_DIMENSION_VERT].width_count = 0;++    {+      FT_Error             error;+      FT_UInt              glyph_index;+      int                  dim;+      AF_LatinMetricsRec   dummy[1];+      AF_Scaler            scaler = &dummy->root.scaler;+++      glyph_index = FT_Get_Char_Index( face, charcode );+      if ( glyph_index == 0 )+        goto Exit;++      error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );+      if ( error || face->glyph->outline.n_points <= 0 )+        goto Exit;++      FT_ZERO( dummy );++      dummy->units_per_em = metrics->units_per_em;+      scaler->x_scale     = scaler->y_scale = 0x10000L;+      scaler->x_delta     = scaler->y_delta = 0;+      scaler->face        = face;+      scaler->render_mode = FT_RENDER_MODE_NORMAL;+      scaler->flags       = 0;++      af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );++      error = af_glyph_hints_reload( hints, &face->glyph->outline );+      if ( error )+        goto Exit;++      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+      {+        AF_LatinAxis  axis    = &metrics->axis[dim];+        AF_AxisHints  axhints = &hints->axis[dim];+        AF_Segment    seg, limit, link;+        FT_UInt       num_widths = 0;+++        error = af_latin_hints_compute_segments( hints,+                                                 (AF_Dimension)dim );+        if ( error )+          goto Exit;++        af_latin_hints_link_segments( hints,+                                      (AF_Dimension)dim );++        seg   = axhints->segments;+        limit = seg + axhints->num_segments;++        for ( ; seg < limit; seg++ )+        {+          link = seg->link;++          /* we only consider stem segments there! */+          if ( link && link->link == seg && link > seg )+          {+            FT_Pos  dist;+++            dist = seg->pos - link->pos;+            if ( dist < 0 )+              dist = -dist;++            if ( num_widths < AF_LATIN_MAX_WIDTHS )+              axis->widths[ num_widths++ ].org = dist;+          }+        }++        af_sort_widths( num_widths, axis->widths );+        axis->width_count = num_widths;+      }++  Exit:+      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+      {+        AF_LatinAxis  axis = &metrics->axis[dim];+        FT_Pos        stdw;+++        stdw = ( axis->width_count > 0 )+                 ? axis->widths[0].org+                 : AF_LATIN_CONSTANT( metrics, 50 );++        /* let's try 20% of the smallest width */+        axis->edge_distance_threshold = stdw / 5;+        axis->standard_width          = stdw;+        axis->extra_light             = 0;+      }+    }++    af_glyph_hints_done( hints );+  }++++#define AF_LATIN_MAX_TEST_CHARACTERS  12+++  static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES]+                                       [AF_LATIN_MAX_TEST_CHARACTERS + 1] =+  {+    "THEZOCQS",+    "HEZLOCUS",+    "fijkdbh",+    "xzroesc",+    "xzroesc",+    "pqgjy"+  };+++  static void+  af_latin_metrics_init_blues( AF_LatinMetrics  metrics,+                               FT_Face          face )+  {+    FT_Pos        flats [AF_LATIN_MAX_TEST_CHARACTERS];+    FT_Pos        rounds[AF_LATIN_MAX_TEST_CHARACTERS];+    FT_Int        num_flats;+    FT_Int        num_rounds;+    FT_Int        bb;+    AF_LatinBlue  blue;+    FT_Error      error;+    AF_LatinAxis  axis  = &metrics->axis[AF_DIMENSION_VERT];+    FT_GlyphSlot  glyph = face->glyph;+++    /* we compute the blues simply by loading each character from the    */+    /* 'af_latin_blue_chars[blues]' string, then compute its top-most or */+    /* bottom-most points (depending on `AF_IS_TOP_BLUE')                */++    AF_LOG(( "blue zones computation\n" ));+    AF_LOG(( "------------------------------------------------\n" ));++    for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )+    {+      const char*  p     = af_latin_blue_chars[bb];+      const char*  limit = p + AF_LATIN_MAX_TEST_CHARACTERS;+      FT_Pos*      blue_ref;+      FT_Pos*      blue_shoot;+++      AF_LOG(( "blue %3d: ", bb ));++      num_flats  = 0;+      num_rounds = 0;++      for ( ; p < limit && *p; p++ )+      {+        FT_UInt     glyph_index;+        FT_Pos      best_y; /* same as points.y */+        FT_Int      best_point, best_first, best_last;+        FT_Vector*  points;+        FT_Bool     round = 0;+++        AF_LOG(( "'%c'", *p ));++        /* load the character in the face -- skip unknown or empty ones */+        glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );+        if ( glyph_index == 0 )+          continue;++        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );+        if ( error || glyph->outline.n_points <= 0 )+          continue;++        /* now compute min or max point indices and coordinates */+        points      = glyph->outline.points;+        best_point  = -1;+        best_y      = 0;  /* make compiler happy */+        best_first  = 0;  /* ditto */+        best_last   = 0;  /* ditto */++        {+          FT_Int  nn;+          FT_Int  first = 0;+          FT_Int  last  = -1;+++          for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ )+          {+            FT_Int  old_best_point = best_point;+            FT_Int  pp;+++            last = glyph->outline.contours[nn];++            /* Avoid single-point contours since they are never rasterized. */+            /* In some fonts, they correspond to mark attachment points     */+            /* which are way outside of the glyph's real outline.           */+            if ( last <= first )+                continue;++            if ( AF_LATIN_IS_TOP_BLUE( bb ) )+            {+              for ( pp = first; pp <= last; pp++ )+                if ( best_point < 0 || points[pp].y > best_y )+                {+                  best_point = pp;+                  best_y     = points[pp].y;+                }+            }+            else+            {+              for ( pp = first; pp <= last; pp++ )+                if ( best_point < 0 || points[pp].y < best_y )+                {+                  best_point = pp;+                  best_y     = points[pp].y;+                }+            }++            if ( best_point != old_best_point )+            {+              best_first = first;+              best_last  = last;+            }+          }+          AF_LOG(( "%5d", best_y ));+        }++        /* now check whether the point belongs to a straight or round   */+        /* segment; we first need to find in which contour the extremum */+        /* lies, then inspect its previous and next points              */+        if ( best_point >= 0 )+        {+          FT_Int  prev, next;+          FT_Pos  dist;+++          /* now look for the previous and next points that are not on the */+          /* same Y coordinate.  Threshold the `closeness'...              */+          prev = best_point;+          next = prev;++          do+          {+            if ( prev > best_first )+              prev--;+            else+              prev = best_last;++            dist = points[prev].y - best_y;+            if ( dist < -5 || dist > 5 )+              break;++          } while ( prev != best_point );++          do+          {+            if ( next < best_last )+              next++;+            else+              next = best_first;++            dist = points[next].y - best_y;+            if ( dist < -5 || dist > 5 )+              break;++          } while ( next != best_point );++          /* now, set the `round' flag depending on the segment's kind */+          round = FT_BOOL(+            FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||+            FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON );++          AF_LOG(( "%c ", round ? 'r' : 'f' ));+        }++        if ( round )+          rounds[num_rounds++] = best_y;+        else+          flats[num_flats++]   = best_y;+      }++      AF_LOG(( "\n" ));++      if ( num_flats == 0 && num_rounds == 0 )+      {+        /*+         *  we couldn't find a single glyph to compute this blue zone,+         *  we will simply ignore it then+         */+        AF_LOG(( "empty\n" ));+        continue;+      }++      /* we have computed the contents of the `rounds' and `flats' tables, */+      /* now determine the reference and overshoot position of the blue -- */+      /* we simply take the median value after a simple sort               */+      af_sort_pos( num_rounds, rounds );+      af_sort_pos( num_flats,  flats );++      blue       = & axis->blues[axis->blue_count];+      blue_ref   = & blue->ref.org;+      blue_shoot = & blue->shoot.org;++      axis->blue_count++;++      if ( num_flats == 0 )+      {+        *blue_ref   =+        *blue_shoot = rounds[num_rounds / 2];+      }+      else if ( num_rounds == 0 )+      {+        *blue_ref   =+        *blue_shoot = flats[num_flats / 2];+      }+      else+      {+        *blue_ref   = flats[num_flats / 2];+        *blue_shoot = rounds[num_rounds / 2];+      }++      /* there are sometimes problems: if the overshoot position of top     */+      /* zones is under its reference position, or the opposite for bottom  */+      /* zones.  We must thus check everything there and correct the errors */+      if ( *blue_shoot != *blue_ref )+      {+        FT_Pos   ref      = *blue_ref;+        FT_Pos   shoot    = *blue_shoot;+        FT_Bool  over_ref = FT_BOOL( shoot > ref );+++        if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )+          *blue_shoot = *blue_ref = ( shoot + ref ) / 2;+      }++      blue->flags = 0;+      if ( AF_LATIN_IS_TOP_BLUE( bb ) )+        blue->flags |= AF_LATIN_BLUE_TOP;++      /*+       * The following flag is used later to adjust the y and x scales+       * in order to optimize the pixel grid alignment of the top of small+       * letters.+       */+      if ( bb == AF_LATIN_BLUE_SMALL_TOP )+        blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;++      AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));+    }++    return;+  }+++  FT_LOCAL_DEF( void )+  af_latin_metrics_check_digits( AF_LatinMetrics  metrics,+                                 FT_Face          face )+  {+    FT_UInt   i;+    FT_Bool   started = 0, same_width = 1;+    FT_Fixed  advance, old_advance = 0;+++    /* check whether all ASCII digits have the same advance width; */+    /* digit `0' is 0x30 in all supported charmaps                 */+    for ( i = 0x30; i <= 0x39; i++ )+    {+      FT_UInt  glyph_index;+++      glyph_index = FT_Get_Char_Index( face, i );+      if ( glyph_index == 0 )+        continue;++      if ( FT_Get_Advance( face, glyph_index,+                           FT_LOAD_NO_SCALE         |+                           FT_LOAD_NO_HINTING       |+                           FT_LOAD_IGNORE_TRANSFORM,+                           &advance ) )+        continue;++      if ( started )+      {+        if ( advance != old_advance )+        {+          same_width = 0;+          break;+        }+      }+      else+      {+        old_advance = advance;+        started     = 1;+      }+    }++    metrics->root.digits_have_same_width = same_width;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin_metrics_init( AF_LatinMetrics  metrics,+                         FT_Face          face )+  {+    FT_Error    error = AF_Err_Ok;+    FT_CharMap  oldmap = face->charmap;+    FT_UInt     ee;++    static const FT_Encoding  latin_encodings[] =+    {+      FT_ENCODING_UNICODE,+      FT_ENCODING_APPLE_ROMAN,+      FT_ENCODING_ADOBE_STANDARD,+      FT_ENCODING_ADOBE_LATIN_1,+      FT_ENCODING_NONE  /* end of list */+    };+++    metrics->units_per_em = face->units_per_EM;++    /* do we have a latin charmap in there? */+    for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )+    {+      error = FT_Select_Charmap( face, latin_encodings[ee] );+      if ( !error )+        break;+    }++    if ( !error )+    {+      /* For now, compute the standard width and height from the `o'. */+      af_latin_metrics_init_widths( metrics, face, 'o' );+      af_latin_metrics_init_blues( metrics, face );+      af_latin_metrics_check_digits( metrics, face );+    }++    FT_Set_Charmap( face, oldmap );+    return AF_Err_Ok;+  }+++  static void+  af_latin_metrics_scale_dim( AF_LatinMetrics  metrics,+                              AF_Scaler        scaler,+                              AF_Dimension     dim )+  {+    FT_Fixed      scale;+    FT_Pos        delta;+    AF_LatinAxis  axis;+    FT_UInt       nn;+++    if ( dim == AF_DIMENSION_HORZ )+    {+      scale = scaler->x_scale;+      delta = scaler->x_delta;+    }+    else+    {+      scale = scaler->y_scale;+      delta = scaler->y_delta;+    }++    axis = &metrics->axis[dim];++    if ( axis->org_scale == scale && axis->org_delta == delta )+      return;++    axis->org_scale = scale;+    axis->org_delta = delta;++    /*+     * correct X and Y scale to optimize the alignment of the top of small+     * letters to the pixel grid+     */+    {+      AF_LatinAxis  Axis = &metrics->axis[AF_DIMENSION_VERT];+      AF_LatinBlue  blue = NULL;+++      for ( nn = 0; nn < Axis->blue_count; nn++ )+      {+        if ( Axis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT )+        {+          blue = &Axis->blues[nn];+          break;+        }+      }++      if ( blue )+      {+        FT_Pos  scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );+        FT_Pos  fitted = ( scaled + 40 ) & ~63;+++        if ( scaled != fitted )+        {+#if 0+          if ( dim == AF_DIMENSION_HORZ )+          {+            if ( fitted < scaled )+              scale -= scale / 50;  /* scale *= 0.98 */+          }+          else+#endif+          if ( dim == AF_DIMENSION_VERT )+          {+            scale = FT_MulDiv( scale, fitted, scaled );+          }+        }+      }+    }++    axis->scale = scale;+    axis->delta = delta;++    if ( dim == AF_DIMENSION_HORZ )+    {+      metrics->root.scaler.x_scale = scale;+      metrics->root.scaler.x_delta = delta;+    }+    else+    {+      metrics->root.scaler.y_scale = scale;+      metrics->root.scaler.y_delta = delta;+    }++    /* scale the standard widths */+    for ( nn = 0; nn < axis->width_count; nn++ )+    {+      AF_Width  width = axis->widths + nn;+++      width->cur = FT_MulFix( width->org, scale );+      width->fit = width->cur;+    }++    /* an extra-light axis corresponds to a standard width that is */+    /* smaller than 0.75 pixels                                    */+    axis->extra_light =+      (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );++    if ( dim == AF_DIMENSION_VERT )+    {+      /* scale the blue zones */+      for ( nn = 0; nn < axis->blue_count; nn++ )+      {+        AF_LatinBlue  blue = &axis->blues[nn];+        FT_Pos        dist;+++        blue->ref.cur   = FT_MulFix( blue->ref.org, scale ) + delta;+        blue->ref.fit   = blue->ref.cur;+        blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta;+        blue->shoot.fit = blue->shoot.cur;+        blue->flags    &= ~AF_LATIN_BLUE_ACTIVE;++        /* a blue zone is only active if it is less than 3/4 pixels tall */+        dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );+        if ( dist <= 48 && dist >= -48 )+        {+          FT_Pos  delta1, delta2;+++          delta1 = blue->shoot.org - blue->ref.org;+          delta2 = delta1;+          if ( delta1 < 0 )+            delta2 = -delta2;++          delta2 = FT_MulFix( delta2, scale );++          if ( delta2 < 32 )+            delta2 = 0;+          else if ( delta2 < 64 )+            delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );+          else+            delta2 = FT_PIX_ROUND( delta2 );++          if ( delta1 < 0 )+            delta2 = -delta2;++          blue->ref.fit   = FT_PIX_ROUND( blue->ref.cur );+          blue->shoot.fit = blue->ref.fit + delta2;++          blue->flags |= AF_LATIN_BLUE_ACTIVE;+        }+      }+    }+  }+++  FT_LOCAL_DEF( void )+  af_latin_metrics_scale( AF_LatinMetrics  metrics,+                          AF_Scaler        scaler )+  {+    metrics->root.scaler.render_mode = scaler->render_mode;+    metrics->root.scaler.face        = scaler->face;++    af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );+    af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****           L A T I N   G L Y P H   A N A L Y S I S             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( FT_Error )+  af_latin_hints_compute_segments( AF_GlyphHints  hints,+                                   AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    FT_Memory     memory        = hints->memory;+    FT_Error      error         = AF_Err_Ok;+    AF_Segment    segment       = NULL;+    AF_SegmentRec seg0;+    AF_Point*     contour       = hints->contours;+    AF_Point*     contour_limit = contour + hints->num_contours;+    AF_Direction  major_dir, segment_dir;+++    FT_ZERO( &seg0 );+    seg0.score = 32000;+    seg0.flags = AF_EDGE_NORMAL;++    major_dir   = (AF_Direction)FT_ABS( axis->major_dir );+    segment_dir = major_dir;++    axis->num_segments = 0;++    /* set up (u,v) in each point */+    if ( dim == AF_DIMENSION_HORZ )+    {+      AF_Point  point = hints->points;+      AF_Point  limit = point + hints->num_points;+++      for ( ; point < limit; point++ )+      {+        point->u = point->fx;+        point->v = point->fy;+      }+    }+    else+    {+      AF_Point  point = hints->points;+      AF_Point  limit = point + hints->num_points;+++      for ( ; point < limit; point++ )+      {+        point->u = point->fy;+        point->v = point->fx;+      }+    }++    /* do each contour separately */+    for ( ; contour < contour_limit; contour++ )+    {+      AF_Point  point   =  contour[0];+      AF_Point  last    =  point->prev;+      int       on_edge =  0;+      FT_Pos    min_pos =  32000;  /* minimum segment pos != min_coord */+      FT_Pos    max_pos = -32000;  /* maximum segment pos != max_coord */+      FT_Bool   passed;+++      if ( point == last )  /* skip singletons -- just in case */+        continue;++      if ( FT_ABS( last->out_dir )  == major_dir &&+           FT_ABS( point->out_dir ) == major_dir )+      {+        /* we are already on an edge, try to locate its start */+        last = point;++        for (;;)+        {+          point = point->prev;+          if ( FT_ABS( point->out_dir ) != major_dir )+          {+            point = point->next;+            break;+          }+          if ( point == last )+            break;+        }+      }++      last   = point;+      passed = 0;++      for (;;)+      {+        FT_Pos  u, v;+++        if ( on_edge )+        {+          u = point->u;+          if ( u < min_pos )+            min_pos = u;+          if ( u > max_pos )+            max_pos = u;++          if ( point->out_dir != segment_dir || point == last )+          {+            /* we are just leaving an edge; record a new segment! */+            segment->last = point;+            segment->pos  = (FT_Short)( ( min_pos + max_pos ) >> 1 );++            /* a segment is round if either its first or last point */+            /* is a control point                                   */+            if ( ( segment->first->flags | point->flags ) &+                   AF_FLAG_CONTROL                        )+              segment->flags |= AF_EDGE_ROUND;++            /* compute segment size */+            min_pos = max_pos = point->v;++            v = segment->first->v;+            if ( v < min_pos )+              min_pos = v;+            if ( v > max_pos )+              max_pos = v;++            segment->min_coord = (FT_Short)min_pos;+            segment->max_coord = (FT_Short)max_pos;+            segment->height    = (FT_Short)( segment->max_coord -+                                             segment->min_coord );++            on_edge = 0;+            segment = NULL;+            /* fallthrough */+          }+        }++        /* now exit if we are at the start/end point */+        if ( point == last )+        {+          if ( passed )+            break;+          passed = 1;+        }++        if ( !on_edge && FT_ABS( point->out_dir ) == major_dir )+        {+          /* this is the start of a new segment! */+          segment_dir = (AF_Direction)point->out_dir;++          /* clear all segment fields */+          error = af_axis_hints_new_segment( axis, memory, &segment );+          if ( error )+            goto Exit;++          segment[0]        = seg0;+          segment->dir      = (FT_Char)segment_dir;+          min_pos = max_pos = point->u;+          segment->first    = point;+          segment->last     = point;+          segment->contour  = contour;+          on_edge           = 1;+        }++        point = point->next;+      }++    } /* contours */+++    /* now slightly increase the height of segments when this makes */+    /* sense -- this is used to better detect and ignore serifs     */+    {+      AF_Segment  segments     = axis->segments;+      AF_Segment  segments_end = segments + axis->num_segments;+++      for ( segment = segments; segment < segments_end; segment++ )+      {+        AF_Point  first   = segment->first;+        AF_Point  last    = segment->last;+        FT_Pos    first_v = first->v;+        FT_Pos    last_v  = last->v;+++        if ( first == last )+          continue;++        if ( first_v < last_v )+        {+          AF_Point  p;+++          p = first->prev;+          if ( p->v < first_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( first_v - p->v ) >> 1 ) );++          p = last->next;+          if ( p->v > last_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( p->v - last_v ) >> 1 ) );+        }+        else+        {+          AF_Point  p;+++          p = first->prev;+          if ( p->v > first_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( p->v - first_v ) >> 1 ) );++          p = last->next;+          if ( p->v < last_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( last_v - p->v ) >> 1 ) );+        }+      }+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_latin_hints_link_segments( AF_GlyphHints  hints,+                                AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    FT_Pos        len_threshold, len_score;+    AF_Segment    seg1, seg2;+++    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );+    if ( len_threshold == 0 )+      len_threshold = 1;++    len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );++    /* now compare each segment to the others */+    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      /* the fake segments are introduced to hint the metrics -- */+      /* we must never link them to anything                     */+      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )+        continue;++      for ( seg2 = segments; seg2 < segment_limit; seg2++ )+        if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )+        {+          FT_Pos  pos1 = seg1->pos;+          FT_Pos  pos2 = seg2->pos;+          FT_Pos  dist = pos2 - pos1;+++          if ( dist < 0 )+            dist = -dist;++          {+            FT_Pos  min = seg1->min_coord;+            FT_Pos  max = seg1->max_coord;+            FT_Pos  len, score;+++            if ( min < seg2->min_coord )+              min = seg2->min_coord;++            if ( max > seg2->max_coord )+              max = seg2->max_coord;++            len = max - min;+            if ( len >= len_threshold )+            {+              score = dist + len_score / len;++              if ( score < seg1->score )+              {+                seg1->score = score;+                seg1->link  = seg2;+              }++              if ( score < seg2->score )+              {+                seg2->score = score;+                seg2->link  = seg1;+              }+            }+          }+        }+    }++    /* now, compute the `serif' segments */+    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      seg2 = seg1->link;++      if ( seg2 )+      {+        if ( seg2->link != seg1 )+        {+          seg1->link  = 0;+          seg1->serif = seg2->link;+        }+      }+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin_hints_compute_edges( AF_GlyphHints  hints,+                                AF_Dimension   dim )+  {+    AF_AxisHints  axis   = &hints->axis[dim];+    FT_Error      error  = AF_Err_Ok;+    FT_Memory     memory = hints->memory;+    AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];++    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    AF_Segment    seg;++    AF_Direction  up_dir;+    FT_Fixed      scale;+    FT_Pos        edge_distance_threshold;+    FT_Pos        segment_length_threshold;+++    axis->num_edges = 0;++    scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale+                                         : hints->y_scale;++    up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP+                                          : AF_DIR_RIGHT;++    /*+     *  We ignore all segments that are less than 1 pixels in length,+     *  to avoid many problems with serif fonts.  We compute the+     *  corresponding threshold in font units.+     */+    if ( dim == AF_DIMENSION_HORZ )+        segment_length_threshold = FT_DivFix( 64, hints->y_scale );+    else+        segment_length_threshold = 0;++    /*********************************************************************/+    /*                                                                   */+    /* We will begin by generating a sorted table of edges for the       */+    /* current direction.  To do so, we simply scan each segment and try */+    /* to find an edge in our table that corresponds to its position.    */+    /*                                                                   */+    /* If no edge is found, we create and insert a new edge in the       */+    /* sorted table.  Otherwise, we simply add the segment to the edge's */+    /* list which will be processed in the second step to compute the    */+    /* edge's properties.                                                */+    /*                                                                   */+    /* Note that the edges table is sorted along the segment/edge        */+    /* position.                                                         */+    /*                                                                   */+    /*********************************************************************/++    edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,+                                         scale );+    if ( edge_distance_threshold > 64 / 4 )+      edge_distance_threshold = 64 / 4;++    edge_distance_threshold = FT_DivFix( edge_distance_threshold,+                                         scale );++    for ( seg = segments; seg < segment_limit; seg++ )+    {+      AF_Edge  found = 0;+      FT_Int   ee;+++      if ( seg->height < segment_length_threshold )+        continue;++      /* A special case for serif edges: If they are smaller than */+      /* 1.5 pixels we ignore them.                               */+      if ( seg->serif                                     &&+           2 * seg->height < 3 * segment_length_threshold )+        continue;++      /* look for an edge corresponding to the segment */+      for ( ee = 0; ee < axis->num_edges; ee++ )+      {+        AF_Edge  edge = axis->edges + ee;+        FT_Pos   dist;+++        dist = seg->pos - edge->fpos;+        if ( dist < 0 )+          dist = -dist;++        if ( dist < edge_distance_threshold && edge->dir == seg->dir )+        {+          found = edge;+          break;+        }+      }++      if ( !found )+      {+        AF_Edge  edge;+++        /* insert a new edge in the list and */+        /* sort according to the position    */+        error = af_axis_hints_new_edge( axis, seg->pos,+                                        (AF_Direction)seg->dir,+                                        memory, &edge );+        if ( error )+          goto Exit;++        /* add the segment to the new edge's list */+        FT_ZERO( edge );++        edge->first    = seg;+        edge->last     = seg;+        edge->fpos     = seg->pos;+        edge->dir      = seg->dir;+        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );+        seg->edge_next = seg;+      }+      else+      {+        /* if an edge was found, simply add the segment to the edge's */+        /* list                                                       */+        seg->edge_next         = found->first;+        found->last->edge_next = seg;+        found->last            = seg;+      }+    }+++    /*********************************************************************/+    /*                                                                   */+    /* Good, we will now compute each edge's properties according to     */+    /* segments found on its position.  Basically, these are:            */+    /*                                                                   */+    /*  - edge's main direction                                          */+    /*  - stem edge, serif edge or both (which defaults to stem then)    */+    /*  - rounded edge, straight or both (which defaults to straight)    */+    /*  - link for edge                                                  */+    /*                                                                   */+    /*********************************************************************/++    /* first of all, set the `edge' field in each segment -- this is */+    /* required in order to compute edge links                       */++    /*+     * Note that removing this loop and setting the `edge' field of each+     * segment directly in the code above slows down execution speed for+     * some reasons on platforms like the Sun.+     */+    {+      AF_Edge  edges      = axis->edges;+      AF_Edge  edge_limit = edges + axis->num_edges;+      AF_Edge  edge;+++      for ( edge = edges; edge < edge_limit; edge++ )+      {+        seg = edge->first;+        if ( seg )+          do+          {+            seg->edge = edge;+            seg       = seg->edge_next;++          } while ( seg != edge->first );+      }++      /* now, compute each edge properties */+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        FT_Int  is_round    = 0;  /* does it contain round segments?    */+        FT_Int  is_straight = 0;  /* does it contain straight segments? */+        FT_Pos  ups         = 0;  /* number of upwards segments         */+        FT_Pos  downs       = 0;  /* number of downwards segments       */+++        seg = edge->first;++        do+        {+          FT_Bool  is_serif;+++          /* check for roundness of segment */+          if ( seg->flags & AF_EDGE_ROUND )+            is_round++;+          else+            is_straight++;++          /* check for segment direction */+          if ( seg->dir == up_dir )+            ups   += seg->max_coord-seg->min_coord;+          else+            downs += seg->max_coord-seg->min_coord;++          /* check for links -- if seg->serif is set, then seg->link must */+          /* be ignored                                                   */+          is_serif = (FT_Bool)( seg->serif               &&+                                seg->serif->edge         &&+                                seg->serif->edge != edge );++          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )+          {+            AF_Edge     edge2;+            AF_Segment  seg2;+++            edge2 = edge->link;+            seg2  = seg->link;++            if ( is_serif )+            {+              seg2  = seg->serif;+              edge2 = edge->serif;+            }++            if ( edge2 )+            {+              FT_Pos  edge_delta;+              FT_Pos  seg_delta;+++              edge_delta = edge->fpos - edge2->fpos;+              if ( edge_delta < 0 )+                edge_delta = -edge_delta;++              seg_delta = seg->pos - seg2->pos;+              if ( seg_delta < 0 )+                seg_delta = -seg_delta;++              if ( seg_delta < edge_delta )+                edge2 = seg2->edge;+            }+            else+              edge2 = seg2->edge;++            if ( is_serif )+            {+              edge->serif   = edge2;+              edge2->flags |= AF_EDGE_SERIF;+            }+            else+              edge->link  = edge2;+          }++          seg = seg->edge_next;++        } while ( seg != edge->first );++        /* set the round/straight flags */+        edge->flags = AF_EDGE_NORMAL;++        if ( is_round > 0 && is_round >= is_straight )+          edge->flags |= AF_EDGE_ROUND;++#if 0+        /* set the edge's main direction */+        edge->dir = AF_DIR_NONE;++        if ( ups > downs )+          edge->dir = (FT_Char)up_dir;++        else if ( ups < downs )+          edge->dir = (FT_Char)-up_dir;++        else if ( ups == downs )+          edge->dir = 0;  /* both up and down! */+#endif++        /* gets rid of serifs if link is set                */+        /* XXX: This gets rid of many unpleasant artefacts! */+        /*      Example: the `c' in cour.pfa at size 13     */++        if ( edge->serif && edge->link )+          edge->serif = 0;+      }+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin_hints_detect_features( AF_GlyphHints  hints,+                                  AF_Dimension   dim )+  {+    FT_Error  error;+++    error = af_latin_hints_compute_segments( hints, dim );+    if ( !error )+    {+      af_latin_hints_link_segments( hints, dim );++      error = af_latin_hints_compute_edges( hints, dim );+    }+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_latin_hints_compute_blue_edges( AF_GlyphHints    hints,+                                     AF_LatinMetrics  metrics )+  {+    AF_AxisHints  axis       = &hints->axis[ AF_DIMENSION_VERT ];+    AF_Edge       edge       = axis->edges;+    AF_Edge       edge_limit = edge + axis->num_edges;+    AF_LatinAxis  latin      = &metrics->axis[ AF_DIMENSION_VERT ];+    FT_Fixed      scale      = latin->scale;+++    /* compute which blue zones are active, i.e. have their scaled */+    /* size < 3/4 pixels                                           */++    /* for each horizontal edge search the blue zone which is closest */+    for ( ; edge < edge_limit; edge++ )+    {+      FT_Int    bb;+      AF_Width  best_blue = NULL;+      FT_Pos    best_dist;  /* initial threshold */+++      /* compute the initial threshold as a fraction of the EM size */+      best_dist = FT_MulFix( metrics->units_per_em / 40, scale );++      if ( best_dist > 64 / 2 )+        best_dist = 64 / 2;++      for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )+      {+        AF_LatinBlue  blue = latin->blues + bb;+        FT_Bool       is_top_blue, is_major_dir;+++        /* skip inactive blue zones (i.e., those that are too small) */+        if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )+          continue;++        /* if it is a top zone, check for right edges -- if it is a bottom */+        /* zone, check for left edges                                      */+        /*                                                                 */+        /* of course, that's for TrueType                                  */+        is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );+        is_major_dir = FT_BOOL( edge->dir == axis->major_dir );++        /* if it is a top zone, the edge must be against the major    */+        /* direction; if it is a bottom zone, it must be in the major */+        /* direction                                                  */+        if ( is_top_blue ^ is_major_dir )+        {+          FT_Pos  dist;+++          /* first of all, compare it to the reference position */+          dist = edge->fpos - blue->ref.org;+          if ( dist < 0 )+            dist = -dist;++          dist = FT_MulFix( dist, scale );+          if ( dist < best_dist )+          {+            best_dist = dist;+            best_blue = & blue->ref;+          }++          /* now, compare it to the overshoot position if the edge is     */+          /* rounded, and if the edge is over the reference position of a */+          /* top zone, or under the reference position of a bottom zone   */+          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )+          {+            FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );+++            if ( is_top_blue ^ is_under_ref )+            {+              blue = latin->blues + bb;+              dist = edge->fpos - blue->shoot.org;+              if ( dist < 0 )+                dist = -dist;++              dist = FT_MulFix( dist, scale );+              if ( dist < best_dist )+              {+                best_dist = dist;+                best_blue = & blue->shoot;+              }+            }+          }+        }+      }++      if ( best_blue )+        edge->blue_edge = best_blue;+    }+  }+++  static FT_Error+  af_latin_hints_init( AF_GlyphHints    hints,+                       AF_LatinMetrics  metrics )+  {+    FT_Render_Mode  mode;+    FT_UInt32       scaler_flags, other_flags;+    FT_Face         face = metrics->root.scaler.face;+++    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );++    /*+     *  correct x_scale and y_scale if needed, since they may have+     *  been modified `af_latin_metrics_scale_dim' above+     */+    hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;+    hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;+    hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;+    hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;++    /* compute flags depending on render mode, etc. */+    mode = metrics->root.scaler.render_mode;++#if 0 /* #ifdef AF_USE_WARPER */+    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )+    {+      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;+    }+#endif++    scaler_flags = hints->scaler_flags;+    other_flags  = 0;++    /*+     *  We snap the width of vertical stems for the monochrome and+     *  horizontal LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )+      other_flags |= AF_LATIN_HINTS_HORZ_SNAP;++    /*+     *  We snap the width of horizontal stems for the monochrome and+     *  vertical LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )+      other_flags |= AF_LATIN_HINTS_VERT_SNAP;++    /*+     *  We adjust stems to full pixels only if we don't use the `light' mode.+     */+    if ( mode != FT_RENDER_MODE_LIGHT )+      other_flags |= AF_LATIN_HINTS_STEM_ADJUST;++    if ( mode == FT_RENDER_MODE_MONO )+      other_flags |= AF_LATIN_HINTS_MONO;++    /*+     *  In `light' hinting mode we disable horizontal hinting completely.+     *  We also do it if the face is italic.+     */+    if ( mode == FT_RENDER_MODE_LIGHT                    ||+         (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 )+      scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;++    hints->scaler_flags = scaler_flags;+    hints->other_flags  = other_flags;++    return 0;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****        L A T I N   G L Y P H   G R I D - F I T T I N G        *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* snap a given width in scaled coordinates to one of the */+  /* current standard widths                                */++  static FT_Pos+  af_latin_snap_width( AF_Width  widths,+                       FT_Int    count,+                       FT_Pos    width )+  {+    int     n;+    FT_Pos  best      = 64 + 32 + 2;+    FT_Pos  reference = width;+    FT_Pos  scaled;+++    for ( n = 0; n < count; n++ )+    {+      FT_Pos  w;+      FT_Pos  dist;+++      w = widths[n].cur;+      dist = width - w;+      if ( dist < 0 )+        dist = -dist;+      if ( dist < best )+      {+        best      = dist;+        reference = w;+      }+    }++    scaled = FT_PIX_ROUND( reference );++    if ( width >= reference )+    {+      if ( width < scaled + 48 )+        width = reference;+    }+    else+    {+      if ( width > scaled - 48 )+        width = reference;+    }++    return width;+  }+++  /* compute the snapped width of a given stem */++  static FT_Pos+  af_latin_compute_stem_width( AF_GlyphHints  hints,+                               AF_Dimension   dim,+                               FT_Pos         width,+                               AF_Edge_Flags  base_flags,+                               AF_Edge_Flags  stem_flags )+  {+    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;+    AF_LatinAxis     axis     = & metrics->axis[dim];+    FT_Pos           dist     = width;+    FT_Int           sign     = 0;+    FT_Int           vertical = ( dim == AF_DIMENSION_VERT );+++    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||+          axis->extra_light                      )+      return width;++    if ( dist < 0 )+    {+      dist = -width;+      sign = 1;+    }++    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||+         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )+    {+      /* smooth hinting process: very lightly quantize the stem width */++      /* leave the widths of serifs alone */++      if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )+        goto Done_Width;++      else if ( ( base_flags & AF_EDGE_ROUND ) )+      {+        if ( dist < 80 )+          dist = 64;+      }+      else if ( dist < 56 )+        dist = 56;++      if ( axis->width_count > 0 )+      {+        FT_Pos  delta;+++        /* compare to standard width */+        delta = dist - axis->widths[0].cur;++        if ( delta < 0 )+          delta = -delta;++        if ( delta < 40 )+        {+          dist = axis->widths[0].cur;+          if ( dist < 48 )+            dist = 48;++          goto Done_Width;+        }++        if ( dist < 3 * 64 )+        {+          delta  = dist & 63;+          dist  &= -64;++          if ( delta < 10 )+            dist += delta;++          else if ( delta < 32 )+            dist += 10;++          else if ( delta < 54 )+            dist += 54;++          else+            dist += delta;+        }+        else+          dist = ( dist + 32 ) & ~63;+      }+    }+    else+    {+      /* strong hinting process: snap the stem width to integer pixels */+      FT_Pos  org_dist = dist;+++      dist = af_latin_snap_width( axis->widths, axis->width_count, dist );++      if ( vertical )+      {+        /* in the case of vertical hinting, always round */+        /* the stem heights to integer pixels            */++        if ( dist >= 64 )+          dist = ( dist + 16 ) & ~63;+        else+          dist = 64;+      }+      else+      {+        if ( AF_LATIN_HINTS_DO_MONO( hints ) )+        {+          /* monochrome horizontal hinting: snap widths to integer pixels */+          /* with a different threshold                                   */++          if ( dist < 64 )+            dist = 64;+          else+            dist = ( dist + 32 ) & ~63;+        }+        else+        {+          /* for horizontal anti-aliased hinting, we adopt a more subtle */+          /* approach: we strengthen small stems, round stems whose size */+          /* is between 1 and 2 pixels to an integer, otherwise nothing  */++          if ( dist < 48 )+            dist = ( dist + 64 ) >> 1;++          else if ( dist < 128 )+          {+            /* We only round to an integer width if the corresponding */+            /* distortion is less than 1/4 pixel.  Otherwise this     */+            /* makes everything worse since the diagonals, which are  */+            /* not hinted, appear a lot bolder or thinner than the    */+            /* vertical stems.                                        */++            FT_Pos  delta;+++            dist = ( dist + 22 ) & ~63;+            delta = dist - org_dist;+            if ( delta < 0 )+              delta = -delta;++            if (delta >= 16)+            {+              dist = org_dist;+              if ( dist < 48 )+                dist = ( dist + 64 ) >> 1;+            }+          }+          else+            /* round otherwise to prevent color fringes in LCD mode */+            dist = ( dist + 32 ) & ~63;+        }+      }+    }++  Done_Width:+    if ( sign )+      dist = -dist;++    return dist;+  }+++  /* align one stem edge relative to the previous stem edge */++  static void+  af_latin_align_linked_edge( AF_GlyphHints  hints,+                              AF_Dimension   dim,+                              AF_Edge        base_edge,+                              AF_Edge        stem_edge )+  {+    FT_Pos  dist = stem_edge->opos - base_edge->opos;++    FT_Pos  fitted_width = af_latin_compute_stem_width(+                             hints, dim, dist,+                             (AF_Edge_Flags)base_edge->flags,+                             (AF_Edge_Flags)stem_edge->flags );+++    stem_edge->pos = base_edge->pos + fitted_width;++    AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "+             "dist was %.2f, now %.2f\n",+             stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,+             stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));+  }+++  static void+  af_latin_align_serif_edge( AF_GlyphHints  hints,+                             AF_Edge        base,+                             AF_Edge        serif )+  {+    FT_UNUSED( hints );++    serif->pos = base->pos + (serif->opos - base->opos);+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                    E D G E   H I N T I N G                      ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( void )+  af_latin_hint_edges( AF_GlyphHints  hints,+                       AF_Dimension   dim )+  {+    AF_AxisHints  axis       = &hints->axis[dim];+    AF_Edge       edges      = axis->edges;+    AF_Edge       edge_limit = edges + axis->num_edges;+    FT_PtrDist    n_edges;+    AF_Edge       edge;+    AF_Edge       anchor     = 0;+    FT_Int        has_serifs = 0;+++    /* we begin by aligning all stems relative to the blue zone */+    /* if needed -- that's only for horizontal edges            */++    if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )+    {+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        AF_Width  blue;+        AF_Edge   edge1, edge2;+++        if ( edge->flags & AF_EDGE_DONE )+          continue;++        blue  = edge->blue_edge;+        edge1 = NULL;+        edge2 = edge->link;++        if ( blue )+        {+          edge1 = edge;+        }+        else if ( edge2 && edge2->blue_edge )+        {+          blue  = edge2->blue_edge;+          edge1 = edge2;+          edge2 = edge;+        }++        if ( !edge1 )+          continue;++        AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "+                 "was (%.2f)\n",+                 edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,+                 edge1->pos / 64.0 ));++        edge1->pos    = blue->fit;+        edge1->flags |= AF_EDGE_DONE;++        if ( edge2 && !edge2->blue_edge )+        {+          af_latin_align_linked_edge( hints, dim, edge1, edge2 );+          edge2->flags |= AF_EDGE_DONE;+        }++        if ( !anchor )+          anchor = edge;+      }+    }++    /* now we will align all stem edges, trying to maintain the */+    /* relative order of stems in the glyph                     */+    for ( edge = edges; edge < edge_limit; edge++ )+    {+      AF_Edge  edge2;+++      if ( edge->flags & AF_EDGE_DONE )+        continue;++      /* skip all non-stem edges */+      edge2 = edge->link;+      if ( !edge2 )+      {+        has_serifs++;+        continue;+      }++      /* now align the stem */++      /* this should not happen, but it's better to be safe */+      if ( edge2->blue_edge )+      {+        AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));++        af_latin_align_linked_edge( hints, dim, edge2, edge );+        edge->flags |= AF_EDGE_DONE;+        continue;+      }++      if ( !anchor )+      {+        FT_Pos  org_len, org_center, cur_len;+        FT_Pos  cur_pos1, error1, error2, u_off, d_off;+++        org_len = edge2->opos - edge->opos;+        cur_len = af_latin_compute_stem_width(+                    hints, dim, org_len,+                    (AF_Edge_Flags)edge->flags,+                    (AF_Edge_Flags)edge2->flags );+        if ( cur_len <= 64 )+          u_off = d_off = 32;+        else+        {+          u_off = 38;+          d_off = 26;+        }++        if ( cur_len < 96 )+        {+          org_center = edge->opos + ( org_len >> 1 );++          cur_pos1   = FT_PIX_ROUND( org_center );++          error1 = org_center - ( cur_pos1 - u_off );+          if ( error1 < 0 )+            error1 = -error1;++          error2 = org_center - ( cur_pos1 + d_off );+          if ( error2 < 0 )+            error2 = -error2;++          if ( error1 < error2 )+            cur_pos1 -= u_off;+          else+            cur_pos1 += d_off;++          edge->pos  = cur_pos1 - cur_len / 2;+          edge2->pos = edge->pos + cur_len;+        }+        else+          edge->pos = FT_PIX_ROUND( edge->opos );++        AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "+                 "snapped to (%.2f) (%.2f)\n",+                 edge-edges, edge->opos / 64.0,+                 edge2-edges, edge2->opos / 64.0,+                 edge->pos / 64.0, edge2->pos / 64.0 ));+        anchor = edge;++        edge->flags |= AF_EDGE_DONE;++        af_latin_align_linked_edge( hints, dim, edge, edge2 );+      }+      else+      {+        FT_Pos  org_pos, org_len, org_center, cur_len;+        FT_Pos  cur_pos1, cur_pos2, delta1, delta2;+++        org_pos    = anchor->pos + ( edge->opos - anchor->opos );+        org_len    = edge2->opos - edge->opos;+        org_center = org_pos + ( org_len >> 1 );++        cur_len = af_latin_compute_stem_width(+                   hints, dim, org_len,+                   (AF_Edge_Flags)edge->flags,+                   (AF_Edge_Flags)edge2->flags );++        if ( edge2->flags & AF_EDGE_DONE )+          edge->pos = edge2->pos - cur_len;++        else if ( cur_len < 96 )+        {+          FT_Pos  u_off, d_off;+++          cur_pos1 = FT_PIX_ROUND( org_center );++          if (cur_len <= 64 )+            u_off = d_off = 32;+          else+          {+            u_off = 38;+            d_off = 26;+          }++          delta1 = org_center - ( cur_pos1 - u_off );+          if ( delta1 < 0 )+            delta1 = -delta1;++          delta2 = org_center - ( cur_pos1 + d_off );+          if ( delta2 < 0 )+            delta2 = -delta2;++          if ( delta1 < delta2 )+            cur_pos1 -= u_off;+          else+            cur_pos1 += d_off;++          edge->pos  = cur_pos1 - cur_len / 2;+          edge2->pos = cur_pos1 + cur_len / 2;++          AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "+                   "snapped to (%.2f) and (%.2f)\n",+                   edge-edges, edge->opos / 64.0,+                   edge2-edges, edge2->opos / 64.0,+                   edge->pos / 64.0, edge2->pos / 64.0 ));+        }+        else+        {+          org_pos    = anchor->pos + ( edge->opos - anchor->opos );+          org_len    = edge2->opos - edge->opos;+          org_center = org_pos + ( org_len >> 1 );++          cur_len    = af_latin_compute_stem_width(+                         hints, dim, org_len,+                         (AF_Edge_Flags)edge->flags,+                         (AF_Edge_Flags)edge2->flags );++          cur_pos1   = FT_PIX_ROUND( org_pos );+          delta1     = cur_pos1 + ( cur_len >> 1 ) - org_center;+          if ( delta1 < 0 )+            delta1 = -delta1;++          cur_pos2   = FT_PIX_ROUND( org_pos + org_len ) - cur_len;+          delta2     = cur_pos2 + ( cur_len >> 1 ) - org_center;+          if ( delta2 < 0 )+            delta2 = -delta2;++          edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;+          edge2->pos = edge->pos + cur_len;++          AF_LOG(( "STEM: %d (opos=%.2f) to %d (opos=%.2f) "+                   "snapped to (%.2f) and (%.2f)\n",+                   edge-edges, edge->opos / 64.0,+                   edge2-edges, edge2->opos / 64.0,+                   edge->pos / 64.0, edge2->pos / 64.0 ));+        }++        edge->flags  |= AF_EDGE_DONE;+        edge2->flags |= AF_EDGE_DONE;++        if ( edge > edges && edge->pos < edge[-1].pos )+        {+          AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",+                   edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));+          edge->pos = edge[-1].pos;+        }+      }+    }++    /* make sure that lowercase m's maintain their symmetry */++    /* In general, lowercase m's have six vertical edges if they are sans */+    /* serif, or twelve if they are with serifs.  This implementation is  */+    /* based on that assumption, and seems to work very well with most    */+    /* faces.  However, if for a certain face this assumption is not      */+    /* true, the m is just rendered like before.  In addition, any stem   */+    /* correction will only be applied to symmetrical glyphs (even if the */+    /* glyph is not an m), so the potential for unwanted distortion is    */+    /* relatively low.                                                    */++    /* We don't handle horizontal edges since we can't easily assure that */+    /* the third (lowest) stem aligns with the base line; it might end up */+    /* one pixel higher or lower.                                         */++    n_edges = edge_limit - edges;+    if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )+    {+      AF_Edge  edge1, edge2, edge3;+      FT_Pos   dist1, dist2, span, delta;+++      if ( n_edges == 6 )+      {+        edge1 = edges;+        edge2 = edges + 2;+        edge3 = edges + 4;+      }+      else+      {+        edge1 = edges + 1;+        edge2 = edges + 5;+        edge3 = edges + 9;+      }++      dist1 = edge2->opos - edge1->opos;+      dist2 = edge3->opos - edge2->opos;++      span = dist1 - dist2;+      if ( span < 0 )+        span = -span;++      if ( span < 8 )+      {+        delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );+        edge3->pos -= delta;+        if ( edge3->link )+          edge3->link->pos -= delta;++        /* move the serifs along with the stem */+        if ( n_edges == 12 )+        {+          ( edges + 8 )->pos -= delta;+          ( edges + 11 )->pos -= delta;+        }++        edge3->flags |= AF_EDGE_DONE;+        if ( edge3->link )+          edge3->link->flags |= AF_EDGE_DONE;+      }+    }++    if ( has_serifs || !anchor )+    {+      /*+       *  now hint the remaining edges (serifs and single) in order+       *  to complete our processing+       */+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        FT_Pos  delta;+++        if ( edge->flags & AF_EDGE_DONE )+          continue;++        delta = 1000;++        if ( edge->serif )+        {+          delta = edge->serif->opos - edge->opos;+          if ( delta < 0 )+            delta = -delta;+        }++        if ( delta < 64 + 16 )+        {+          af_latin_align_serif_edge( hints, edge->serif, edge );+          AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "+                   "aligned to (%.2f)\n",+                   edge-edges, edge->opos / 64.0,+                   edge->serif - edges, edge->serif->opos / 64.0,+                   edge->pos / 64.0 ));+        }+        else if ( !anchor )+        {+          AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",+                   edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));+          edge->pos = FT_PIX_ROUND( edge->opos );+          anchor    = edge;+        }+        else+        {+          AF_Edge  before, after;+++          for ( before = edge - 1; before >= edges; before-- )+            if ( before->flags & AF_EDGE_DONE )+              break;++          for ( after = edge + 1; after < edge_limit; after++ )+            if ( after->flags & AF_EDGE_DONE )+              break;++          if ( before >= edges && before < edge   &&+               after < edge_limit && after > edge )+          {+            if ( after->opos == before->opos )+              edge->pos = before->pos;+            else+              edge->pos = before->pos ++                          FT_MulDiv( edge->opos - before->opos,+                                     after->pos - before->pos,+                                     after->opos - before->opos );+            AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) "+                     "from %d (opos=%.2f)\n",+                     edge-edges, edge->opos / 64.0,+                     edge->pos / 64.0, before - edges,+                     before->opos / 64.0 ));+          }+          else+          {+            edge->pos = anchor->pos ++                        ( ( edge->opos - anchor->opos + 16 ) & ~31 );+            AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n",+                     edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));+          }+        }++        edge->flags |= AF_EDGE_DONE;++        if ( edge > edges && edge->pos < edge[-1].pos )+          edge->pos = edge[-1].pos;++        if ( edge + 1 < edge_limit        &&+             edge[1].flags & AF_EDGE_DONE &&+             edge->pos > edge[1].pos      )+          edge->pos = edge[1].pos;+      }+    }+  }+++  static FT_Error+  af_latin_hints_apply( AF_GlyphHints    hints,+                        FT_Outline*      outline,+                        AF_LatinMetrics  metrics )+  {+    FT_Error  error;+    int       dim;+++    error = af_glyph_hints_reload( hints, outline );+    if ( error )+      goto Exit;++    /* analyze glyph outline */+#ifdef AF_USE_WARPER+    if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||+         AF_HINTS_DO_HORIZONTAL( hints ) )+#else+    if ( AF_HINTS_DO_HORIZONTAL( hints ) )+#endif+    {+      error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );+      if ( error )+        goto Exit;+    }++    if ( AF_HINTS_DO_VERTICAL( hints ) )+    {+      error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );+      if ( error )+        goto Exit;++      af_latin_hints_compute_blue_edges( hints, metrics );+    }++    /* grid-fit the outline */+    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+    {+#ifdef AF_USE_WARPER+      if ( ( dim == AF_DIMENSION_HORZ &&+             metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )+      {+        AF_WarperRec  warper;+        FT_Fixed      scale;+        FT_Pos        delta;+++        af_warper_compute( &warper, hints, dim, &scale, &delta );+        af_glyph_hints_scale_dim( hints, dim, scale, delta );+        continue;+      }+#endif++      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||+           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )+      {+        af_latin_hint_edges( hints, (AF_Dimension)dim );+        af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );+      }+    }+    af_glyph_hints_save( hints, outline );++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****              L A T I N   S C R I P T   C L A S S              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* XXX: this should probably fine tuned to differentiate better between */+  /*      scripts...                                                      */++  static const AF_Script_UniRangeRec  af_latin_uniranges[] =+  {+    AF_UNIRANGE_REC(  0x0020UL,  0x007FUL ),  /* Basic Latin (no control chars) */+    AF_UNIRANGE_REC(  0x00A0UL,  0x00FFUL ),  /* Latin-1 Supplement (no control chars) */+    AF_UNIRANGE_REC(  0x0100UL,  0x017FUL ),  /* Latin Extended-A */+    AF_UNIRANGE_REC(  0x0180UL,  0x024FUL ),  /* Latin Extended-B */+    AF_UNIRANGE_REC(  0x0250UL,  0x02AFUL ),  /* IPA Extensions */+    AF_UNIRANGE_REC(  0x02B0UL,  0x02FFUL ),  /* Spacing Modifier Letters */+    AF_UNIRANGE_REC(  0x0300UL,  0x036FUL ),  /* Combining Diacritical Marks */+    AF_UNIRANGE_REC(  0x0370UL,  0x03FFUL ),  /* Greek and Coptic */+    AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic */+    AF_UNIRANGE_REC(  0x0500UL,  0x052FUL ),  /* Cyrillic Supplement */+    AF_UNIRANGE_REC(  0x1D00UL,  0x1D7FUL ),  /* Phonetic Extensions */+    AF_UNIRANGE_REC(  0x1D80UL,  0x1DBFUL ),  /* Phonetic Extensions Supplement */+    AF_UNIRANGE_REC(  0x1DC0UL,  0x1DFFUL ),  /* Combining Diacritical Marks Supplement */+    AF_UNIRANGE_REC(  0x1E00UL,  0x1EFFUL ),  /* Latin Extended Additional */+    AF_UNIRANGE_REC(  0x1F00UL,  0x1FFFUL ),  /* Greek Extended */+    AF_UNIRANGE_REC(  0x2000UL,  0x206FUL ),  /* General Punctuation */+    AF_UNIRANGE_REC(  0x2070UL,  0x209FUL ),  /* Superscripts and Subscripts */+    AF_UNIRANGE_REC(  0x20A0UL,  0x20CFUL ),  /* Currency Symbols */+    AF_UNIRANGE_REC(  0x2150UL,  0x218FUL ),  /* Number Forms */+    AF_UNIRANGE_REC(  0x2460UL,  0x24FFUL ),  /* Enclosed Alphanumerics */+    AF_UNIRANGE_REC(  0x2C60UL,  0x2C7FUL ),  /* Latin Extended-C */+    AF_UNIRANGE_REC(  0x2DE0UL,  0x2DFFUL ),  /* Cyrillic Extended-A */+    AF_UNIRANGE_REC(  0xA640UL,  0xA69FUL ),  /* Cyrillic Extended-B */+    AF_UNIRANGE_REC(  0xA720UL,  0xA7FFUL ),  /* Latin Extended-D */+    AF_UNIRANGE_REC(  0xFB00UL,  0xFB06UL ),  /* Alphab. Present. Forms (Latin Ligs) */+    AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ),  /* Mathematical Alphanumeric Symbols */+    AF_UNIRANGE_REC(       0UL,       0UL )+  };+++  AF_DEFINE_SCRIPT_CLASS(af_latin_script_class,  +    AF_SCRIPT_LATIN,+    af_latin_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) af_latin_metrics_init,+    (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   af_latin_hints_init,+    (AF_Script_ApplyHintsFunc)  af_latin_hints_apply+  )+++/* END */
+ src/autofit/aflatin.h view
@@ -0,0 +1,212 @@+/***************************************************************************/+/*                                                                         */+/*  aflatin.h                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines for latin script (specification).       */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2009 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFLATIN_H__+#define __AFLATIN_H__++#include "afhints.h"+++FT_BEGIN_HEADER+++  /* the latin-specific script class */++  AF_DECLARE_SCRIPT_CLASS(af_latin_script_class)+++/* constants are given with units_per_em == 2048 in mind */+#define AF_LATIN_CONSTANT( metrics, c ) \+  ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****            L A T I N   G L O B A L   M E T R I C S            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /*+   *  The following declarations could be embedded in the file `aflatin.c';+   *  they have been made semi-public to allow alternate script hinters to+   *  re-use some of them.+   */+++  /* Latin (global) metrics management */++  enum+  {+    AF_LATIN_BLUE_CAPITAL_TOP,+    AF_LATIN_BLUE_CAPITAL_BOTTOM,+    AF_LATIN_BLUE_SMALL_F_TOP,+    AF_LATIN_BLUE_SMALL_TOP,+    AF_LATIN_BLUE_SMALL_BOTTOM,+    AF_LATIN_BLUE_SMALL_MINOR,++    AF_LATIN_BLUE_MAX+  };+++#define AF_LATIN_IS_TOP_BLUE( b )  ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \+                                     (b) == AF_LATIN_BLUE_SMALL_F_TOP || \+                                     (b) == AF_LATIN_BLUE_SMALL_TOP   )++#define AF_LATIN_MAX_WIDTHS  16+#define AF_LATIN_MAX_BLUES   AF_LATIN_BLUE_MAX+++  enum+  {+    AF_LATIN_BLUE_ACTIVE     = 1 << 0,+    AF_LATIN_BLUE_TOP        = 1 << 1,+    AF_LATIN_BLUE_ADJUSTMENT = 1 << 2,  /* used for scale adjustment */+                                        /* optimization              */+    AF_LATIN_BLUE_FLAG_MAX+  };+++  typedef struct  AF_LatinBlueRec_+  {+    AF_WidthRec  ref;+    AF_WidthRec  shoot;+    FT_UInt      flags;++  } AF_LatinBlueRec, *AF_LatinBlue;+++  typedef struct  AF_LatinAxisRec_+  {+    FT_Fixed         scale;+    FT_Pos           delta;++    FT_UInt          width_count;+    AF_WidthRec      widths[AF_LATIN_MAX_WIDTHS];+    FT_Pos           edge_distance_threshold;+    FT_Pos           standard_width;+    FT_Bool          extra_light;++    /* ignored for horizontal metrics */+    FT_Bool          control_overshoot;+    FT_UInt          blue_count;+    AF_LatinBlueRec  blues[AF_LATIN_BLUE_MAX];++    FT_Fixed         org_scale;+    FT_Pos           org_delta;++  } AF_LatinAxisRec, *AF_LatinAxis;+++  typedef struct  AF_LatinMetricsRec_+  {+    AF_ScriptMetricsRec  root;+    FT_UInt              units_per_em;+    AF_LatinAxisRec      axis[AF_DIMENSION_MAX];++  } AF_LatinMetricsRec, *AF_LatinMetrics;+++  FT_LOCAL( FT_Error )+  af_latin_metrics_init( AF_LatinMetrics  metrics,+                         FT_Face          face );++  FT_LOCAL( void )+  af_latin_metrics_scale( AF_LatinMetrics  metrics,+                          AF_Scaler        scaler );++  FT_LOCAL( void )+  af_latin_metrics_init_widths( AF_LatinMetrics  metrics,+                                FT_Face          face,+                                FT_ULong         charcode );++  FT_LOCAL( void )+  af_latin_metrics_check_digits( AF_LatinMetrics  metrics,+                                 FT_Face          face );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****           L A T I N   G L Y P H   A N A L Y S I S             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  enum+  {+    AF_LATIN_HINTS_HORZ_SNAP   = 1 << 0, /* enable stem width snapping  */+    AF_LATIN_HINTS_VERT_SNAP   = 1 << 1, /* enable stem height snapping */+    AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height    */+                                         /* adjustment                  */+    AF_LATIN_HINTS_MONO        = 1 << 3  /* indicate monochrome         */+                                         /* rendering                   */+  };+++#define AF_LATIN_HINTS_DO_HORZ_SNAP( h )             \+  AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_HORZ_SNAP )++#define AF_LATIN_HINTS_DO_VERT_SNAP( h )             \+  AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_VERT_SNAP )++#define AF_LATIN_HINTS_DO_STEM_ADJUST( h )             \+  AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_STEM_ADJUST )++#define AF_LATIN_HINTS_DO_MONO( h )             \+  AF_HINTS_TEST_OTHER( h, AF_LATIN_HINTS_MONO )+++  /*+   *  This shouldn't normally be exported.  However, other scripts might+   *  like to use this function as-is.+   */+  FT_LOCAL( FT_Error )+  af_latin_hints_compute_segments( AF_GlyphHints  hints,+                                   AF_Dimension   dim );++  /*+   *  This shouldn't normally be exported.  However, other scripts might+   *  want to use this function as-is.+   */+  FT_LOCAL( void )+  af_latin_hints_link_segments( AF_GlyphHints  hints,+                                AF_Dimension   dim );++  /*+   *  This shouldn't normally be exported.  However, other scripts might+   *  want to use this function as-is.+   */+  FT_LOCAL( FT_Error )+  af_latin_hints_compute_edges( AF_GlyphHints  hints,+                                AF_Dimension   dim );++  FT_LOCAL( FT_Error )+  af_latin_hints_detect_features( AF_GlyphHints  hints,+                                  AF_Dimension   dim );++/* */++FT_END_HEADER++#endif /* __AFLATIN_H__ */+++/* END */
+ src/autofit/aflatin2.c view
@@ -0,0 +1,2345 @@+/***************************************************************************/+/*                                                                         */+/*  aflatin.c                                                              */+/*                                                                         */+/*    Auto-fitter hinting routines for latin script (body).                */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by            */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include FT_ADVANCES_H++#include "aflatin.h"+#include "aflatin2.h"+#include "aferrors.h"+++#ifdef AF_USE_WARPER+#include "afwarp.h"+#endif++  FT_LOCAL_DEF( FT_Error )+  af_latin2_hints_compute_segments( AF_GlyphHints  hints,+                                   AF_Dimension   dim );++  FT_LOCAL_DEF( void )+  af_latin2_hints_link_segments( AF_GlyphHints  hints,+                                 AF_Dimension   dim );++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****            L A T I N   G L O B A L   M E T R I C S            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  af_latin2_metrics_init_widths( AF_LatinMetrics  metrics,+                                FT_Face          face,+                                FT_ULong         charcode )+  {+    /* scan the array of segments in each direction */+    AF_GlyphHintsRec  hints[1];+++    af_glyph_hints_init( hints, face->memory );++    metrics->axis[AF_DIMENSION_HORZ].width_count = 0;+    metrics->axis[AF_DIMENSION_VERT].width_count = 0;++    {+      FT_Error             error;+      FT_UInt              glyph_index;+      int                  dim;+      AF_LatinMetricsRec   dummy[1];+      AF_Scaler            scaler = &dummy->root.scaler;+++      glyph_index = FT_Get_Char_Index( face, charcode );+      if ( glyph_index == 0 )+        goto Exit;++      error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );+      if ( error || face->glyph->outline.n_points <= 0 )+        goto Exit;++      FT_ZERO( dummy );++      dummy->units_per_em = metrics->units_per_em;+      scaler->x_scale     = scaler->y_scale = 0x10000L;+      scaler->x_delta     = scaler->y_delta = 0;+      scaler->face        = face;+      scaler->render_mode = FT_RENDER_MODE_NORMAL;+      scaler->flags       = 0;++      af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );++      error = af_glyph_hints_reload( hints, &face->glyph->outline );+      if ( error )+        goto Exit;++      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+      {+        AF_LatinAxis  axis    = &metrics->axis[dim];+        AF_AxisHints  axhints = &hints->axis[dim];+        AF_Segment    seg, limit, link;+        FT_UInt       num_widths = 0;+++        error = af_latin2_hints_compute_segments( hints,+                                                 (AF_Dimension)dim );+        if ( error )+          goto Exit;++        af_latin2_hints_link_segments( hints,+                                      (AF_Dimension)dim );++        seg   = axhints->segments;+        limit = seg + axhints->num_segments;++        for ( ; seg < limit; seg++ )+        {+          link = seg->link;++          /* we only consider stem segments there! */+          if ( link && link->link == seg && link > seg )+          {+            FT_Pos  dist;+++            dist = seg->pos - link->pos;+            if ( dist < 0 )+              dist = -dist;++            if ( num_widths < AF_LATIN_MAX_WIDTHS )+              axis->widths[ num_widths++ ].org = dist;+          }+        }++        af_sort_widths( num_widths, axis->widths );+        axis->width_count = num_widths;+      }++  Exit:+      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+      {+        AF_LatinAxis  axis = &metrics->axis[dim];+        FT_Pos        stdw;+++        stdw = ( axis->width_count > 0 )+                 ? axis->widths[0].org+                 : AF_LATIN_CONSTANT( metrics, 50 );++        /* let's try 20% of the smallest width */+        axis->edge_distance_threshold = stdw / 5;+        axis->standard_width          = stdw;+        axis->extra_light             = 0;+      }+    }++    af_glyph_hints_done( hints );+  }++++#define AF_LATIN_MAX_TEST_CHARACTERS  12+++  static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] =+  {+    "THEZOCQS",+    "HEZLOCUS",+    "fijkdbh",+    "xzroesc",+    "xzroesc",+    "pqgjy"+  };+++  static void+  af_latin2_metrics_init_blues( AF_LatinMetrics  metrics,+                               FT_Face          face )+  {+    FT_Pos        flats [AF_LATIN_MAX_TEST_CHARACTERS];+    FT_Pos        rounds[AF_LATIN_MAX_TEST_CHARACTERS];+    FT_Int        num_flats;+    FT_Int        num_rounds;+    FT_Int        bb;+    AF_LatinBlue  blue;+    FT_Error      error;+    AF_LatinAxis  axis  = &metrics->axis[AF_DIMENSION_VERT];+    FT_GlyphSlot  glyph = face->glyph;+++    /* we compute the blues simply by loading each character from the    */+    /* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */+    /* bottom-most points (depending on `AF_IS_TOP_BLUE')                */++    AF_LOG(( "blue zones computation\n" ));+    AF_LOG(( "------------------------------------------------\n" ));++    for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )+    {+      const char*  p     = af_latin2_blue_chars[bb];+      const char*  limit = p + AF_LATIN_MAX_TEST_CHARACTERS;+      FT_Pos*      blue_ref;+      FT_Pos*      blue_shoot;+++      AF_LOG(( "blue %3d: ", bb ));++      num_flats  = 0;+      num_rounds = 0;++      for ( ; p < limit && *p; p++ )+      {+        FT_UInt     glyph_index;+        FT_Int      best_point, best_y, best_first, best_last;+        FT_Vector*  points;+        FT_Bool     round;+++        AF_LOG(( "'%c'", *p ));++        /* load the character in the face -- skip unknown or empty ones */+        glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );+        if ( glyph_index == 0 )+          continue;++        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );+        if ( error || glyph->outline.n_points <= 0 )+          continue;++        /* now compute min or max point indices and coordinates */+        points      = glyph->outline.points;+        best_point  = -1;+        best_y      = 0;  /* make compiler happy */+        best_first  = 0;  /* ditto */+        best_last   = 0;  /* ditto */++        {+          FT_Int  nn;+          FT_Int  first = 0;+          FT_Int  last  = -1;+++          for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ )+          {+            FT_Int  old_best_point = best_point;+            FT_Int  pp;+++            last = glyph->outline.contours[nn];++            /* Avoid single-point contours since they are never rasterized. */+            /* In some fonts, they correspond to mark attachment points     */+            /* which are way outside of the glyph's real outline.           */+            if ( last == first )+                continue;++            if ( AF_LATIN_IS_TOP_BLUE( bb ) )+            {+              for ( pp = first; pp <= last; pp++ )+                if ( best_point < 0 || points[pp].y > best_y )+                {+                  best_point = pp;+                  best_y     = points[pp].y;+                }+            }+            else+            {+              for ( pp = first; pp <= last; pp++ )+                if ( best_point < 0 || points[pp].y < best_y )+                {+                  best_point = pp;+                  best_y     = points[pp].y;+                }+            }++            if ( best_point != old_best_point )+            {+              best_first = first;+              best_last  = last;+            }+          }+          AF_LOG(( "%5d", best_y ));+        }++        /* now check whether the point belongs to a straight or round   */+        /* segment; we first need to find in which contour the extremum */+        /* lies, then inspect its previous and next points              */+        {+          FT_Int  start, end, prev, next;+          FT_Pos  dist;+++          /* now look for the previous and next points that are not on the */+          /* same Y coordinate.  Threshold the `closeness'...              */+          start = end = best_point;++          do+          {+            prev = start-1;+            if ( prev < best_first )+              prev = best_last;++            dist = points[prev].y - best_y;+            if ( dist < -5 || dist > 5 )+              break;++            start = prev;++          } while ( start != best_point );++          do+          {+            next = end+1;+            if ( next > best_last )+              next = best_first;++            dist = points[next].y - best_y;+            if ( dist < -5 || dist > 5 )+              break;++            end = next;++          } while ( end != best_point );++          /* now, set the `round' flag depending on the segment's kind */+          round = FT_BOOL(+            FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON ||+            FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON );++          AF_LOG(( "%c ", round ? 'r' : 'f' ));+        }++        if ( round )+          rounds[num_rounds++] = best_y;+        else+          flats[num_flats++]   = best_y;+      }++      AF_LOG(( "\n" ));++      if ( num_flats == 0 && num_rounds == 0 )+      {+        /*+         *  we couldn't find a single glyph to compute this blue zone,+         *  we will simply ignore it then+         */+        AF_LOG(( "empty\n" ));+        continue;+      }++      /* we have computed the contents of the `rounds' and `flats' tables, */+      /* now determine the reference and overshoot position of the blue -- */+      /* we simply take the median value after a simple sort               */+      af_sort_pos( num_rounds, rounds );+      af_sort_pos( num_flats,  flats );++      blue       = & axis->blues[axis->blue_count];+      blue_ref   = & blue->ref.org;+      blue_shoot = & blue->shoot.org;++      axis->blue_count++;++      if ( num_flats == 0 )+      {+        *blue_ref   =+        *blue_shoot = rounds[num_rounds / 2];+      }+      else if ( num_rounds == 0 )+      {+        *blue_ref   =+        *blue_shoot = flats[num_flats / 2];+      }+      else+      {+        *blue_ref   = flats[num_flats / 2];+        *blue_shoot = rounds[num_rounds / 2];+      }++      /* there are sometimes problems: if the overshoot position of top     */+      /* zones is under its reference position, or the opposite for bottom  */+      /* zones.  We must thus check everything there and correct the errors */+      if ( *blue_shoot != *blue_ref )+      {+        FT_Pos   ref      = *blue_ref;+        FT_Pos   shoot    = *blue_shoot;+        FT_Bool  over_ref = FT_BOOL( shoot > ref );+++        if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )+          *blue_shoot = *blue_ref = ( shoot + ref ) / 2;+      }++      blue->flags = 0;+      if ( AF_LATIN_IS_TOP_BLUE( bb ) )+        blue->flags |= AF_LATIN_BLUE_TOP;++      /*+       * The following flags is used later to adjust the y and x scales+       * in order to optimize the pixel grid alignment of the top of small+       * letters.+       */+      if ( bb == AF_LATIN_BLUE_SMALL_TOP )+        blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;++      AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));+    }++    return;+  }+++  FT_LOCAL_DEF( void )+  af_latin2_metrics_check_digits( AF_LatinMetrics  metrics,+                                  FT_Face          face )+  {+    FT_UInt   i;+    FT_Bool   started = 0, same_width = 1;+    FT_Fixed  advance, old_advance = 0;+++    /* check whether all ASCII digits have the same advance width; */+    /* digit `0' is 0x30 in all supported charmaps                 */+    for ( i = 0x30; i <= 0x39; i++ )+    {+      FT_UInt  glyph_index;+++      glyph_index = FT_Get_Char_Index( face, i );+      if ( glyph_index == 0 )+        continue;++      if ( FT_Get_Advance( face, glyph_index,+                           FT_LOAD_NO_SCALE         |+                           FT_LOAD_NO_HINTING       |+                           FT_LOAD_IGNORE_TRANSFORM,+                           &advance ) )+        continue;++      if ( started )+      {+        if ( advance != old_advance )+        {+          same_width = 0;+          break;+        }+      }+      else+      {+        old_advance = advance;+        started     = 1;+      }+    }++    metrics->root.digits_have_same_width = same_width;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin2_metrics_init( AF_LatinMetrics  metrics,+                         FT_Face          face )+  {+    FT_Error    error = AF_Err_Ok;+    FT_CharMap  oldmap = face->charmap;+    FT_UInt     ee;++    static const FT_Encoding  latin_encodings[] =+    {+      FT_ENCODING_UNICODE,+      FT_ENCODING_APPLE_ROMAN,+      FT_ENCODING_ADOBE_STANDARD,+      FT_ENCODING_ADOBE_LATIN_1,+      FT_ENCODING_NONE  /* end of list */+    };+++    metrics->units_per_em = face->units_per_EM;++    /* do we have a latin charmap in there? */+    for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )+    {+      error = FT_Select_Charmap( face, latin_encodings[ee] );+      if ( !error )+        break;+    }++    if ( !error )+    {+      /* For now, compute the standard width and height from the `o'. */+      af_latin2_metrics_init_widths( metrics, face, 'o' );+      af_latin2_metrics_init_blues( metrics, face );+      af_latin2_metrics_check_digits( metrics, face );+    }++    FT_Set_Charmap( face, oldmap );+    return AF_Err_Ok;+  }+++  static void+  af_latin2_metrics_scale_dim( AF_LatinMetrics  metrics,+                              AF_Scaler        scaler,+                              AF_Dimension     dim )+  {+    FT_Fixed      scale;+    FT_Pos        delta;+    AF_LatinAxis  axis;+    FT_UInt       nn;+++    if ( dim == AF_DIMENSION_HORZ )+    {+      scale = scaler->x_scale;+      delta = scaler->x_delta;+    }+    else+    {+      scale = scaler->y_scale;+      delta = scaler->y_delta;+    }++    axis = &metrics->axis[dim];++    if ( axis->org_scale == scale && axis->org_delta == delta )+      return;++    axis->org_scale = scale;+    axis->org_delta = delta;++    /*+     * correct Y scale to optimize the alignment of the top of small+     * letters to the pixel grid+     */+    if ( dim == AF_DIMENSION_VERT )+    {+      AF_LatinAxis  vaxis = &metrics->axis[AF_DIMENSION_VERT];+      AF_LatinBlue  blue = NULL;+++      for ( nn = 0; nn < vaxis->blue_count; nn++ )+      {+        if ( vaxis->blues[nn].flags & AF_LATIN_BLUE_ADJUSTMENT )+        {+          blue = &vaxis->blues[nn];+          break;+        }+      }++      if ( blue )+      {+        FT_Pos  scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );+        FT_Pos  fitted = ( scaled + 40 ) & ~63;++#if 1+        if ( scaled != fitted )+        {+          scale = FT_MulDiv( scale, fitted, scaled );+          AF_LOG(( "== scaled x-top = %.2g  fitted = %.2g, scaling = %.4g\n", scaled/64.0, fitted/64.0, (fitted*1.0)/scaled ));+        }+#endif+      }+    }++    axis->scale = scale;+    axis->delta = delta;++    if ( dim == AF_DIMENSION_HORZ )+    {+      metrics->root.scaler.x_scale = scale;+      metrics->root.scaler.x_delta = delta;+    }+    else+    {+      metrics->root.scaler.y_scale = scale;+      metrics->root.scaler.y_delta = delta;+    }++    /* scale the standard widths */+    for ( nn = 0; nn < axis->width_count; nn++ )+    {+      AF_Width  width = axis->widths + nn;+++      width->cur = FT_MulFix( width->org, scale );+      width->fit = width->cur;+    }++    /* an extra-light axis corresponds to a standard width that is */+    /* smaller than 0.75 pixels                                    */+    axis->extra_light =+      (FT_Bool)( FT_MulFix( axis->standard_width, scale ) < 32 + 8 );++    if ( dim == AF_DIMENSION_VERT )+    {+      /* scale the blue zones */+      for ( nn = 0; nn < axis->blue_count; nn++ )+      {+        AF_LatinBlue  blue = &axis->blues[nn];+        FT_Pos        dist;+++        blue->ref.cur   = FT_MulFix( blue->ref.org, scale ) + delta;+        blue->ref.fit   = blue->ref.cur;+        blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta;+        blue->shoot.fit = blue->shoot.cur;+        blue->flags    &= ~AF_LATIN_BLUE_ACTIVE;++        /* a blue zone is only active if it is less than 3/4 pixels tall */+        dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );+        if ( dist <= 48 && dist >= -48 )+        {+          FT_Pos  delta1, delta2;++          delta1 = blue->shoot.org - blue->ref.org;+          delta2 = delta1;+          if ( delta1 < 0 )+            delta2 = -delta2;++          delta2 = FT_MulFix( delta2, scale );++          if ( delta2 < 32 )+            delta2 = 0;+          else if ( delta2 < 64 )+            delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 );+          else+            delta2 = FT_PIX_ROUND( delta2 );++          if ( delta1 < 0 )+            delta2 = -delta2;++          blue->ref.fit   = FT_PIX_ROUND( blue->ref.cur );+          blue->shoot.fit = blue->ref.fit + delta2;++          AF_LOG(( ">> activating blue zone %d:  ref.cur=%.2g ref.fit=%.2g shoot.cur=%.2g shoot.fit=%.2g\n",+                   nn, blue->ref.cur/64.0, blue->ref.fit/64.0,+                   blue->shoot.cur/64.0, blue->shoot.fit/64.0 ));++          blue->flags |= AF_LATIN_BLUE_ACTIVE;+        }+      }+    }+  }+++  FT_LOCAL_DEF( void )+  af_latin2_metrics_scale( AF_LatinMetrics  metrics,+                          AF_Scaler        scaler )+  {+    metrics->root.scaler.render_mode = scaler->render_mode;+    metrics->root.scaler.face        = scaler->face;++    af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );+    af_latin2_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****           L A T I N   G L Y P H   A N A L Y S I S             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#define  SORT_SEGMENTS++  FT_LOCAL_DEF( FT_Error )+  af_latin2_hints_compute_segments( AF_GlyphHints  hints,+                                   AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    FT_Memory     memory        = hints->memory;+    FT_Error      error         = AF_Err_Ok;+    AF_Segment    segment       = NULL;+    AF_SegmentRec seg0;+    AF_Point*     contour       = hints->contours;+    AF_Point*     contour_limit = contour + hints->num_contours;+    AF_Direction  major_dir, segment_dir;+++    FT_ZERO( &seg0 );+    seg0.score = 32000;+    seg0.flags = AF_EDGE_NORMAL;++    major_dir   = (AF_Direction)FT_ABS( axis->major_dir );+    segment_dir = major_dir;++    axis->num_segments = 0;++    /* set up (u,v) in each point */+    if ( dim == AF_DIMENSION_HORZ )+    {+      AF_Point  point = hints->points;+      AF_Point  limit = point + hints->num_points;+++      for ( ; point < limit; point++ )+      {+        point->u = point->fx;+        point->v = point->fy;+      }+    }+    else+    {+      AF_Point  point = hints->points;+      AF_Point  limit = point + hints->num_points;+++      for ( ; point < limit; point++ )+      {+        point->u = point->fy;+        point->v = point->fx;+      }+    }++    /* do each contour separately */+    for ( ; contour < contour_limit; contour++ )+    {+      AF_Point  point   =  contour[0];+      AF_Point  start   =  point;+      AF_Point  last    =  point->prev;+++      if ( point == last )  /* skip singletons -- just in case */+        continue;++      /* already on an edge ?, backtrack to find its start */+      if ( FT_ABS( point->in_dir ) == major_dir )+      {+        point = point->prev;++        while ( point->in_dir == start->in_dir )+          point = point->prev;+      }+      else  /* otherwise, find first segment start, if any */+      {+        while ( FT_ABS( point->out_dir ) != major_dir )+        {+          point = point->next;++          if ( point == start )+            goto NextContour;+        }+      }++      start = point;++      for  (;;)+      {+        AF_Point  first;+        FT_Pos    min_u, min_v, max_u, max_v;++        /* we're at the start of a new segment */+        FT_ASSERT( FT_ABS( point->out_dir ) == major_dir &&+                           point->in_dir != point->out_dir );+        first = point;++        min_u = max_u = point->u;+        min_v = max_v = point->v;++        point = point->next;++        while ( point->out_dir == first->out_dir )+        {+          point = point->next;++          if ( point->u < min_u )+            min_u = point->u;++          if ( point->u > max_u )+            max_u = point->u;+        }++        if ( point->v < min_v )+          min_v = point->v;++        if ( point->v > max_v )+          max_v = point->v;++        /* record new segment */+        error = af_axis_hints_new_segment( axis, memory, &segment );+        if ( error )+          goto Exit;++        segment[0]         = seg0;+        segment->dir       = first->out_dir;+        segment->first     = first;+        segment->last      = point;+        segment->contour   = contour;+        segment->pos       = (FT_Short)(( min_u + max_u ) >> 1);+        segment->min_coord = (FT_Short) min_v;+        segment->max_coord = (FT_Short) max_v;+        segment->height    = (FT_Short)(max_v - min_v);++        /* a segment is round if it doesn't have successive */+        /* on-curve points.                                 */+        {+          AF_Point  pt   = first;+          AF_Point  last = point;+          AF_Flags  f0   = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);+          AF_Flags  f1;+++          segment->flags &= ~AF_EDGE_ROUND;++          for ( ; pt != last; f0 = f1 )+          {+            pt = pt->next;+            f1 = (AF_Flags)(pt->flags & AF_FLAG_CONTROL);++            if ( !f0 && !f1 )+              break;++            if ( pt == last )+              segment->flags |= AF_EDGE_ROUND;+          }+        }++       /* this can happen in the case of a degenerate contour+        * e.g. a 2-point vertical contour+        */+        if ( point == start )+          break;++        /* jump to the start of the next segment, if any */+        while ( FT_ABS(point->out_dir) != major_dir )+        {+          point = point->next;++          if ( point == start )+            goto NextContour;+        }+      }++    NextContour:+      ;+    } /* contours */++    /* now slightly increase the height of segments when this makes */+    /* sense -- this is used to better detect and ignore serifs     */+    {+      AF_Segment  segments     = axis->segments;+      AF_Segment  segments_end = segments + axis->num_segments;+++      for ( segment = segments; segment < segments_end; segment++ )+      {+        AF_Point  first   = segment->first;+        AF_Point  last    = segment->last;+        AF_Point  p;+        FT_Pos    first_v = first->v;+        FT_Pos    last_v  = last->v;+++        if ( first == last )+          continue;++        if ( first_v < last_v )+        {+          p = first->prev;+          if ( p->v < first_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( first_v - p->v ) >> 1 ) );++          p = last->next;+          if ( p->v > last_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( p->v - last_v ) >> 1 ) );+        }+        else+        {+          p = first->prev;+          if ( p->v > first_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( p->v - first_v ) >> 1 ) );++          p = last->next;+          if ( p->v < last_v )+            segment->height = (FT_Short)( segment->height ++                                          ( ( last_v - p->v ) >> 1 ) );+        }+      }+    }++#ifdef AF_SORT_SEGMENTS+   /* place all segments with a negative direction to the start+    * of the array, used to speed up segment linking later...+    */+    {+      AF_Segment  segments = axis->segments;+      FT_UInt     count    = axis->num_segments;+      FT_UInt     ii, jj;++      for (ii = 0; ii < count; ii++)+      {+        if ( segments[ii].dir > 0 )+        {+          for (jj = ii+1; jj < count; jj++)+          {+            if ( segments[jj].dir < 0 )+            {+              AF_SegmentRec  tmp;++              tmp          = segments[ii];+              segments[ii] = segments[jj];+              segments[jj] = tmp;++              break;+            }+          }++          if ( jj == count )+            break;+        }+      }+      axis->mid_segments = ii;+    }+#endif++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_latin2_hints_link_segments( AF_GlyphHints  hints,+                                AF_Dimension   dim )+  {+    AF_AxisHints  axis          = &hints->axis[dim];+    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+#ifdef AF_SORT_SEGMENTS+    AF_Segment    segment_mid   = segments + axis->mid_segments;+#endif+    FT_Pos        len_threshold, len_score;+    AF_Segment    seg1, seg2;+++    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );+    if ( len_threshold == 0 )+      len_threshold = 1;++    len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );++#ifdef AF_SORT_SEGMENTS+    for ( seg1 = segments; seg1 < segment_mid; seg1++ )+    {+      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )+        continue;++      for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ )+#else+    /* now compare each segment to the others */+    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      /* the fake segments are introduced to hint the metrics -- */+      /* we must never link them to anything                     */+      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )+        continue;++      for ( seg2 = segments; seg2 < segment_limit; seg2++ )+        if ( seg1->dir + seg2->dir == 0 && seg2->pos > seg1->pos )+#endif+        {+          FT_Pos  pos1 = seg1->pos;+          FT_Pos  pos2 = seg2->pos;+          FT_Pos  dist = pos2 - pos1;+++          if ( dist < 0 )+            continue;++          {+            FT_Pos  min = seg1->min_coord;+            FT_Pos  max = seg1->max_coord;+            FT_Pos  len, score;+++            if ( min < seg2->min_coord )+              min = seg2->min_coord;++            if ( max > seg2->max_coord )+              max = seg2->max_coord;++            len = max - min;+            if ( len >= len_threshold )+            {+              score = dist + len_score / len;+              if ( score < seg1->score )+              {+                seg1->score = score;+                seg1->link  = seg2;+              }++              if ( score < seg2->score )+              {+                seg2->score = score;+                seg2->link  = seg1;+              }+            }+          }+        }+    }+#if 0+    }+#endif++    /* now, compute the `serif' segments */+    for ( seg1 = segments; seg1 < segment_limit; seg1++ )+    {+      seg2 = seg1->link;++      if ( seg2 )+      {+        if ( seg2->link != seg1 )+        {+          seg1->link  = 0;+          seg1->serif = seg2->link;+        }+      }+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin2_hints_compute_edges( AF_GlyphHints  hints,+                                AF_Dimension   dim )+  {+    AF_AxisHints  axis   = &hints->axis[dim];+    FT_Error      error  = AF_Err_Ok;+    FT_Memory     memory = hints->memory;+    AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];++    AF_Segment    segments      = axis->segments;+    AF_Segment    segment_limit = segments + axis->num_segments;+    AF_Segment    seg;++    AF_Direction  up_dir;+    FT_Fixed      scale;+    FT_Pos        edge_distance_threshold;+    FT_Pos        segment_length_threshold;+++    axis->num_edges = 0;++    scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale+                                         : hints->y_scale;++    up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP+                                          : AF_DIR_RIGHT;++    /*+     *  We want to ignore very small (mostly serif) segments, we do that+     *  by ignoring those that whose length is less than a given fraction+     *  of the standard width. If there is no standard width, we ignore+     *  those that are less than a given size in pixels+     *+     *  also, unlink serif segments that are linked to segments farther+     *  than 50% of the standard width+     */+    if ( dim == AF_DIMENSION_HORZ )+    {+      if ( laxis->width_count > 0 )+        segment_length_threshold = (laxis->standard_width * 10 ) >> 4;+      else+        segment_length_threshold = FT_DivFix( 64, hints->y_scale );+    }+    else+      segment_length_threshold = 0;++    /*********************************************************************/+    /*                                                                   */+    /* We will begin by generating a sorted table of edges for the       */+    /* current direction.  To do so, we simply scan each segment and try */+    /* to find an edge in our table that corresponds to its position.    */+    /*                                                                   */+    /* If no edge is found, we create and insert a new edge in the       */+    /* sorted table.  Otherwise, we simply add the segment to the edge's */+    /* list which will be processed in the second step to compute the    */+    /* edge's properties.                                                */+    /*                                                                   */+    /* Note that the edges table is sorted along the segment/edge        */+    /* position.                                                         */+    /*                                                                   */+    /*********************************************************************/++    edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,+                                         scale );+    if ( edge_distance_threshold > 64 / 4 )+      edge_distance_threshold = 64 / 4;++    edge_distance_threshold = FT_DivFix( edge_distance_threshold,+                                         scale );++    for ( seg = segments; seg < segment_limit; seg++ )+    {+      AF_Edge  found = 0;+      FT_Int   ee;+++      if ( seg->height < segment_length_threshold )+        continue;++      /* A special case for serif edges: If they are smaller than */+      /* 1.5 pixels we ignore them.                               */+      if ( seg->serif )+      {+        FT_Pos  dist = seg->serif->pos - seg->pos;++        if (dist < 0)+          dist = -dist;++        if (dist >= laxis->standard_width >> 1)+        {+          /* unlink this serif, it is too distant from its reference stem */+          seg->serif = NULL;+        }+        else if ( 2*seg->height < 3 * segment_length_threshold )+          continue;+      }++      /* look for an edge corresponding to the segment */+      for ( ee = 0; ee < axis->num_edges; ee++ )+      {+        AF_Edge  edge = axis->edges + ee;+        FT_Pos   dist;+++        dist = seg->pos - edge->fpos;+        if ( dist < 0 )+          dist = -dist;++        if ( dist < edge_distance_threshold && edge->dir == seg->dir )+        {+          found = edge;+          break;+        }+      }++      if ( !found )+      {+        AF_Edge   edge;+++        /* insert a new edge in the list and */+        /* sort according to the position    */+        error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, memory, &edge );+        if ( error )+          goto Exit;++        /* add the segment to the new edge's list */+        FT_ZERO( edge );++        edge->first    = seg;+        edge->last     = seg;+        edge->fpos     = seg->pos;+        edge->dir      = seg->dir;+        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );+        seg->edge_next = seg;+      }+      else+      {+        /* if an edge was found, simply add the segment to the edge's */+        /* list                                                       */+        seg->edge_next         = found->first;+        found->last->edge_next = seg;+        found->last            = seg;+      }+    }+++    /*********************************************************************/+    /*                                                                   */+    /* Good, we will now compute each edge's properties according to     */+    /* segments found on its position.  Basically, these are:            */+    /*                                                                   */+    /*  - edge's main direction                                          */+    /*  - stem edge, serif edge or both (which defaults to stem then)    */+    /*  - rounded edge, straight or both (which defaults to straight)    */+    /*  - link for edge                                                  */+    /*                                                                   */+    /*********************************************************************/++    /* first of all, set the `edge' field in each segment -- this is */+    /* required in order to compute edge links                       */++    /*+     * Note that removing this loop and setting the `edge' field of each+     * segment directly in the code above slows down execution speed for+     * some reasons on platforms like the Sun.+     */+    {+      AF_Edge  edges      = axis->edges;+      AF_Edge  edge_limit = edges + axis->num_edges;+      AF_Edge  edge;+++      for ( edge = edges; edge < edge_limit; edge++ )+      {+        seg = edge->first;+        if ( seg )+          do+          {+            seg->edge = edge;+            seg       = seg->edge_next;++          } while ( seg != edge->first );+      }++      /* now, compute each edge properties */+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        FT_Int  is_round    = 0;  /* does it contain round segments?    */+        FT_Int  is_straight = 0;  /* does it contain straight segments? */+        FT_Pos  ups         = 0;  /* number of upwards segments         */+        FT_Pos  downs       = 0;  /* number of downwards segments       */+++        seg = edge->first;++        do+        {+          FT_Bool  is_serif;+++          /* check for roundness of segment */+          if ( seg->flags & AF_EDGE_ROUND )+            is_round++;+          else+            is_straight++;++          /* check for segment direction */+          if ( seg->dir == up_dir )+            ups   += seg->max_coord-seg->min_coord;+          else+            downs += seg->max_coord-seg->min_coord;++          /* check for links -- if seg->serif is set, then seg->link must */+          /* be ignored                                                   */+          is_serif = (FT_Bool)( seg->serif               &&+                                seg->serif->edge         &&+                                seg->serif->edge != edge );++          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )+          {+            AF_Edge     edge2;+            AF_Segment  seg2;+++            edge2 = edge->link;+            seg2  = seg->link;++            if ( is_serif )+            {+              seg2  = seg->serif;+              edge2 = edge->serif;+            }++            if ( edge2 )+            {+              FT_Pos  edge_delta;+              FT_Pos  seg_delta;+++              edge_delta = edge->fpos - edge2->fpos;+              if ( edge_delta < 0 )+                edge_delta = -edge_delta;++              seg_delta = seg->pos - seg2->pos;+              if ( seg_delta < 0 )+                seg_delta = -seg_delta;++              if ( seg_delta < edge_delta )+                edge2 = seg2->edge;+            }+            else+              edge2 = seg2->edge;++            if ( is_serif )+            {+              edge->serif   = edge2;+              edge2->flags |= AF_EDGE_SERIF;+            }+            else+              edge->link  = edge2;+          }++          seg = seg->edge_next;++        } while ( seg != edge->first );++        /* set the round/straight flags */+        edge->flags = AF_EDGE_NORMAL;++        if ( is_round > 0 && is_round >= is_straight )+          edge->flags |= AF_EDGE_ROUND;++#if 0+        /* set the edge's main direction */+        edge->dir = AF_DIR_NONE;++        if ( ups > downs )+          edge->dir = (FT_Char)up_dir;++        else if ( ups < downs )+          edge->dir = (FT_Char)-up_dir;++        else if ( ups == downs )+          edge->dir = 0;  /* both up and down! */+#endif++        /* gets rid of serifs if link is set                */+        /* XXX: This gets rid of many unpleasant artefacts! */+        /*      Example: the `c' in cour.pfa at size 13     */++        if ( edge->serif && edge->link )+          edge->serif = 0;+      }+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_latin2_hints_detect_features( AF_GlyphHints  hints,+                                  AF_Dimension   dim )+  {+    FT_Error  error;+++    error = af_latin2_hints_compute_segments( hints, dim );+    if ( !error )+    {+      af_latin2_hints_link_segments( hints, dim );++      error = af_latin2_hints_compute_edges( hints, dim );+    }+    return error;+  }+++  FT_LOCAL_DEF( void )+  af_latin2_hints_compute_blue_edges( AF_GlyphHints    hints,+                                     AF_LatinMetrics  metrics )+  {+    AF_AxisHints  axis       = &hints->axis[ AF_DIMENSION_VERT ];+    AF_Edge       edge       = axis->edges;+    AF_Edge       edge_limit = edge + axis->num_edges;+    AF_LatinAxis  latin      = &metrics->axis[ AF_DIMENSION_VERT ];+    FT_Fixed      scale      = latin->scale;+    FT_Pos        best_dist0;  /* initial threshold */+++    /* compute the initial threshold as a fraction of the EM size */+    best_dist0 = FT_MulFix( metrics->units_per_em / 40, scale );++    if ( best_dist0 > 64 / 2 )+      best_dist0 = 64 / 2;++    /* compute which blue zones are active, i.e. have their scaled */+    /* size < 3/4 pixels                                           */++    /* for each horizontal edge search the blue zone which is closest */+    for ( ; edge < edge_limit; edge++ )+    {+      FT_Int    bb;+      AF_Width  best_blue = NULL;+      FT_Pos    best_dist = best_dist0;++      for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )+      {+        AF_LatinBlue  blue = latin->blues + bb;+        FT_Bool       is_top_blue, is_major_dir;+++        /* skip inactive blue zones (i.e., those that are too small) */+        if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )+          continue;++        /* if it is a top zone, check for right edges -- if it is a bottom */+        /* zone, check for left edges                                      */+        /*                                                                 */+        /* of course, that's for TrueType                                  */+        is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );+        is_major_dir = FT_BOOL( edge->dir == axis->major_dir );++        /* if it is a top zone, the edge must be against the major    */+        /* direction; if it is a bottom zone, it must be in the major */+        /* direction                                                  */+        if ( is_top_blue ^ is_major_dir )+        {+          FT_Pos     dist;+          AF_Width   compare;+++          /* if it's a rounded edge, compare it to the overshoot position */+          /* if it's a flat edge, compare it to the reference position    */+          if ( edge->flags & AF_EDGE_ROUND )+            compare = &blue->shoot;+          else+            compare = &blue->ref;++          dist = edge->fpos - compare->org;+          if (dist < 0)+            dist = -dist;++          dist = FT_MulFix( dist, scale );+          if ( dist < best_dist )+          {+            best_dist = dist;+            best_blue = compare;+          }++#if 0+          /* now, compare it to the overshoot position if the edge is     */+          /* rounded, and if the edge is over the reference position of a */+          /* top zone, or under the reference position of a bottom zone   */+          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )+          {+            FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );+++            if ( is_top_blue ^ is_under_ref )+            {+              blue = latin->blues + bb;+              dist = edge->fpos - blue->shoot.org;+              if ( dist < 0 )+                dist = -dist;++              dist = FT_MulFix( dist, scale );+              if ( dist < best_dist )+              {+                best_dist = dist;+                best_blue = & blue->shoot;+              }+            }+          }+#endif+        }+      }++      if ( best_blue )+        edge->blue_edge = best_blue;+    }+  }+++  static FT_Error+  af_latin2_hints_init( AF_GlyphHints    hints,+                       AF_LatinMetrics  metrics )+  {+    FT_Render_Mode  mode;+    FT_UInt32       scaler_flags, other_flags;+    FT_Face         face = metrics->root.scaler.face;+++    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );++    /*+     *  correct x_scale and y_scale if needed, since they may have+     *  been modified `af_latin2_metrics_scale_dim' above+     */+    hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;+    hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;+    hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;+    hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;++    /* compute flags depending on render mode, etc. */+    mode = metrics->root.scaler.render_mode;++#if 0 /* #ifdef AF_USE_WARPER */+    if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )+    {+      metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;+    }+#endif++    scaler_flags = hints->scaler_flags;+    other_flags  = 0;++    /*+     *  We snap the width of vertical stems for the monochrome and+     *  horizontal LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )+      other_flags |= AF_LATIN_HINTS_HORZ_SNAP;++    /*+     *  We snap the width of horizontal stems for the monochrome and+     *  vertical LCD rendering targets only.+     */+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )+      other_flags |= AF_LATIN_HINTS_VERT_SNAP;++    /*+     *  We adjust stems to full pixels only if we don't use the `light' mode.+     */+    if ( mode != FT_RENDER_MODE_LIGHT )+      other_flags |= AF_LATIN_HINTS_STEM_ADJUST;++    if ( mode == FT_RENDER_MODE_MONO )+      other_flags |= AF_LATIN_HINTS_MONO;++    /*+     *  In `light' hinting mode we disable horizontal hinting completely.+     *  We also do it if the face is italic.+     */+    if ( mode == FT_RENDER_MODE_LIGHT                    ||+         (face->style_flags & FT_STYLE_FLAG_ITALIC) != 0 )+      scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;++    hints->scaler_flags = scaler_flags;+    hints->other_flags  = other_flags;++    return 0;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****        L A T I N   G L Y P H   G R I D - F I T T I N G        *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* snap a given width in scaled coordinates to one of the */+  /* current standard widths                                */++  static FT_Pos+  af_latin2_snap_width( AF_Width  widths,+                       FT_Int    count,+                       FT_Pos    width )+  {+    int     n;+    FT_Pos  best      = 64 + 32 + 2;+    FT_Pos  reference = width;+    FT_Pos  scaled;+++    for ( n = 0; n < count; n++ )+    {+      FT_Pos  w;+      FT_Pos  dist;+++      w = widths[n].cur;+      dist = width - w;+      if ( dist < 0 )+        dist = -dist;+      if ( dist < best )+      {+        best      = dist;+        reference = w;+      }+    }++    scaled = FT_PIX_ROUND( reference );++    if ( width >= reference )+    {+      if ( width < scaled + 48 )+        width = reference;+    }+    else+    {+      if ( width > scaled - 48 )+        width = reference;+    }++    return width;+  }+++  /* compute the snapped width of a given stem */++  static FT_Pos+  af_latin2_compute_stem_width( AF_GlyphHints  hints,+                               AF_Dimension   dim,+                               FT_Pos         width,+                               AF_Edge_Flags  base_flags,+                               AF_Edge_Flags  stem_flags )+  {+    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;+    AF_LatinAxis     axis     = & metrics->axis[dim];+    FT_Pos           dist     = width;+    FT_Int           sign     = 0;+    FT_Int           vertical = ( dim == AF_DIMENSION_VERT );+++    FT_UNUSED(base_flags);++    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||+          axis->extra_light                      )+      return width;++    if ( dist < 0 )+    {+      dist = -width;+      sign = 1;+    }++    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||+         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )+    {+      /* smooth hinting process: very lightly quantize the stem width */++      /* leave the widths of serifs alone */++      if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )+        goto Done_Width;++#if 0+      else if ( ( base_flags & AF_EDGE_ROUND ) )+      {+        if ( dist < 80 )+          dist = 64;+      }+      else if ( dist < 56 )+        dist = 56;+#endif+      if ( axis->width_count > 0 )+      {+        FT_Pos  delta;+++        /* compare to standard width */+        if ( axis->width_count > 0 )+        {+          delta = dist - axis->widths[0].cur;++          if ( delta < 0 )+            delta = -delta;++          if ( delta < 40 )+          {+            dist = axis->widths[0].cur;+            if ( dist < 48 )+              dist = 48;++            goto Done_Width;+          }+        }++        if ( dist < 3 * 64 )+        {+          delta  = dist & 63;+          dist  &= -64;++          if ( delta < 10 )+            dist += delta;++          else if ( delta < 32 )+            dist += 10;++          else if ( delta < 54 )+            dist += 54;++          else+            dist += delta;+        }+        else+          dist = ( dist + 32 ) & ~63;+      }+    }+    else+    {+      /* strong hinting process: snap the stem width to integer pixels */+      FT_Pos  org_dist = dist;+++      dist = af_latin2_snap_width( axis->widths, axis->width_count, dist );++      if ( vertical )+      {+        /* in the case of vertical hinting, always round */+        /* the stem heights to integer pixels            */++        if ( dist >= 64 )+          dist = ( dist + 16 ) & ~63;+        else+          dist = 64;+      }+      else+      {+        if ( AF_LATIN_HINTS_DO_MONO( hints ) )+        {+          /* monochrome horizontal hinting: snap widths to integer pixels */+          /* with a different threshold                                   */++          if ( dist < 64 )+            dist = 64;+          else+            dist = ( dist + 32 ) & ~63;+        }+        else+        {+          /* for horizontal anti-aliased hinting, we adopt a more subtle */+          /* approach: we strengthen small stems, round stems whose size */+          /* is between 1 and 2 pixels to an integer, otherwise nothing  */++          if ( dist < 48 )+            dist = ( dist + 64 ) >> 1;++          else if ( dist < 128 )+          {+            /* We only round to an integer width if the corresponding */+            /* distortion is less than 1/4 pixel.  Otherwise this     */+            /* makes everything worse since the diagonals, which are  */+            /* not hinted, appear a lot bolder or thinner than the    */+            /* vertical stems.                                        */++            FT_Int  delta;+++            dist = ( dist + 22 ) & ~63;+            delta = dist - org_dist;+            if ( delta < 0 )+              delta = -delta;++            if (delta >= 16)+            {+              dist = org_dist;+              if ( dist < 48 )+                dist = ( dist + 64 ) >> 1;+            }+          }+          else+            /* round otherwise to prevent color fringes in LCD mode */+            dist = ( dist + 32 ) & ~63;+        }+      }+    }++  Done_Width:+    if ( sign )+      dist = -dist;++    return dist;+  }+++  /* align one stem edge relative to the previous stem edge */++  static void+  af_latin2_align_linked_edge( AF_GlyphHints  hints,+                              AF_Dimension   dim,+                              AF_Edge        base_edge,+                              AF_Edge        stem_edge )+  {+    FT_Pos  dist = stem_edge->opos - base_edge->opos;++    FT_Pos  fitted_width = af_latin2_compute_stem_width(+                             hints, dim, dist,+                             (AF_Edge_Flags)base_edge->flags,+                             (AF_Edge_Flags)stem_edge->flags );+++    stem_edge->pos = base_edge->pos + fitted_width;++    AF_LOG(( "LINK: edge %d (opos=%.2f) linked to (%.2f), "+             "dist was %.2f, now %.2f\n",+             stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,+             stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));+  }+++  static void+  af_latin2_align_serif_edge( AF_GlyphHints  hints,+                             AF_Edge        base,+                             AF_Edge        serif )+  {+    FT_UNUSED( hints );++    serif->pos = base->pos + (serif->opos - base->opos);+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                    E D G E   H I N T I N G                      ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( void )+  af_latin2_hint_edges( AF_GlyphHints  hints,+                       AF_Dimension   dim )+  {+    AF_AxisHints  axis       = &hints->axis[dim];+    AF_Edge       edges      = axis->edges;+    AF_Edge       edge_limit = edges + axis->num_edges;+    AF_Edge       edge;+    AF_Edge       anchor     = 0;+    FT_Int        has_serifs = 0;+    FT_Pos        anchor_drift = 0;++++    AF_LOG(( "==== hinting %s edges =====\n", dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ));++    /* we begin by aligning all stems relative to the blue zone */+    /* if needed -- that's only for horizontal edges            */++    if ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_BLUES( hints ) )+    {+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        AF_Width  blue;+        AF_Edge   edge1, edge2;+++        if ( edge->flags & AF_EDGE_DONE )+          continue;++        blue  = edge->blue_edge;+        edge1 = NULL;+        edge2 = edge->link;++        if ( blue )+        {+          edge1 = edge;+        }+        else if ( edge2 && edge2->blue_edge )+        {+          blue  = edge2->blue_edge;+          edge1 = edge2;+          edge2 = edge;+        }++        if ( !edge1 )+          continue;++        AF_LOG(( "BLUE: edge %d (opos=%.2f) snapped to (%.2f), "+                 "was (%.2f)\n",+                 edge1-edges, edge1->opos / 64.0, blue->fit / 64.0,+                 edge1->pos / 64.0 ));++        edge1->pos    = blue->fit;+        edge1->flags |= AF_EDGE_DONE;++        if ( edge2 && !edge2->blue_edge )+        {+          af_latin2_align_linked_edge( hints, dim, edge1, edge2 );+          edge2->flags |= AF_EDGE_DONE;+        }++        if ( !anchor )+        {+          anchor = edge;++          anchor_drift = (anchor->pos - anchor->opos);+          if (edge2)+            anchor_drift = (anchor_drift + (edge2->pos - edge2->opos)) >> 1;+        }+      }+    }++    /* now we will align all stem edges, trying to maintain the */+    /* relative order of stems in the glyph                     */+    for ( edge = edges; edge < edge_limit; edge++ )+    {+      AF_Edge  edge2;+++      if ( edge->flags & AF_EDGE_DONE )+        continue;++      /* skip all non-stem edges */+      edge2 = edge->link;+      if ( !edge2 )+      {+        has_serifs++;+        continue;+      }++      /* now align the stem */++      /* this should not happen, but it's better to be safe */+      if ( edge2->blue_edge )+      {+        AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));++        af_latin2_align_linked_edge( hints, dim, edge2, edge );+        edge->flags |= AF_EDGE_DONE;+        continue;+      }++      if ( !anchor )+      {+        FT_Pos  org_len, org_center, cur_len;+        FT_Pos  cur_pos1, error1, error2, u_off, d_off;+++        org_len = edge2->opos - edge->opos;+        cur_len = af_latin2_compute_stem_width(+                    hints, dim, org_len,+                    (AF_Edge_Flags)edge->flags,+                    (AF_Edge_Flags)edge2->flags );+        if ( cur_len <= 64 )+          u_off = d_off = 32;+        else+        {+          u_off = 38;+          d_off = 26;+        }++        if ( cur_len < 96 )+        {+          org_center = edge->opos + ( org_len >> 1 );++          cur_pos1   = FT_PIX_ROUND( org_center );++          error1 = org_center - ( cur_pos1 - u_off );+          if ( error1 < 0 )+            error1 = -error1;++          error2 = org_center - ( cur_pos1 + d_off );+          if ( error2 < 0 )+            error2 = -error2;++          if ( error1 < error2 )+            cur_pos1 -= u_off;+          else+            cur_pos1 += d_off;++          edge->pos  = cur_pos1 - cur_len / 2;+          edge2->pos = edge->pos + cur_len;+        }+        else+          edge->pos = FT_PIX_ROUND( edge->opos );++        AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) "+                 "snapped to (%.2f) (%.2f)\n",+                 edge-edges, edge->opos / 64.0,+                 edge2-edges, edge2->opos / 64.0,+                 edge->pos / 64.0, edge2->pos / 64.0 ));+        anchor = edge;++        edge->flags |= AF_EDGE_DONE;++        af_latin2_align_linked_edge( hints, dim, edge, edge2 );++        edge2->flags |= AF_EDGE_DONE;++        anchor_drift = ( (anchor->pos - anchor->opos) ++                         (edge2->pos - edge2->opos)) >> 1;++        AF_LOG(( "DRIFT: %.2f\n", anchor_drift/64.0 ));+      }+      else+      {+        FT_Pos   org_pos, org_len, org_center, cur_center, cur_len;+        FT_Pos   org_left, org_right;+++        org_pos    = edge->opos + anchor_drift;+        org_len    = edge2->opos - edge->opos;+        org_center = org_pos + ( org_len >> 1 );++        cur_len = af_latin2_compute_stem_width(+                   hints, dim, org_len,+                   (AF_Edge_Flags)edge->flags,+                   (AF_Edge_Flags)edge2->flags );++        org_left  = org_pos + ((org_len - cur_len) >> 1);+        org_right = org_pos + ((org_len + cur_len) >> 1);++        AF_LOG(( "ALIGN: left=%.2f right=%.2f ", org_left/64.0, org_right/64.0 ));+        cur_center = org_center;++        if ( edge2->flags & AF_EDGE_DONE )+        {+          AF_LOG(( "\n" ));+          edge->pos = edge2->pos - cur_len;+        }+        else+        {+         /* we want to compare several displacement, and choose+          * the one that increases fitness while minimizing+          * distortion as well+          */+          FT_Pos   displacements[6], scores[6], org, fit, delta;+          FT_UInt  count = 0;++          /* note: don't even try to fit tiny stems */+          if ( cur_len < 32 )+          {+            AF_LOG(( "tiny stem\n" ));+            goto AlignStem;+          }++          /* if the span is within a single pixel, don't touch it */+          if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) )+          {+            AF_LOG(( "single pixel stem\n" ));+            goto AlignStem;+          }++          if (cur_len <= 96)+          {+           /* we want to avoid the absolute worst case which is+            * when the left and right edges of the span each represent+            * about 50% of the gray. we'd better want to change this+            * to 25/75%, since this is much more pleasant to the eye with+            * very acceptable distortion+            */+            FT_Pos  frac_left  = (org_left) & 63;+            FT_Pos  frac_right = (org_right) & 63;++            if ( frac_left  >= 22 && frac_left  <= 42 &&+                 frac_right >= 22 && frac_right <= 42 )+            {+              org = frac_left;+              fit = (org <= 32) ? 16 : 48;+              delta = FT_ABS(fit - org);+              displacements[count] = fit - org;+              scores[count++]      = delta;+              AF_LOG(( "dispA=%.2f (%d) ", (fit - org)/64.0, delta ));++              org = frac_right;+              fit = (org <= 32) ? 16 : 48;+              delta = FT_ABS(fit - org);+              displacements[count] = fit - org;+              scores[count++]     = delta;+              AF_LOG(( "dispB=%.2f (%d) ", (fit - org)/64.0, delta ));+            }+          }++          /* snapping the left edge to the grid */+          org   = org_left;+          fit   = FT_PIX_ROUND(org);+          delta = FT_ABS(fit - org);+          displacements[count] = fit - org;+          scores[count++]      = delta;+          AF_LOG(( "dispC=%.2f (%d) ", (fit - org)/64.0, delta ));++          /* snapping the right edge to the grid */+          org   = org_right;+          fit   = FT_PIX_ROUND(org);+          delta = FT_ABS(fit - org);+          displacements[count] = fit - org;+          scores[count++]      = delta;+          AF_LOG(( "dispD=%.2f (%d) ", (fit - org)/64.0, delta ));++          /* now find the best displacement */+          {+            FT_Pos  best_score = scores[0];+            FT_Pos  best_disp  = displacements[0];+            FT_UInt nn;++            for (nn = 1; nn < count; nn++)+            {+              if (scores[nn] < best_score)+              {+                best_score = scores[nn];+                best_disp  = displacements[nn];+              }+            }++            cur_center = org_center + best_disp;+          }+          AF_LOG(( "\n" ));+        }++      AlignStem:+        edge->pos  = cur_center - (cur_len >> 1);+        edge2->pos = edge->pos + cur_len;++        AF_LOG(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f) "+                 "snapped to (%.2f) and (%.2f), org_len = %.2f cur_len=%.2f\n",+                 edge-edges, edge->opos / 64.0,+                 edge2-edges, edge2->opos / 64.0,+                 edge->pos / 64.0, edge2->pos / 64.0,+                 org_len / 64.0, cur_len / 64.0 ));++        edge->flags  |= AF_EDGE_DONE;+        edge2->flags |= AF_EDGE_DONE;++        if ( edge > edges && edge->pos < edge[-1].pos )+        {+          AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n",+                   edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));+          edge->pos = edge[-1].pos;+        }+      }+    }++    /* make sure that lowercase m's maintain their symmetry */++    /* In general, lowercase m's have six vertical edges if they are sans */+    /* serif, or twelve if they are with serifs.  This implementation is  */+    /* based on that assumption, and seems to work very well with most    */+    /* faces.  However, if for a certain face this assumption is not      */+    /* true, the m is just rendered like before.  In addition, any stem   */+    /* correction will only be applied to symmetrical glyphs (even if the */+    /* glyph is not an m), so the potential for unwanted distortion is    */+    /* relatively low.                                                    */++    /* We don't handle horizontal edges since we can't easily assure that */+    /* the third (lowest) stem aligns with the base line; it might end up */+    /* one pixel higher or lower.                                         */++#if 0+    {+      FT_Int  n_edges = edge_limit - edges;+++      if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )+      {+        AF_Edge  edge1, edge2, edge3;+        FT_Pos   dist1, dist2, span, delta;+++        if ( n_edges == 6 )+        {+          edge1 = edges;+          edge2 = edges + 2;+          edge3 = edges + 4;+        }+        else+        {+          edge1 = edges + 1;+          edge2 = edges + 5;+          edge3 = edges + 9;+        }++        dist1 = edge2->opos - edge1->opos;+        dist2 = edge3->opos - edge2->opos;++        span = dist1 - dist2;+        if ( span < 0 )+          span = -span;++        if ( span < 8 )+        {+          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );+          edge3->pos -= delta;+          if ( edge3->link )+            edge3->link->pos -= delta;++          /* move the serifs along with the stem */+          if ( n_edges == 12 )+          {+            ( edges + 8 )->pos -= delta;+            ( edges + 11 )->pos -= delta;+          }++          edge3->flags |= AF_EDGE_DONE;+          if ( edge3->link )+            edge3->link->flags |= AF_EDGE_DONE;+        }+      }+    }+#endif++    if ( has_serifs || !anchor )+    {+      /*+       *  now hint the remaining edges (serifs and single) in order+       *  to complete our processing+       */+      for ( edge = edges; edge < edge_limit; edge++ )+      {+        FT_Pos  delta;+++        if ( edge->flags & AF_EDGE_DONE )+          continue;++        delta = 1000;++        if ( edge->serif )+        {+          delta = edge->serif->opos - edge->opos;+          if ( delta < 0 )+            delta = -delta;+        }++        if ( delta < 64 + 16 )+        {+          af_latin2_align_serif_edge( hints, edge->serif, edge );+          AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) "+                   "aligned to (%.2f)\n",+                   edge-edges, edge->opos / 64.0,+                   edge->serif - edges, edge->serif->opos / 64.0,+                   edge->pos / 64.0 ));+        }+        else if ( !anchor )+        {+          AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",+                   edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));+          edge->pos = FT_PIX_ROUND( edge->opos );+          anchor    = edge;+        }+        else+        {+          AF_Edge  before, after;+++          for ( before = edge - 1; before >= edges; before-- )+            if ( before->flags & AF_EDGE_DONE )+              break;++          for ( after = edge + 1; after < edge_limit; after++ )+            if ( after->flags & AF_EDGE_DONE )+              break;++          if ( before >= edges && before < edge   &&+               after < edge_limit && after > edge )+          {+            if ( after->opos == before->opos )+              edge->pos = before->pos;+            else+              edge->pos = before->pos ++                          FT_MulDiv( edge->opos - before->opos,+                                     after->pos - before->pos,+                                     after->opos - before->opos );+            AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f) from %d (opos=%.2f)\n",+                     edge-edges, edge->opos / 64.0, edge->pos / 64.0, before - edges, before->opos / 64.0 ));+          }+          else+          {+              edge->pos = anchor->pos + (( edge->opos - anchor->opos + 16) & ~31);++            AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n",+                     edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));+          }+        }++        edge->flags |= AF_EDGE_DONE;++        if ( edge > edges && edge->pos < edge[-1].pos )+          edge->pos = edge[-1].pos;++        if ( edge + 1 < edge_limit        &&+             edge[1].flags & AF_EDGE_DONE &&+             edge->pos > edge[1].pos      )+          edge->pos = edge[1].pos;+      }+    }+  }+++  static FT_Error+  af_latin2_hints_apply( AF_GlyphHints    hints,+                        FT_Outline*      outline,+                        AF_LatinMetrics  metrics )+  {+    FT_Error  error;+    int       dim;+++    error = af_glyph_hints_reload( hints, outline );+    if ( error )+      goto Exit;++    /* analyze glyph outline */+#ifdef AF_USE_WARPER+    if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||+         AF_HINTS_DO_HORIZONTAL( hints ) )+#else+    if ( AF_HINTS_DO_HORIZONTAL( hints ) )+#endif+    {+      error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ );+      if ( error )+        goto Exit;+    }++    if ( AF_HINTS_DO_VERTICAL( hints ) )+    {+      error = af_latin2_hints_detect_features( hints, AF_DIMENSION_VERT );+      if ( error )+        goto Exit;++      af_latin2_hints_compute_blue_edges( hints, metrics );+    }++    /* grid-fit the outline */+    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )+    {+#ifdef AF_USE_WARPER+      if ( ( dim == AF_DIMENSION_HORZ &&+             metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )+      {+        AF_WarperRec  warper;+        FT_Fixed      scale;+        FT_Pos        delta;+++        af_warper_compute( &warper, hints, dim, &scale, &delta );+        af_glyph_hints_scale_dim( hints, dim, scale, delta );+        continue;+      }+#endif++      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||+           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )+      {+        af_latin2_hint_edges( hints, (AF_Dimension)dim );+        af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );+        af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );+      }+    }+    af_glyph_hints_save( hints, outline );++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****              L A T I N   S C R I P T   C L A S S              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  static const AF_Script_UniRangeRec  af_latin2_uniranges[] =+  {+    AF_UNIRANGE_REC( 32UL,  127UL ),    /* XXX: TODO: Add new Unicode ranges here! */+    AF_UNIRANGE_REC( 160UL, 255UL ),+    AF_UNIRANGE_REC( 0UL,   0UL )+  };+++  AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class,+    AF_SCRIPT_LATIN2,+    af_latin2_uniranges,++    sizeof( AF_LatinMetricsRec ),++    (AF_Script_InitMetricsFunc) af_latin2_metrics_init,+    (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale,+    (AF_Script_DoneMetricsFunc) NULL,++    (AF_Script_InitHintsFunc)   af_latin2_hints_init,+    (AF_Script_ApplyHintsFunc)  af_latin2_hints_apply+  )+++/* END */
+ src/autofit/aflatin2.h view
@@ -0,0 +1,39 @@+/***************************************************************************/+/*                                                                         */+/*  aflatin2.h                                                             */+/*                                                                         */+/*    Auto-fitter hinting routines for latin script (specification).       */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFLATIN2_H__+#define __AFLATIN2_H__++#include "afhints.h"+++FT_BEGIN_HEADER+++  /* the latin-specific script class */++  AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class)++/* */++FT_END_HEADER++#endif /* __AFLATIN_H__ */+++/* END */
+ src/autofit/afloader.c view
@@ -0,0 +1,539 @@+/***************************************************************************/+/*                                                                         */+/*  afloader.c                                                             */+/*                                                                         */+/*    Auto-fitter glyph loading routines (body).                           */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afloader.h"+#include "afhints.h"+#include "afglobal.h"+#include "aferrors.h"+++  FT_LOCAL_DEF( FT_Error )+  af_loader_init( AF_Loader  loader,+                  FT_Memory  memory )+  {+    FT_ZERO( loader );++    af_glyph_hints_init( &loader->hints, memory );+#ifdef AF_DEBUG+    _af_debug_hints = &loader->hints;+#endif+    return FT_GlyphLoader_New( memory, &loader->gloader );+  }+++  FT_LOCAL_DEF( FT_Error )+  af_loader_reset( AF_Loader  loader,+                   FT_Face    face )+  {+    FT_Error  error = AF_Err_Ok;+++    loader->face    = face;+    loader->globals = (AF_FaceGlobals)face->autohint.data;++    FT_GlyphLoader_Rewind( loader->gloader );++    if ( loader->globals == NULL )+    {+      error = af_face_globals_new( face, &loader->globals );+      if ( !error )+      {+        face->autohint.data =+          (FT_Pointer)loader->globals;+        face->autohint.finalizer =+          (FT_Generic_Finalizer)af_face_globals_free;+      }+    }++    return error;+  }+++  FT_LOCAL_DEF( void )+  af_loader_done( AF_Loader  loader )+  {+    af_glyph_hints_done( &loader->hints );++    loader->face    = NULL;+    loader->globals = NULL;++#ifdef AF_DEBUG+    _af_debug_hints = NULL;+#endif+    FT_GlyphLoader_Done( loader->gloader );+    loader->gloader = NULL;+  }+++  static FT_Error+  af_loader_load_g( AF_Loader  loader,+                    AF_Scaler  scaler,+                    FT_UInt    glyph_index,+                    FT_Int32   load_flags,+                    FT_UInt    depth )+  {+    FT_Error          error;+    FT_Face           face     = loader->face;+    FT_GlyphLoader    gloader  = loader->gloader;+    AF_ScriptMetrics  metrics  = loader->metrics;+    AF_GlyphHints     hints    = &loader->hints;+    FT_GlyphSlot      slot     = face->glyph;+    FT_Slot_Internal  internal = slot->internal;+++    error = FT_Load_Glyph( face, glyph_index, load_flags );+    if ( error )+      goto Exit;++    loader->transformed = internal->glyph_transformed;+    if ( loader->transformed )+    {+      FT_Matrix  inverse;+++      loader->trans_matrix = internal->glyph_matrix;+      loader->trans_delta  = internal->glyph_delta;++      inverse = loader->trans_matrix;+      FT_Matrix_Invert( &inverse );+      FT_Vector_Transform( &loader->trans_delta, &inverse );+    }++    /* set linear metrics */+    slot->linearHoriAdvance = slot->metrics.horiAdvance;+    slot->linearVertAdvance = slot->metrics.vertAdvance;++    switch ( slot->format )+    {+    case FT_GLYPH_FORMAT_OUTLINE:+      /* translate the loaded glyph when an internal transform is needed */+      if ( loader->transformed )+        FT_Outline_Translate( &slot->outline,+                              loader->trans_delta.x,+                              loader->trans_delta.y );++      /* copy the outline points in the loader's current               */+      /* extra points which is used to keep original glyph coordinates */+      error = FT_GLYPHLOADER_CHECK_POINTS( gloader,+                                           slot->outline.n_points + 4,+                                           slot->outline.n_contours );+      if ( error )+        goto Exit;++      FT_ARRAY_COPY( gloader->current.outline.points,+                     slot->outline.points,+                     slot->outline.n_points );++      FT_ARRAY_COPY( gloader->current.outline.contours,+                     slot->outline.contours,+                     slot->outline.n_contours );++      FT_ARRAY_COPY( gloader->current.outline.tags,+                     slot->outline.tags,+                     slot->outline.n_points );++      gloader->current.outline.n_points   = slot->outline.n_points;+      gloader->current.outline.n_contours = slot->outline.n_contours;++      /* compute original horizontal phantom points (and ignore */+      /* vertical ones)                                         */+      loader->pp1.x = hints->x_delta;+      loader->pp1.y = hints->y_delta;+      loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,+                                 hints->x_scale ) + hints->x_delta;+      loader->pp2.y = hints->y_delta;++      /* be sure to check for spacing glyphs */+      if ( slot->outline.n_points == 0 )+        goto Hint_Metrics;++      /* now load the slot image into the auto-outline and run the */+      /* automatic hinting process                                 */+      if ( metrics->clazz->script_hints_apply )+        metrics->clazz->script_hints_apply( hints,+                                            &gloader->current.outline,+                                            metrics );++      /* we now need to hint the metrics according to the change in */+      /* width/positioning that occurred during the hinting process */+      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )+      {+        FT_Pos        old_rsb, old_lsb, new_lsb;+        FT_Pos        pp1x_uh, pp2x_uh;+        AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];+        AF_Edge       edge1 = axis->edges;         /* leftmost edge  */+        AF_Edge       edge2 = edge1 ++                              axis->num_edges - 1; /* rightmost edge */+++        if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )+        {+          old_rsb = loader->pp2.x - edge2->opos;+          old_lsb = edge1->opos;+          new_lsb = edge1->pos;++          /* remember unhinted values to later account */+          /* for rounding errors                       */++          pp1x_uh = new_lsb    - old_lsb;+          pp2x_uh = edge2->pos + old_rsb;++          /* prefer too much space over too little space */+          /* for very small sizes                        */++          if ( old_lsb < 24 )+            pp1x_uh -= 8;++          if ( old_rsb < 24 )+            pp2x_uh += 8;++          loader->pp1.x = FT_PIX_ROUND( pp1x_uh );+          loader->pp2.x = FT_PIX_ROUND( pp2x_uh );++          if ( loader->pp1.x >= new_lsb && old_lsb > 0 )+            loader->pp1.x -= 64;++          if ( loader->pp2.x <= edge2->pos && old_rsb > 0 )+            loader->pp2.x += 64;++          slot->lsb_delta = loader->pp1.x - pp1x_uh;+          slot->rsb_delta = loader->pp2.x - pp2x_uh;+        }+        else+        {+          FT_Pos  pp1x = loader->pp1.x;+          FT_Pos  pp2x = loader->pp2.x;+++          loader->pp1.x = FT_PIX_ROUND( pp1x );+          loader->pp2.x = FT_PIX_ROUND( pp2x );++          slot->lsb_delta = loader->pp1.x - pp1x;+          slot->rsb_delta = loader->pp2.x - pp2x;+        }+      }+      else+      {+        FT_Pos  pp1x = loader->pp1.x;+        FT_Pos  pp2x = loader->pp2.x;+++        loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );+        loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );++        slot->lsb_delta = loader->pp1.x - pp1x;+        slot->rsb_delta = loader->pp2.x - pp2x;+      }++      /* good, we simply add the glyph to our loader's base */+      FT_GlyphLoader_Add( gloader );+      break;++    case FT_GLYPH_FORMAT_COMPOSITE:+      {+        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;+        FT_UInt      num_base_subgs, start_point;+        FT_SubGlyph  subglyph;+++        start_point = gloader->base.outline.n_points;++        /* first of all, copy the subglyph descriptors in the glyph loader */+        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );+        if ( error )+          goto Exit;++        FT_ARRAY_COPY( gloader->current.subglyphs,+                       slot->subglyphs,+                       num_subglyphs );++        gloader->current.num_subglyphs = num_subglyphs;+        num_base_subgs                 = gloader->base.num_subglyphs;++        /* now, read each subglyph independently */+        for ( nn = 0; nn < num_subglyphs; nn++ )+        {+          FT_Vector  pp1, pp2;+          FT_Pos     x, y;+          FT_UInt    num_points, num_new_points, num_base_points;+++          /* gloader.current.subglyphs can change during glyph loading due */+          /* to re-allocation -- we must recompute the current subglyph on */+          /* each iteration                                                */+          subglyph = gloader->base.subglyphs + num_base_subgs + nn;++          pp1 = loader->pp1;+          pp2 = loader->pp2;++          num_base_points = gloader->base.outline.n_points;++          error = af_loader_load_g( loader, scaler, subglyph->index,+                                    load_flags, depth + 1 );+          if ( error )+            goto Exit;++          /* recompute subglyph pointer */+          subglyph = gloader->base.subglyphs + num_base_subgs + nn;++          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )+          {+            pp1 = loader->pp1;+            pp2 = loader->pp2;+          }+          else+          {+            loader->pp1 = pp1;+            loader->pp2 = pp2;+          }++          num_points     = gloader->base.outline.n_points;+          num_new_points = num_points - num_base_points;++          /* now perform the transform required for this subglyph */++          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |+                                   FT_SUBGLYPH_FLAG_XY_SCALE |+                                   FT_SUBGLYPH_FLAG_2X2      ) )+          {+            FT_Vector*  cur   = gloader->base.outline.points ++                                num_base_points;+            FT_Vector*  limit = cur + num_new_points;+++            for ( ; cur < limit; cur++ )+              FT_Vector_Transform( cur, &subglyph->transform );+          }++          /* apply offset */++          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )+          {+            FT_Int      k = subglyph->arg1;+            FT_UInt     l = subglyph->arg2;+            FT_Vector*  p1;+            FT_Vector*  p2;+++            if ( start_point + k >= num_base_points         ||+                               l >= (FT_UInt)num_new_points )+            {+              error = AF_Err_Invalid_Composite;+              goto Exit;+            }++            l += num_base_points;++            /* for now, only use the current point coordinates;    */+            /* we may consider another approach in the near future */+            p1 = gloader->base.outline.points + start_point + k;+            p2 = gloader->base.outline.points + start_point + l;++            x = p1->x - p2->x;+            y = p1->y - p2->y;+          }+          else+          {+            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;+            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;++            x = FT_PIX_ROUND( x );+            y = FT_PIX_ROUND( y );+          }++          {+            FT_Outline  dummy = gloader->base.outline;+++            dummy.points  += num_base_points;+            dummy.n_points = (short)num_new_points;++            FT_Outline_Translate( &dummy, x, y );+          }+        }+      }+      break;++    default:+      /* we don't support other formats (yet?) */+      error = AF_Err_Unimplemented_Feature;+    }++  Hint_Metrics:+    if ( depth == 0 )+    {+      FT_BBox    bbox;+      FT_Vector  vvector;+++      vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;+      vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;+      vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );+      vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );++      /* transform the hinted outline if needed */+      if ( loader->transformed )+      {+        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );+        FT_Vector_Transform( &vvector, &loader->trans_matrix );+      }+#if 1+      /* we must translate our final outline by -pp1.x and compute */+      /* the new metrics                                           */+      if ( loader->pp1.x )+        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );+#endif+      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );++      bbox.xMin = FT_PIX_FLOOR( bbox.xMin );+      bbox.yMin = FT_PIX_FLOOR( bbox.yMin );+      bbox.xMax = FT_PIX_CEIL(  bbox.xMax );+      bbox.yMax = FT_PIX_CEIL(  bbox.yMax );++      slot->metrics.width        = bbox.xMax - bbox.xMin;+      slot->metrics.height       = bbox.yMax - bbox.yMin;+      slot->metrics.horiBearingX = bbox.xMin;+      slot->metrics.horiBearingY = bbox.yMax;++      slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x );+      slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );++      /* for mono-width fonts (like Andale, Courier, etc.) we need */+      /* to keep the original rounded advance width; ditto for     */+      /* digits if all have the same advance width                 */+#if 0+      if ( !FT_IS_FIXED_WIDTH( slot->face ) )+        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;+      else+        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,+                                               x_scale );+#else+      if ( FT_IS_FIXED_WIDTH( slot->face )                              ||+           ( af_face_globals_is_digit( loader->globals, glyph_index ) &&+             metrics->digits_have_same_width                          ) )+      {+        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,+                                               metrics->scaler.x_scale );++        /* Set delta values to 0.  Otherwise code that uses them is */+        /* going to ruin the fixed advance width.                   */+        slot->lsb_delta = 0;+        slot->rsb_delta = 0;+      }+      else+      {+        /* non-spacing glyphs must stay as-is */+        if ( slot->metrics.horiAdvance )+          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;+      }+#endif++      slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,+                                              metrics->scaler.y_scale );++      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );+      slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );++      /* now copy outline into glyph slot */+      FT_GlyphLoader_Rewind( internal->loader );+      error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );+      if ( error )+        goto Exit;++      slot->outline = internal->loader->base.outline;+      slot->format  = FT_GLYPH_FORMAT_OUTLINE;+    }++#ifdef DEBUG_HINTER+    af_debug_hinter = hinter;+#endif++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  af_loader_load_glyph( AF_Loader  loader,+                        FT_Face    face,+                        FT_UInt    gindex,+                        FT_UInt32  load_flags )+  {+    FT_Error      error;+    FT_Size       size = face->size;+    AF_ScalerRec  scaler;+++    if ( !size )+      return AF_Err_Invalid_Argument;++    FT_ZERO( &scaler );++    scaler.face    = face;+    scaler.x_scale = size->metrics.x_scale;+    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */+    scaler.y_scale = size->metrics.y_scale;+    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */++    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );+    scaler.flags       = 0;  /* XXX: fix this */++    error = af_loader_reset( loader, face );+    if ( !error )+    {+      AF_ScriptMetrics  metrics;+      FT_UInt           options = 0;+++#ifdef FT_OPTION_AUTOFIT2+      /* XXX: undocumented hook to activate the latin2 hinter */+      if ( load_flags & ( 1UL << 20 ) )+        options = 2;+#endif++      error = af_face_globals_get_metrics( loader->globals, gindex,+                                           options, &metrics );+      if ( !error )+      {+        loader->metrics = metrics;++        if ( metrics->clazz->script_metrics_scale )+          metrics->clazz->script_metrics_scale( metrics, &scaler );+        else+          metrics->scaler = scaler;++        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;+        load_flags &= ~FT_LOAD_RENDER;++        if ( metrics->clazz->script_hints_init )+        {+          error = metrics->clazz->script_hints_init( &loader->hints,+                                                     metrics );+          if ( error )+            goto Exit;+        }++        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );+      }+    }+  Exit:+    return error;+  }+++/* END */
+ src/autofit/afloader.h view
@@ -0,0 +1,73 @@+/***************************************************************************/+/*                                                                         */+/*  afloader.h                                                             */+/*                                                                         */+/*    Auto-fitter glyph loading routines (specification).                  */+/*                                                                         */+/*  Copyright 2003, 2004, 2005 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AF_LOADER_H__+#define __AF_LOADER_H__++#include "afhints.h"+#include "afglobal.h"+++FT_BEGIN_HEADER++  typedef struct AF_LoaderRec_+  {+    FT_Face           face;           /* current face */+    AF_FaceGlobals    globals;        /* current face globals */+    FT_GlyphLoader    gloader;        /* glyph loader */+    AF_GlyphHintsRec  hints;+    AF_ScriptMetrics  metrics;+    FT_Bool           transformed;+    FT_Matrix         trans_matrix;+    FT_Vector         trans_delta;+    FT_Vector         pp1;+    FT_Vector         pp2;+    /* we don't handle vertical phantom points */++  } AF_LoaderRec, *AF_Loader;+++  FT_LOCAL( FT_Error )+  af_loader_init( AF_Loader  loader,+                  FT_Memory  memory );+++  FT_LOCAL( FT_Error )+  af_loader_reset( AF_Loader  loader,+                   FT_Face    face );+++  FT_LOCAL( void )+  af_loader_done( AF_Loader  loader );+++  FT_LOCAL( FT_Error )+  af_loader_load_glyph( AF_Loader  loader,+                        FT_Face    face,+                        FT_UInt    gindex,+                        FT_UInt32  load_flags );++/* */+++FT_END_HEADER++#endif /* __AF_LOADER_H__ */+++/* END */
+ src/autofit/afmodule.c view
@@ -0,0 +1,94 @@+/***************************************************************************/+/*                                                                         */+/*  afmodule.c                                                             */+/*                                                                         */+/*    Auto-fitter module implementation (body).                            */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afmodule.h"+#include "afloader.h"+#include "afpic.h"++#ifdef AF_DEBUG+  int    _af_debug;+  int    _af_debug_disable_horz_hints;+  int    _af_debug_disable_vert_hints;+  int    _af_debug_disable_blue_hints;+  void*  _af_debug_hints;+#endif++#include FT_INTERNAL_OBJECTS_H+++  typedef struct  FT_AutofitterRec_+  {+    FT_ModuleRec  root;+    AF_LoaderRec  loader[1];++  } FT_AutofitterRec, *FT_Autofitter;+++  FT_CALLBACK_DEF( FT_Error )+  af_autofitter_init( FT_Autofitter  module )+  {+    return af_loader_init( module->loader, module->root.library->memory );+  }+++  FT_CALLBACK_DEF( void )+  af_autofitter_done( FT_Autofitter  module )+  {+    af_loader_done( module->loader );+  }+++  FT_CALLBACK_DEF( FT_Error )+  af_autofitter_load_glyph( FT_Autofitter  module,+                            FT_GlyphSlot   slot,+                            FT_Size        size,+                            FT_UInt        glyph_index,+                            FT_Int32       load_flags )+  {+    FT_UNUSED( size );++    return af_loader_load_glyph( module->loader, slot->face,+                                 glyph_index, load_flags );+  }+++  FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service,+    NULL,+    NULL,+    NULL,+    (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph+  )++  FT_DEFINE_MODULE(autofit_module_class,++    FT_MODULE_HINTER,+    sizeof ( FT_AutofitterRec ),++    "autofitter",+    0x10000L,   /* version 1.0 of the autofitter  */+    0x20000L,   /* requires FreeType 2.0 or above */++    (const void*)&AF_AF_AUTOFITTER_SERVICE_GET,++    (FT_Module_Constructor)af_autofitter_init,+    (FT_Module_Destructor) af_autofitter_done,+    (FT_Module_Requester)  NULL+  )+++/* END */
+ src/autofit/afmodule.h view
@@ -0,0 +1,37 @@+/***************************************************************************/+/*                                                                         */+/*  afmodule.h                                                             */+/*                                                                         */+/*    Auto-fitter module implementation (specification).                   */+/*                                                                         */+/*  Copyright 2003, 2004, 2005 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFMODULE_H__+#define __AFMODULE_H__++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_MODULE_H+++FT_BEGIN_HEADER++FT_DECLARE_MODULE(autofit_module_class)+++FT_END_HEADER++#endif /* __AFMODULE_H__ */+++/* END */
+ src/autofit/afpic.c view
@@ -0,0 +1,94 @@+/***************************************************************************/+/*                                                                         */+/*  afpic.c                                                                */+/*                                                                         */+/*    The FreeType position independent code services for autofit module.  */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "afpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from afmodule.c */+  void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*);++  /* forward declaration of PIC init functions from script classes */+#include "aflatin.h"+#include "aflatin2.h"+#include "afcjk.h"+#include "afdummy.h"+#include "afindic.h"++  void+  autofit_module_class_pic_free( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->autofit )+    {+      FT_FREE( pic_container->autofit );+      pic_container->autofit = NULL;+    }+  }+++  FT_Error+  autofit_module_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_UInt            ss;+    FT_Error           error         = AF_Err_Ok;+    AFModulePIC*       container;+    FT_Memory          memory        = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof ( *container ) );+    pic_container->autofit = container;++    /* initialize pointer table - this is how the module usually expects this data */+    for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ )+    {+      container->af_script_classes[ss] = &container->af_script_classes_rec[ss];+    }+    container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL;+    +    /* add call to initialization function when you add new scripts */+    ss = 0;+    FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]);+#ifdef FT_OPTION_AUTOFIT2+    FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]);+#endif+    FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]);+    FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]);+    FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]);    ++    FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service);++/*Exit:*/+    if(error)+      autofit_module_class_pic_free(library);+    return error;+  }+++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/autofit/afpic.h view
@@ -0,0 +1,64 @@+/***************************************************************************/+/*                                                                         */+/*  afpic.h                                                                */+/*                                                                         */+/*    The FreeType position independent code services for autofit module.  */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFPIC_H__+#define __AFPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC++#define AF_SCRIPT_CLASSES_GET         af_script_classes+#define AF_AF_AUTOFITTER_SERVICE_GET  af_autofitter_service++#else /* FT_CONFIG_OPTION_PIC */++#include "aftypes.h"++/* increase these when you add new scripts, and update autofit_module_class_pic_init */+#ifdef FT_OPTION_AUTOFIT2+  #define AF_SCRIPT_CLASSES_COUNT     6+#else+  #define AF_SCRIPT_CLASSES_COUNT     5  +#endif+#define AF_SCRIPT_CLASSES_REC_COUNT  (AF_SCRIPT_CLASSES_COUNT-1)    ++  typedef struct AFModulePIC_+  {+    AF_ScriptClass    af_script_classes[AF_SCRIPT_CLASSES_COUNT];+    AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT];+    FT_AutoHinter_ServiceRec af_autofitter_service;+  } AFModulePIC;++#define GET_PIC(lib)                  ((AFModulePIC*)((lib)->pic_container.autofit))+#define AF_SCRIPT_CLASSES_GET         (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes)+#define AF_AF_AUTOFITTER_SERVICE_GET  (GET_PIC(library)->af_autofitter_service)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __AFPIC_H__ */+++/* END */
+ src/autofit/aftypes.h view
@@ -0,0 +1,403 @@+/***************************************************************************/+/*                                                                         */+/*  aftypes.h                                                              */+/*                                                                         */+/*    Auto-fitter types (specification only).                              */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************+   *+   *  The auto-fitter is a complete rewrite of the old auto-hinter.+   *  Its main feature is the ability to differentiate between different+   *  scripts in order to apply language-specific rules.+   *+   *  The code has also been compartmentized into several entities that+   *  should make algorithmic experimentation easier than with the old+   *  code.+   *+   *  Finally, we get rid of the Catharon license, since this code is+   *  released under the FreeType one.+   *+   *************************************************************************/+++#ifndef __AFTYPES_H__+#define __AFTYPES_H__++#include <ft2build.h>++#include FT_FREETYPE_H+#include FT_OUTLINE_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+++FT_BEGIN_HEADER++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    D E B U G G I N G                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#define xxAF_USE_WARPER  /* only define to use warp hinting */+#define xxAF_DEBUG++#ifdef AF_DEBUG++#include FT_CONFIG_STANDARD_LIBRARY_H++#define AF_LOG( x )  do { if ( _af_debug ) printf x; } while ( 0 )++extern int    _af_debug;+extern int    _af_debug_disable_horz_hints;+extern int    _af_debug_disable_vert_hints;+extern int    _af_debug_disable_blue_hints;+extern void*  _af_debug_hints;++#else /* !AF_DEBUG */++#define AF_LOG( x )  do { } while ( 0 )        /* nothing */++#endif /* !AF_DEBUG */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                 U T I L I T Y   S T U F F                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct  AF_WidthRec_+  {+    FT_Pos  org;  /* original position/width in font units              */+    FT_Pos  cur;  /* current/scaled position/width in device sub-pixels */+    FT_Pos  fit;  /* current/fitted position/width in device sub-pixels */++  } AF_WidthRec, *AF_Width;+++  FT_LOCAL( void )+  af_sort_pos( FT_UInt  count,+               FT_Pos*  table );++  FT_LOCAL( void )+  af_sort_widths( FT_UInt   count,+                  AF_Width  widths );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                   A N G L E   T Y P E S                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*+   *  The auto-fitter doesn't need a very high angular accuracy;+   *  this allows us to speed up some computations considerably with a+   *  light Cordic algorithm (see afangles.c).+   */++  typedef FT_Int  AF_Angle;+++#define AF_ANGLE_PI   256+#define AF_ANGLE_2PI  ( AF_ANGLE_PI * 2 )+#define AF_ANGLE_PI2  ( AF_ANGLE_PI / 2 )+#define AF_ANGLE_PI4  ( AF_ANGLE_PI / 4 )+++#if 0+  /*+   *  compute the angle of a given 2-D vector+   */+  FT_LOCAL( AF_Angle )+  af_angle_atan( FT_Pos  dx,+                 FT_Pos  dy );+++  /*+   *  compute `angle2 - angle1'; the result is always within+   *  the range [-AF_ANGLE_PI .. AF_ANGLE_PI - 1]+   */+  FT_LOCAL( AF_Angle )+  af_angle_diff( AF_Angle  angle1,+                 AF_Angle  angle2 );+#endif /* 0 */+++#define AF_ANGLE_DIFF( result, angle1, angle2 ) \+  FT_BEGIN_STMNT                                \+    AF_Angle  _delta = (angle2) - (angle1);     \+                                                \+                                                \+    _delta %= AF_ANGLE_2PI;                     \+    if ( _delta < 0 )                           \+      _delta += AF_ANGLE_2PI;                   \+                                                \+    if ( _delta > AF_ANGLE_PI )                 \+      _delta -= AF_ANGLE_2PI;                   \+                                                \+    result = _delta;                            \+  FT_END_STMNT+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    O U T L I N E S                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*  opaque handle to glyph-specific hints -- see `afhints.h' for more+   *  details+   */+  typedef struct AF_GlyphHintsRec_*  AF_GlyphHints;++  /*  This structure is used to model an input glyph outline to+   *  the auto-hinter.  The latter will set the `hints' field+   *  depending on the glyph's script.+   */+  typedef struct  AF_OutlineRec_+  {+    FT_Face        face;+    FT_Outline     outline;+    FT_UInt        outline_resolution;++    FT_Int         advance;+    FT_UInt        metrics_resolution;++    AF_GlyphHints  hints;++  } AF_OutlineRec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       S C A L E R S                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*+   *  A scaler models the target pixel device that will receive the+   *  auto-hinted glyph image.+   */++  typedef enum  AF_ScalerFlags_+  {+    AF_SCALER_FLAG_NO_HORIZONTAL = 1,  /* disable horizontal hinting */+    AF_SCALER_FLAG_NO_VERTICAL   = 2,  /* disable vertical hinting   */+    AF_SCALER_FLAG_NO_ADVANCE    = 4   /* disable advance hinting    */++  } AF_ScalerFlags;+++  typedef struct  AF_ScalerRec_+  {+    FT_Face         face;        /* source font face                        */+    FT_Fixed        x_scale;     /* from font units to 1/64th device pixels */+    FT_Fixed        y_scale;     /* from font units to 1/64th device pixels */+    FT_Pos          x_delta;     /* in 1/64th device pixels                 */+    FT_Pos          y_delta;     /* in 1/64th device pixels                 */+    FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.     */+    FT_UInt32       flags;       /* additional control flags, see above     */++  } AF_ScalerRec, *AF_Scaler;+++#define AF_SCALER_EQUAL_SCALES( a, b )      \+          ( (a)->x_scale == (b)->x_scale && \+            (a)->y_scale == (b)->y_scale && \+            (a)->x_delta == (b)->x_delta && \+            (a)->y_delta == (b)->y_delta )+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       S C R I P T S                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*+   *  The list of know scripts.  Each different script corresponds to the+   *  following information:+   *+   *   - A set of Unicode ranges to test whether the face supports the+   *     script.+   *+   *   - A specific global analyzer that will compute global metrics+   *     specific to the script.+   *+   *   - A specific glyph analyzer that will compute segments and+   *     edges for each glyph covered by the script.+   *+   *   - A specific grid-fitting algorithm that will distort the+   *     scaled glyph outline according to the results of the glyph+   *     analyzer.+   *+   *  Note that a given analyzer and/or grid-fitting algorithm can be+   *  used by more than one script.+   */++  typedef enum  AF_Script_+  {+    AF_SCRIPT_NONE  = 0,+    AF_SCRIPT_LATIN = 1,+    AF_SCRIPT_CJK   = 2,+    AF_SCRIPT_INDIC = 3, +#ifdef FT_OPTION_AUTOFIT2+    AF_SCRIPT_LATIN2,+#endif++    /* add new scripts here.  Don't forget to update the list in */+    /* `afglobal.c'.                                             */++    AF_SCRIPT_MAX   /* do not remove */++  } AF_Script;+++  typedef struct AF_ScriptClassRec_ const*  AF_ScriptClass;++  typedef struct  AF_ScriptMetricsRec_+  {+    AF_ScriptClass  clazz;+    AF_ScalerRec    scaler;+    FT_Bool         digits_have_same_width;++  } AF_ScriptMetricsRec, *AF_ScriptMetrics;+++  /*  This function parses an FT_Face to compute global metrics for+   *  a specific script.+   */+  typedef FT_Error+  (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics  metrics,+                                FT_Face           face );++  typedef void+  (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics  metrics,+                                 AF_Scaler         scaler );++  typedef void+  (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics  metrics );+++  typedef FT_Error+  (*AF_Script_InitHintsFunc)( AF_GlyphHints     hints,+                              AF_ScriptMetrics  metrics );++  typedef void+  (*AF_Script_ApplyHintsFunc)( AF_GlyphHints     hints,+                               FT_Outline*       outline,+                               AF_ScriptMetrics  metrics );+++  typedef struct  AF_Script_UniRangeRec_+  {+    FT_UInt32  first;+    FT_UInt32  last;++  } AF_Script_UniRangeRec;++#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) }++  typedef const AF_Script_UniRangeRec  *AF_Script_UniRange;+++  typedef struct  AF_ScriptClassRec_+  {+    AF_Script                   script;+    AF_Script_UniRange          script_uni_ranges; /* last must be { 0, 0 } */++    FT_Offset                   script_metrics_size;+    AF_Script_InitMetricsFunc   script_metrics_init;+    AF_Script_ScaleMetricsFunc  script_metrics_scale;+    AF_Script_DoneMetricsFunc   script_metrics_done;++    AF_Script_InitHintsFunc     script_hints_init;+    AF_Script_ApplyHintsFunc    script_hints_apply;++  } AF_ScriptClassRec;++/* Declare and define vtables for classes */+#ifndef FT_CONFIG_OPTION_PIC++#define AF_DECLARE_SCRIPT_CLASS(script_class)                                \+  FT_CALLBACK_TABLE const AF_ScriptClassRec                                  \+  script_class;++#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size,        \+                               m_init, m_scale, m_done, h_init, h_apply)     \+  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec                              \+  script_class =                                                             \+  {                                                                          \+    script_,                                                                 \+    ranges,                                                                  \+                                                                             \+    m_size,                                                                  \+                                                                             \+    m_init,                                                                  \+    m_scale,                                                                 \+    m_done,                                                                  \+                                                                             \+    h_init,                                                                  \+    h_apply                                                                  \+  };++#else ++#define AF_DECLARE_SCRIPT_CLASS(script_class)                                \+  FT_LOCAL(void)                                                             \+  FT_Init_Class_##script_class(AF_ScriptClassRec* ac);++#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size,        \+                               m_init, m_scale, m_done, h_init, h_apply)     \+  FT_LOCAL_DEF(void)                                                         \+  FT_Init_Class_##script_class(AF_ScriptClassRec* ac)                        \+  {                                                                          \+    ac->script                = script_;                                     \+    ac->script_uni_ranges     = ranges;                                      \+                                                                             \+    ac->script_metrics_size   = m_size;                                      \+                                                                             \+    ac->script_metrics_init   = m_init;                                      \+    ac->script_metrics_scale  = m_scale;                                     \+    ac->script_metrics_done   = m_done;                                      \+                                                                             \+    ac->script_hints_init     = h_init;                                      \+    ac->script_hints_apply    = h_apply;                                     \+  }+#endif+++/* */++FT_END_HEADER++#endif /* __AFTYPES_H__ */+++/* END */
+ src/autofit/afwarp.c view
@@ -0,0 +1,338 @@+/***************************************************************************/+/*                                                                         */+/*  afwarp.c                                                               */+/*                                                                         */+/*    Auto-fitter warping algorithm (body).                                */+/*                                                                         */+/*  Copyright 2006, 2007 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "afwarp.h"++#ifdef AF_USE_WARPER++#if 1+  static const AF_WarpScore+  af_warper_weights[64] =+  {+    35, 32, 30, 25, 20, 15, 12, 10,  5,  1,  0,  0,  0,  0,  0,  0,+     0,  0,  0,  0,  0,  0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,++   -30,-30,-20,-20,-10,-10, -8, -5, -2, -1,  0,  0,  0,  0,  0,  0,+     0,  0,  0,  0,  0,  0,  0,  1,  5, 10, 12, 15, 20, 25, 30, 32,+  };+#else+  static const AF_WarpScore+  af_warper_weights[64] =+  {+    30, 20, 10,  5,  4,  4,  3,  2,  1,  0,  0,  0,  0,  0,  0,  0,+     0,  0,  0,  0,  0,  0,  0, -1, -2, -2, -5, -5,-10,-10,-15,-20,++   -20,-15,-15,-10,-10, -5, -5, -2, -2, -1,  0,  0,  0,  0,  0,  0,+     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  4,  5, 10, 20,+  };+#endif+++  static void+  af_warper_compute_line_best( AF_Warper     warper,+                               FT_Fixed      scale,+                               FT_Pos        delta,+                               FT_Pos        xx1,+                               FT_Pos        xx2,+                               AF_WarpScore  base_distort,+                               AF_Segment    segments,+                               FT_UInt       num_segments )+  {+    FT_Int        idx_min, idx_max, idx0;+    FT_UInt       nn;+    AF_WarpScore  scores[65];+++    for ( nn = 0; nn < 65; nn++ )+      scores[nn] = 0;++    idx0 = xx1 - warper->t1;++    /* compute minimum and maximum indices */+    {+      FT_Pos  xx1min = warper->x1min;+      FT_Pos  xx1max = warper->x1max;+      FT_Pos  w      = xx2 - xx1;+++      if ( xx1min + w < warper->x2min )+        xx1min = warper->x2min - w;++      xx1max = warper->x1max;+      if ( xx1max + w > warper->x2max )+        xx1max = warper->x2max - w;++      idx_min = xx1min - warper->t1;+      idx_max = xx1max - warper->t1;++      if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )+      {+        AF_LOG(( "invalid indices:\n"+                 "  min=%d max=%d, xx1=%ld xx2=%ld,\n"+                 "  x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",+                 idx_min, idx_max, xx1, xx2,+                 warper->x1min, warper->x1max,+                 warper->x2min, warper->x2max ));+        return;+      }+    }++    for ( nn = 0; nn < num_segments; nn++ )+    {+      FT_Pos  len = segments[nn].max_coord - segments[nn].min_coord;+      FT_Pos  y0  = FT_MulFix( segments[nn].pos, scale ) + delta;+      FT_Pos  y   = y0 + ( idx_min - idx0 );+      FT_Int  idx;+++      for ( idx = idx_min; idx <= idx_max; idx++, y++ )+        scores[idx] += af_warper_weights[y & 63] * len;+    }++    /* find best score */+    {+      FT_Int  idx;+++      for ( idx = idx_min; idx <= idx_max; idx++ )+      {+        AF_WarpScore  score = scores[idx];+        AF_WarpScore  distort = base_distort + ( idx - idx0 );+++        if ( score > warper->best_score           ||+             ( score == warper->best_score    &&+               distort < warper->best_distort )   )+        {+          warper->best_score   = score;+          warper->best_distort = distort;+          warper->best_scale   = scale;+          warper->best_delta   = delta + ( idx - idx0 );+        }+      }+    }+  }+++  FT_LOCAL_DEF( void )+  af_warper_compute( AF_Warper      warper,+                     AF_GlyphHints  hints,+                     AF_Dimension   dim,+                     FT_Fixed      *a_scale,+                     FT_Pos        *a_delta )+  {+    AF_AxisHints  axis;+    AF_Point      points;++    FT_Fixed      org_scale;+    FT_Pos        org_delta;++    FT_UInt       nn, num_points, num_segments;+    FT_Int        X1, X2;+    FT_Int        w;++    AF_WarpScore  base_distort;+    AF_Segment    segments;+++    /* get original scaling transformation */+    if ( dim == AF_DIMENSION_VERT )+    {+      org_scale = hints->y_scale;+      org_delta = hints->y_delta;+    }+    else+    {+      org_scale = hints->x_scale;+      org_delta = hints->x_delta;+    }++    warper->best_scale   = org_scale;+    warper->best_delta   = org_delta;+    warper->best_score   = INT_MIN;+    warper->best_distort = 0;++    axis         = &hints->axis[dim];+    segments     = axis->segments;+    num_segments = axis->num_segments;+    points       = hints->points;+    num_points   = hints->num_points;++    *a_scale = org_scale;+    *a_delta = org_delta;++    /* get X1 and X2, minimum and maximum in original coordinates */+    if ( num_segments < 1 )+      return;++#if 1+    X1 = X2 = points[0].fx;+    for ( nn = 1; nn < num_points; nn++ )+    {+      FT_Int  X = points[nn].fx;+++      if ( X < X1 )+        X1 = X;+      if ( X > X2 )+        X2 = X;+    }+#else+    X1 = X2 = segments[0].pos;+    for ( nn = 1; nn < num_segments; nn++ )+    {+      FT_Int  X = segments[nn].pos;+++      if ( X < X1 )+        X1 = X;+      if ( X > X2 )+        X2 = X;+    }+#endif++    if ( X1 >= X2 )+      return;++    warper->x1 = FT_MulFix( X1, org_scale ) + org_delta;+    warper->x2 = FT_MulFix( X2, org_scale ) + org_delta;++    warper->t1 = AF_WARPER_FLOOR( warper->x1 );+    warper->t2 = AF_WARPER_CEIL( warper->x2 );++    warper->x1min = warper->x1 & ~31;+    warper->x1max = warper->x1min + 32;+    warper->x2min = warper->x2 & ~31;+    warper->x2max = warper->x2min + 32;++    if ( warper->x1max > warper->x2 )+      warper->x1max = warper->x2;++    if ( warper->x2min < warper->x1 )+      warper->x2min = warper->x1;++    warper->w0 = warper->x2 - warper->x1;++    if ( warper->w0 <= 64 )+    {+      warper->x1max = warper->x1;+      warper->x2min = warper->x2;+    }++    warper->wmin = warper->x2min - warper->x1max;+    warper->wmax = warper->x2max - warper->x1min;++#if 1+    {+      int  margin = 16;+++      if ( warper->w0 <= 128 )+      {+         margin = 8;+         if ( warper->w0 <= 96 )+           margin = 4;+      }++      if ( warper->wmin < warper->w0 - margin )+        warper->wmin = warper->w0 - margin;++      if ( warper->wmax > warper->w0 + margin )+        warper->wmax = warper->w0 + margin;+    }++    if ( warper->wmin < warper->w0 * 3 / 4 )+      warper->wmin = warper->w0 * 3 / 4;++    if ( warper->wmax > warper->w0 * 5 / 4 )+      warper->wmax = warper->w0 * 5 / 4;+#else+    /* no scaling, just translation */+    warper->wmin = warper->wmax = warper->w0;+#endif++    for ( w = warper->wmin; w <= warper->wmax; w++ )+    {+      FT_Fixed  new_scale;+      FT_Pos    new_delta;+      FT_Pos    xx1, xx2;+++      xx1 = warper->x1;+      xx2 = warper->x2;+      if ( w >= warper->w0 )+      {+        xx1 -= w - warper->w0;+        if ( xx1 < warper->x1min )+        {+          xx2 += warper->x1min - xx1;+          xx1  = warper->x1min;+        }+      }+      else+      {+        xx1 -= w - warper->w0;+        if ( xx1 > warper->x1max )+        {+          xx2 -= xx1 - warper->x1max;+          xx1  = warper->x1max;+        }+      }++      if ( xx1 < warper->x1 )+        base_distort = warper->x1 - xx1;+      else+        base_distort = xx1 - warper->x1;++      if ( xx2 < warper->x2 )+        base_distort += warper->x2 - xx2;+      else+        base_distort += xx2 - warper->x2;++      base_distort *= 10;++      new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );+      new_delta = xx1 - FT_MulFix( X1, new_scale );++      af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2,+                                   base_distort,+                                   segments, num_segments );+    }++    {+      FT_Fixed  best_scale = warper->best_scale;+      FT_Pos    best_delta = warper->best_delta;+     ++      hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale )+                          + best_delta;+      hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale )+                          + best_delta;++      *a_scale = best_scale;+      *a_delta = best_delta;+    }+  }++#else /* !AF_USE_WARPER */++char  af_warper_dummy = 0;  /* make compiler happy */++#endif /* !AF_USE_WARPER */++/* END */
+ src/autofit/afwarp.h view
@@ -0,0 +1,64 @@+/***************************************************************************/+/*                                                                         */+/*  afwarp.h                                                               */+/*                                                                         */+/*    Auto-fitter warping algorithm (specification).                       */+/*                                                                         */+/*  Copyright 2006, 2007 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFWARP_H__+#define __AFWARP_H__++#include "afhints.h"++FT_BEGIN_HEADER++#define AF_WARPER_SCALE++#define AF_WARPER_FLOOR( x )  ( (x) & ~63 )+#define AF_WARPER_CEIL( x )   AF_WARPER_FLOOR( (x) + 63 )+++  typedef FT_Int32  AF_WarpScore;++  typedef struct  AF_WarperRec_+  {+    FT_Pos        x1, x2;+    FT_Pos        t1, t2;+    FT_Pos        x1min, x1max;+    FT_Pos        x2min, x2max;+    FT_Pos        w0, wmin, wmax;++    FT_Fixed      best_scale;+    FT_Pos        best_delta;+    AF_WarpScore  best_score;+    AF_WarpScore  best_distort;++  } AF_WarperRec, *AF_Warper;+++  FT_LOCAL( void )+  af_warper_compute( AF_Warper      warper,+                     AF_GlyphHints  hints,+                     AF_Dimension   dim,+                     FT_Fixed      *a_scale,+                     FT_Fixed      *a_delta );+++FT_END_HEADER+++#endif /* __AFWARP_H__ */+++/* END */
+ src/autofit/autofit.c view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  autofit.c                                                              */+/*                                                                         */+/*    Auto-fitter module (body).                                           */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT+#include <ft2build.h>+#include "afpic.c"+#include "afangles.c"+#include "afglobal.c"+#include "afhints.c"++#include "afdummy.c"+#include "aflatin.c"+#ifdef FT_OPTION_AUTOFIT2+#include "aflatin2.c"+#endif+#include "afcjk.c"+#include "afindic.c"++#include "afloader.c"+#include "afmodule.c"++#ifdef AF_USE_WARPER+#include "afwarp.c"+#endif++/* END */
+ src/base/basepic.c view
@@ -0,0 +1,83 @@+/***************************************************************************/+/*                                                                         */+/*  basepic.c                                                              */+/*                                                                         */+/*    The FreeType position independent code services for base.            */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "basepic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from ftglyph.c */+  void FT_Init_Class_ft_outline_glyph_class(FT_Glyph_Class*);+  void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*);++  /* forward declaration of PIC init functions from ftinit.c */+  FT_Error ft_create_default_module_classes(FT_Library);+  void ft_destroy_default_module_classes(FT_Library);++  void+  ft_base_pic_free( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory    memory = library->memory;+    if ( pic_container->base )+    {+      /* Destroy default module classes (in case FT_Add_Default_Modules was used) */+      ft_destroy_default_module_classes( library );++      FT_FREE( pic_container->base );+      pic_container->base = NULL;+    }+  }+++  FT_Error+  ft_base_pic_init( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Error        error = FT_Err_Ok;+    BasePIC*     container;+    FT_Memory    memory = library->memory;++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof(*container) );+    pic_container->base = container;++    /* initialize default modules list and pointers */+    error = ft_create_default_module_classes( library );+    if ( error )+      goto Exit;++    /* initialize pointer table - this is how the module usually expects this data */+    FT_Init_Class_ft_outline_glyph_class(&container->ft_outline_glyph_class);+    FT_Init_Class_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class);++Exit:+    if(error)+      ft_base_pic_free(library);+    return error;+  }+++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/base/basepic.h view
@@ -0,0 +1,62 @@+/***************************************************************************/+/*                                                                         */+/*  basepic.h                                                              */+/*                                                                         */+/*    The FreeType position independent code services for base.            */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __BASEPIC_H__+#define __BASEPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC+#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class+#define FT_BITMAP_GLYPH_CLASS_GET  &ft_bitmap_glyph_class+#define FT_DEFAULT_MODULES_GET     ft_default_modules++#else /* FT_CONFIG_OPTION_PIC */++#include FT_GLYPH_H++  typedef struct BasePIC_+  {+    FT_Module_Class** default_module_classes;+    FT_Glyph_Class ft_outline_glyph_class;+    FT_Glyph_Class ft_bitmap_glyph_class;+  } BasePIC;++#define GET_PIC(lib)                  ((BasePIC*)((lib)->pic_container.base))+#define FT_OUTLINE_GLYPH_CLASS_GET    (&GET_PIC(library)->ft_outline_glyph_class)+#define FT_BITMAP_GLYPH_CLASS_GET     (&GET_PIC(library)->ft_bitmap_glyph_class)+#define FT_DEFAULT_MODULES_GET        (GET_PIC(library)->default_module_classes)++  void+  ft_base_pic_free( FT_Library library );++  FT_Error+  ft_base_pic_init( FT_Library library );++#endif /* FT_CONFIG_OPTION_PIC */+ /* */++FT_END_HEADER++#endif /* __BASEPIC_H__ */+++/* END */
+ src/base/ftadvanc.c view
@@ -0,0 +1,163 @@+/***************************************************************************/+/*                                                                         */+/*  ftadvanc.c                                                             */+/*                                                                         */+/*    Quick computation of advance widths (body).                          */+/*                                                                         */+/*  Copyright 2008, 2009 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_ADVANCES_H+#include FT_INTERNAL_OBJECTS_H+++  static FT_Error+  _ft_face_scale_advances( FT_Face    face,+                           FT_Fixed*  advances,+                           FT_UInt    count,+                           FT_Int32   flags )+  {+    FT_Fixed  scale;+    FT_UInt   nn;+++    if ( flags & FT_LOAD_NO_SCALE )+      return FT_Err_Ok;++    if ( face->size == NULL )+      return FT_Err_Invalid_Size_Handle;++    if ( flags & FT_LOAD_VERTICAL_LAYOUT )+      scale = face->size->metrics.y_scale;+    else+      scale = face->size->metrics.x_scale;++    /* this must be the same scaling as to get linear{Hori,Vert}Advance */+    /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c)        */++    for ( nn = 0; nn < count; nn++ )+      advances[nn] = FT_MulDiv( advances[nn], scale, 64 );++    return FT_Err_Ok;+  }+++   /* at the moment, we can perform fast advance retrieval only in */+   /* the following cases:                                         */+   /*                                                              */+   /*  - unscaled load                                             */+   /*  - unhinted load                                             */+   /*  - light-hinted load                                         */++#define LOAD_ADVANCE_FAST_CHECK( flags )                            \+          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \+            FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )+++  /* documentation is in ftadvanc.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Advance( FT_Face    face,+                  FT_UInt    gindex,+                  FT_Int32   flags,+                  FT_Fixed  *padvance )+  {+    FT_Face_GetAdvancesFunc  func;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( gindex >= (FT_UInt)face->num_glyphs )+      return FT_Err_Invalid_Glyph_Index;++    func = face->driver->clazz->get_advances;+    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )+    {+      FT_Error  error;+++      error = func( face, gindex, 1, flags, padvance );+      if ( !error )+        return _ft_face_scale_advances( face, padvance, 1, flags );++      if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )+        return error;+    }++    return FT_Get_Advances( face, gindex, 1, flags, padvance );+  }+++  /* documentation is in ftadvanc.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Advances( FT_Face    face,+                   FT_UInt    start,+                   FT_UInt    count,+                   FT_Int32   flags,+                   FT_Fixed  *padvances )+  {+    FT_Face_GetAdvancesFunc  func;+    FT_UInt                  num, end, nn;+    FT_Error                 error = FT_Err_Ok;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    num = (FT_UInt)face->num_glyphs;+    end = start + count;+    if ( start >= num || end < start || end > num )+      return FT_Err_Invalid_Glyph_Index;++    if ( count == 0 )+      return FT_Err_Ok;++    func = face->driver->clazz->get_advances;+    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )+    {+      error = func( face, start, count, flags, padvances );+      if ( !error )+        goto Exit;++      if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )+        return error;+    }++    error = FT_Err_Ok;++    if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )+      return FT_Err_Unimplemented_Feature;++    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;+    for ( nn = 0; nn < count; nn++ )+    {+      error = FT_Load_Glyph( face, start + nn, flags );+      if ( error )+        break;++      padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )+                      ? face->glyph->advance.y+                      : face->glyph->advance.x;+    }++    if ( error )+      return error;++  Exit:+    return _ft_face_scale_advances( face, padvances, count, flags );+  }+++/* END */
+ src/base/ftapi.c view
@@ -0,0 +1,121 @@+/***************************************************************************/+/*                                                                         */+/*  ftapi.c                                                                */+/*                                                                         */+/*    The FreeType compatibility functions (body).                         */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_LIST_H+#include FT_OUTLINE_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TABLES_H+#include FT_OUTLINE_H+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                 C O M P A T I B I L I T Y                       ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /* backwards compatibility API */++  FT_BASE_DEF( void )+  FT_New_Memory_Stream( FT_Library  library,+                        FT_Byte*    base,+                        FT_ULong    size,+                        FT_Stream   stream )+  {+    FT_UNUSED( library );++    FT_Stream_OpenMemory( stream, base, size );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Seek_Stream( FT_Stream  stream,+                  FT_ULong   pos )+  {+    return FT_Stream_Seek( stream, pos );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Skip_Stream( FT_Stream  stream,+                  FT_Long    distance )+  {+    return FT_Stream_Skip( stream, distance );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Read_Stream( FT_Stream  stream,+                  FT_Byte*   buffer,+                  FT_ULong   count )+  {+    return FT_Stream_Read( stream, buffer, count );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Read_Stream_At( FT_Stream  stream,+                     FT_ULong   pos,+                     FT_Byte*   buffer,+                     FT_ULong   count )+  {+    return FT_Stream_ReadAt( stream, pos, buffer, count );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Extract_Frame( FT_Stream  stream,+                    FT_ULong   count,+                    FT_Byte**  pbytes )+  {+    return FT_Stream_ExtractFrame( stream, count, pbytes );+  }+++  FT_BASE_DEF( void )+  FT_Release_Frame( FT_Stream  stream,+                    FT_Byte**  pbytes )+  {+    FT_Stream_ReleaseFrame( stream, pbytes );+  }++  FT_BASE_DEF( FT_Error )+  FT_Access_Frame( FT_Stream  stream,+                   FT_ULong   count )+  {+    return FT_Stream_EnterFrame( stream, count );+  }+++  FT_BASE_DEF( void )+  FT_Forget_Frame( FT_Stream  stream )+  {+    FT_Stream_ExitFrame( stream );+  }+++/* END */
+ src/base/ftbase.c view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  ftbase.c                                                               */+/*                                                                         */+/*    Single object library component (body only).                         */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>++#define  FT_MAKE_OPTION_SINGLE_OBJECT++#include "ftpic.c"+#include "basepic.c"+#include "ftadvanc.c"+#include "ftcalc.c"+#include "ftdbgmem.c"+#include "ftgloadr.c"+#include "ftobjs.c"+#include "ftoutln.c"+#include "ftrfork.c"+#include "ftsnames.c"+#include "ftstream.c"+#include "fttrigon.c"+#include "ftutil.c"++#if defined( FT_MACINTOSH ) && !defined ( DARWIN_NO_CARBON )+#include "ftmac.c"+#endif++/* END */
+ src/base/ftbase.h view
@@ -0,0 +1,68 @@+/***************************************************************************/+/*                                                                         */+/*  ftbase.h                                                               */+/*                                                                         */+/*    The FreeType private functions used in base module (specification).  */+/*                                                                         */+/*  Copyright 2008, 2010 by                                                */+/*  David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTBASE_H__+#define __FTBASE_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++  /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */+  /* font, and try to load a face specified by the face_index.            */+  FT_LOCAL( FT_Error )+  open_face_PS_from_sfnt_stream( FT_Library     library,+                                 FT_Stream      stream,+                                 FT_Long        face_index,+                                 FT_Int         num_params,+                                 FT_Parameter  *params,+                                 FT_Face       *aface );+++  /* Create a new FT_Face given a buffer and a driver name. */+  /* From ftmac.c.                                          */+  FT_LOCAL( FT_Error )+  open_face_from_buffer( FT_Library   library,+                         FT_Byte*     base,+                         FT_ULong     size,+                         FT_Long      face_index,+                         const char*  driver_name,+                         FT_Face     *aface );+++#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK+  /* Mac OS X/Darwin kernel often changes recommended method to access */+  /* the resource fork and older methods makes the kernel issue the    */+  /* warning of deprecated method.  To calm it down, the methods based */+  /* on Darwin VFS should be grouped and skip the rest methods after   */+  /* the case the resource is opened but found to lack a font in it.   */+  FT_LOCAL( FT_Bool )+  raccess_rule_by_darwin_vfs( FT_UInt  rule_index );+#endif /* FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */+++FT_END_HEADER++#endif /* __FTBASE_H__ */+++/* END */
+ src/base/ftbbox.c view
@@ -0,0 +1,662 @@+/***************************************************************************/+/*                                                                         */+/*  ftbbox.c                                                               */+/*                                                                         */+/*    FreeType bbox computation (body).                                    */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2006, 2010 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used        */+/*  modified and distributed under the terms of the FreeType project       */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This component has a _single_ role: to compute exact outline bounding */+  /* boxes.                                                                */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_BBOX_H+#include FT_IMAGE_H+#include FT_OUTLINE_H+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_OBJECTS_H+++  typedef struct  TBBox_Rec_+  {+    FT_Vector  last;+    FT_BBox    bbox;++  } TBBox_Rec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    BBox_Move_To                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used as a `move_to' and `line_to' emitter during  */+  /*    FT_Outline_Decompose().  It simply records the destination point   */+  /*    in `user->last'; no further computations are necessary since we    */+  /*    use the cbox as the starting bbox which must be refined.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    to   :: A pointer to the destination vector.                       */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    user :: A pointer to the current walk context.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Always 0.  Needed for the interface only.                          */+  /*                                                                       */+  static int+  BBox_Move_To( FT_Vector*  to,+                TBBox_Rec*  user )+  {+    user->last = *to;++    return 0;+  }+++#define CHECK_X( p, bbox )  \+          ( p->x < bbox.xMin || p->x > bbox.xMax )++#define CHECK_Y( p, bbox )  \+          ( p->y < bbox.yMin || p->y > bbox.yMax )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    BBox_Conic_Check                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finds the extrema of a 1-dimensional conic Bezier curve and update */+  /*    a bounding range.  This version uses direct computation, as it     */+  /*    doesn't need square roots.                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    y1  :: The start coordinate.                                       */+  /*                                                                       */+  /*    y2  :: The coordinate of the control point.                        */+  /*                                                                       */+  /*    y3  :: The end coordinate.                                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    min :: The address of the current minimum.                         */+  /*                                                                       */+  /*    max :: The address of the current maximum.                         */+  /*                                                                       */+  static void+  BBox_Conic_Check( FT_Pos   y1,+                    FT_Pos   y2,+                    FT_Pos   y3,+                    FT_Pos*  min,+                    FT_Pos*  max )+  {+    if ( y1 <= y3 && y2 == y1 )     /* flat arc */+      goto Suite;++    if ( y1 < y3 )+    {+      if ( y2 >= y1 && y2 <= y3 )   /* ascending arc */+        goto Suite;+    }+    else+    {+      if ( y2 >= y3 && y2 <= y1 )   /* descending arc */+      {+        y2 = y1;+        y1 = y3;+        y3 = y2;+        goto Suite;+      }+    }++    y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 );++  Suite:+    if ( y1 < *min ) *min = y1;+    if ( y3 > *max ) *max = y3;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    BBox_Conic_To                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used as a `conic_to' emitter during               */+  /*    FT_Outline_Decompose().  It checks a conic Bezier curve with the   */+  /*    current bounding box, and computes its extrema if necessary to     */+  /*    update it.                                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    control :: A pointer to a control point.                           */+  /*                                                                       */+  /*    to      :: A pointer to the destination vector.                    */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    user    :: The address of the current walk context.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Always 0.  Needed for the interface only.                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    In the case of a non-monotonous arc, we compute directly the       */+  /*    extremum coordinates, as it is sufficiently fast.                  */+  /*                                                                       */+  static int+  BBox_Conic_To( FT_Vector*  control,+                 FT_Vector*  to,+                 TBBox_Rec*  user )+  {+    /* we don't need to check `to' since it is always an `on' point, thus */+    /* within the bbox                                                    */++    if ( CHECK_X( control, user->bbox ) )+      BBox_Conic_Check( user->last.x,+                        control->x,+                        to->x,+                        &user->bbox.xMin,+                        &user->bbox.xMax );++    if ( CHECK_Y( control, user->bbox ) )+      BBox_Conic_Check( user->last.y,+                        control->y,+                        to->y,+                        &user->bbox.yMin,+                        &user->bbox.yMax );++    user->last = *to;++    return 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    BBox_Cubic_Check                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finds the extrema of a 1-dimensional cubic Bezier curve and        */+  /*    updates a bounding range.  This version uses splitting because we  */+  /*    don't want to use square roots and extra accuracy.                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    p1  :: The start coordinate.                                       */+  /*                                                                       */+  /*    p2  :: The coordinate of the first control point.                  */+  /*                                                                       */+  /*    p3  :: The coordinate of the second control point.                 */+  /*                                                                       */+  /*    p4  :: The end coordinate.                                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    min :: The address of the current minimum.                         */+  /*                                                                       */+  /*    max :: The address of the current maximum.                         */+  /*                                                                       */++#if 0++  static void+  BBox_Cubic_Check( FT_Pos   p1,+                    FT_Pos   p2,+                    FT_Pos   p3,+                    FT_Pos   p4,+                    FT_Pos*  min,+                    FT_Pos*  max )+  {+    FT_Pos  stack[32*3 + 1], *arc;+++    arc = stack;++    arc[0] = p1;+    arc[1] = p2;+    arc[2] = p3;+    arc[3] = p4;++    do+    {+      FT_Pos  y1 = arc[0];+      FT_Pos  y2 = arc[1];+      FT_Pos  y3 = arc[2];+      FT_Pos  y4 = arc[3];+++      if ( y1 == y4 )+      {+        if ( y1 == y2 && y1 == y3 )                         /* flat */+          goto Test;+      }+      else if ( y1 < y4 )+      {+        if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */+          goto Test;+      }+      else+      {+        if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */+        {+          y2 = y1;+          y1 = y4;+          y4 = y2;+          goto Test;+        }+      }++      /* unknown direction -- split the arc in two */+      arc[6] = y4;+      arc[1] = y1 = ( y1 + y2 ) / 2;+      arc[5] = y4 = ( y4 + y3 ) / 2;+      y2 = ( y2 + y3 ) / 2;+      arc[2] = y1 = ( y1 + y2 ) / 2;+      arc[4] = y4 = ( y4 + y2 ) / 2;+      arc[3] = ( y1 + y4 ) / 2;++      arc += 3;+      goto Suite;++   Test:+      if ( y1 < *min ) *min = y1;+      if ( y4 > *max ) *max = y4;+      arc -= 3;++    Suite:+      ;+    } while ( arc >= stack );+  }++#else++  static void+  test_cubic_extrema( FT_Pos    y1,+                      FT_Pos    y2,+                      FT_Pos    y3,+                      FT_Pos    y4,+                      FT_Fixed  u,+                      FT_Pos*   min,+                      FT_Pos*   max )+  {+ /* FT_Pos    a = y4 - 3*y3 + 3*y2 - y1; */+    FT_Pos    b = y3 - 2*y2 + y1;+    FT_Pos    c = y2 - y1;+    FT_Pos    d = y1;+    FT_Pos    y;+    FT_Fixed  uu;++    FT_UNUSED ( y4 );+++    /* The polynomial is                      */+    /*                                        */+    /*    P(x) = a*x^3 + 3b*x^2 + 3c*x + d  , */+    /*                                        */+    /*   dP/dx = 3a*x^2 + 6b*x + 3c         . */+    /*                                        */+    /* However, we also have                  */+    /*                                        */+    /*   dP/dx(u) = 0                       , */+    /*                                        */+    /* which implies by subtraction that      */+    /*                                        */+    /*   P(u) = b*u^2 + 2c*u + d            . */++    if ( u > 0 && u < 0x10000L )+    {+      uu = FT_MulFix( u, u );+      y  = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu );++      if ( y < *min ) *min = y;+      if ( y > *max ) *max = y;+    }+  }+++  static void+  BBox_Cubic_Check( FT_Pos   y1,+                    FT_Pos   y2,+                    FT_Pos   y3,+                    FT_Pos   y4,+                    FT_Pos*  min,+                    FT_Pos*  max )+  {+    /* always compare first and last points */+    if      ( y1 < *min )  *min = y1;+    else if ( y1 > *max )  *max = y1;++    if      ( y4 < *min )  *min = y4;+    else if ( y4 > *max )  *max = y4;++    /* now, try to see if there are split points here */+    if ( y1 <= y4 )+    {+      /* flat or ascending arc test */+      if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 )+        return;+    }+    else /* y1 > y4 */+    {+      /* descending arc test */+      if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 )+        return;+    }++    /* There are some split points.  Find them. */+    {+      FT_Pos    a = y4 - 3*y3 + 3*y2 - y1;+      FT_Pos    b = y3 - 2*y2 + y1;+      FT_Pos    c = y2 - y1;+      FT_Pos    d;+      FT_Fixed  t;+++      /* We need to solve `ax^2+2bx+c' here, without floating points!      */+      /* The trick is to normalize to a different representation in order  */+      /* to use our 16.16 fixed point routines.                            */+      /*                                                                   */+      /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */+      /* These values must fit into a single 16.16 value.                  */+      /*                                                                   */+      /* We normalize a, b, and c to `8.16' fixed float values to ensure   */+      /* that its product is held in a `16.16' value.                      */++      {+        FT_ULong  t1, t2;+        int       shift = 0;+++        /* The following computation is based on the fact that for   */+        /* any value `y', if `n' is the position of the most         */+        /* significant bit of `abs(y)' (starting from 0 for the      */+        /* least significant bit), then `y' is in the range          */+        /*                                                           */+        /*   -2^n..2^n-1                                             */+        /*                                                           */+        /* We want to shift `a', `b', and `c' concurrently in order  */+        /* to ensure that they all fit in 8.16 values, which maps    */+        /* to the integer range `-2^23..2^23-1'.                     */+        /*                                                           */+        /* Necessarily, we need to shift `a', `b', and `c' so that   */+        /* the most significant bit of its absolute values is at     */+        /* _most_ at position 23.                                    */+        /*                                                           */+        /* We begin by computing `t1' as the bitwise `OR' of the     */+        /* absolute values of `a', `b', `c'.                         */++        t1  = (FT_ULong)( ( a >= 0 ) ? a : -a );+        t2  = (FT_ULong)( ( b >= 0 ) ? b : -b );+        t1 |= t2;+        t2  = (FT_ULong)( ( c >= 0 ) ? c : -c );+        t1 |= t2;++        /* Now we can be sure that the most significant bit of `t1'  */+        /* is the most significant bit of either `a', `b', or `c',   */+        /* depending on the greatest integer range of the particular */+        /* variable.                                                 */+        /*                                                           */+        /* Next, we compute the `shift', by shifting `t1' as many    */+        /* times as necessary to move its MSB to position 23.  This  */+        /* corresponds to a value of `t1' that is in the range       */+        /* 0x40_0000..0x7F_FFFF.                                     */+        /*                                                           */+        /* Finally, we shift `a', `b', and `c' by the same amount.   */+        /* This ensures that all values are now in the range         */+        /* -2^23..2^23, i.e., they are now expressed as 8.16         */+        /* fixed-float numbers.  This also means that we are using   */+        /* 24 bits of precision to compute the zeros, independently  */+        /* of the range of the original polynomial coefficients.     */+        /*                                                           */+        /* This algorithm should ensure reasonably accurate values   */+        /* for the zeros.  Note that they are only expressed with    */+        /* 16 bits when computing the extrema (the zeros need to     */+        /* be in 0..1 exclusive to be considered part of the arc).   */++        if ( t1 == 0 )  /* all coefficients are 0! */+          return;++        if ( t1 > 0x7FFFFFUL )+        {+          do+          {+            shift++;+            t1 >>= 1;++          } while ( t1 > 0x7FFFFFUL );++          /* this loses some bits of precision, but we use 24 of them */+          /* for the computation anyway                               */+          a >>= shift;+          b >>= shift;+          c >>= shift;+        }+        else if ( t1 < 0x400000UL )+        {+          do+          {+            shift++;+            t1 <<= 1;++          } while ( t1 < 0x400000UL );++          a <<= shift;+          b <<= shift;+          c <<= shift;+        }+      }++      /* handle a == 0 */+      if ( a == 0 )+      {+        if ( b != 0 )+        {+          t = - FT_DivFix( c, b ) / 2;+          test_cubic_extrema( y1, y2, y3, y4, t, min, max );+        }+      }+      else+      {+        /* solve the equation now */+        d = FT_MulFix( b, b ) - FT_MulFix( a, c );+        if ( d < 0 )+          return;++        if ( d == 0 )+        {+          /* there is a single split point at -b/a */+          t = - FT_DivFix( b, a );+          test_cubic_extrema( y1, y2, y3, y4, t, min, max );+        }+        else+        {+          /* there are two solutions; we need to filter them */+          d = FT_SqrtFixed( (FT_Int32)d );+          t = - FT_DivFix( b - d, a );+          test_cubic_extrema( y1, y2, y3, y4, t, min, max );++          t = - FT_DivFix( b + d, a );+          test_cubic_extrema( y1, y2, y3, y4, t, min, max );+        }+      }+    }+  }++#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    BBox_Cubic_To                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used as a `cubic_to' emitter during               */+  /*    FT_Outline_Decompose().  It checks a cubic Bezier curve with the   */+  /*    current bounding box, and computes its extrema if necessary to     */+  /*    update it.                                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    control1 :: A pointer to the first control point.                  */+  /*                                                                       */+  /*    control2 :: A pointer to the second control point.                 */+  /*                                                                       */+  /*    to       :: A pointer to the destination vector.                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    user     :: The address of the current walk context.               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Always 0.  Needed for the interface only.                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    In the case of a non-monotonous arc, we don't compute directly     */+  /*    extremum coordinates, we subdivide instead.                        */+  /*                                                                       */+  static int+  BBox_Cubic_To( FT_Vector*  control1,+                 FT_Vector*  control2,+                 FT_Vector*  to,+                 TBBox_Rec*  user )+  {+    /* we don't need to check `to' since it is always an `on' point, thus */+    /* within the bbox                                                    */++    if ( CHECK_X( control1, user->bbox ) ||+         CHECK_X( control2, user->bbox ) )+      BBox_Cubic_Check( user->last.x,+                        control1->x,+                        control2->x,+                        to->x,+                        &user->bbox.xMin,+                        &user->bbox.xMax );++    if ( CHECK_Y( control1, user->bbox ) ||+         CHECK_Y( control2, user->bbox ) )+      BBox_Cubic_Check( user->last.y,+                        control1->y,+                        control2->y,+                        to->y,+                        &user->bbox.yMin,+                        &user->bbox.yMax );++    user->last = *to;++    return 0;+  }++FT_DEFINE_OUTLINE_FUNCS(bbox_interface,+    (FT_Outline_MoveTo_Func) BBox_Move_To,+    (FT_Outline_LineTo_Func) BBox_Move_To,+    (FT_Outline_ConicTo_Func)BBox_Conic_To,+    (FT_Outline_CubicTo_Func)BBox_Cubic_To,+    0, 0+  )++  /* documentation is in ftbbox.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Get_BBox( FT_Outline*  outline,+                       FT_BBox     *abbox )+  {+    FT_BBox     cbox;+    FT_BBox     bbox;+    FT_Vector*  vec;+    FT_UShort   n;+++    if ( !abbox )+      return FT_Err_Invalid_Argument;++    if ( !outline )+      return FT_Err_Invalid_Outline;++    /* if outline is empty, return (0,0,0,0) */+    if ( outline->n_points == 0 || outline->n_contours <= 0 )+    {+      abbox->xMin = abbox->xMax = 0;+      abbox->yMin = abbox->yMax = 0;+      return 0;+    }++    /* We compute the control box as well as the bounding box of  */+    /* all `on' points in the outline.  Then, if the two boxes    */+    /* coincide, we exit immediately.                             */++    vec = outline->points;+    bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x;+    bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y;+    vec++;++    for ( n = 1; n < outline->n_points; n++ )+    {+      FT_Pos  x = vec->x;+      FT_Pos  y = vec->y;+++      /* update control box */+      if ( x < cbox.xMin ) cbox.xMin = x;+      if ( x > cbox.xMax ) cbox.xMax = x;++      if ( y < cbox.yMin ) cbox.yMin = y;+      if ( y > cbox.yMax ) cbox.yMax = y;++      if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )+      {+        /* update bbox for `on' points only */+        if ( x < bbox.xMin ) bbox.xMin = x;+        if ( x > bbox.xMax ) bbox.xMax = x;++        if ( y < bbox.yMin ) bbox.yMin = y;+        if ( y > bbox.yMax ) bbox.yMax = y;+      }++      vec++;+    }++    /* test two boxes for equality */+    if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||+         cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )+    {+      /* the two boxes are different, now walk over the outline to */+      /* get the Bezier arc extrema.                               */++      FT_Error   error;+      TBBox_Rec  user;++#ifdef FT_CONFIG_OPTION_PIC+      FT_Outline_Funcs bbox_interface;+      Init_Class_bbox_interface(&bbox_interface);+#endif++      user.bbox = bbox;++      error = FT_Outline_Decompose( outline, &bbox_interface, &user );+      if ( error )+        return error;++      *abbox = user.bbox;+    }+    else+      *abbox = bbox;++    return FT_Err_Ok;+  }+++/* END */
+ src/base/ftbdf.c view
@@ -0,0 +1,88 @@+/***************************************************************************/+/*                                                                         */+/*  ftbdf.c                                                                */+/*                                                                         */+/*    FreeType API for accessing BDF-specific strings (body).              */+/*                                                                         */+/*  Copyright 2002, 2003, 2004 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_BDF_H+++  /* documentation is in ftbdf.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_BDF_Charset_ID( FT_Face       face,+                         const char*  *acharset_encoding,+                         const char*  *acharset_registry )+  {+    FT_Error     error;+    const char*  encoding = NULL;+    const char*  registry = NULL;+++    error = FT_Err_Invalid_Argument;++    if ( face )+    {+      FT_Service_BDF  service;+++      FT_FACE_FIND_SERVICE( face, service, BDF );++      if ( service && service->get_charset_id )+        error = service->get_charset_id( face, &encoding, &registry );+    }++    if ( acharset_encoding )+      *acharset_encoding = encoding;++    if ( acharset_registry )+      *acharset_registry = registry;++    return error;+  }+++  /* documentation is in ftbdf.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_BDF_Property( FT_Face           face,+                       const char*       prop_name,+                       BDF_PropertyRec  *aproperty )+  {+    FT_Error  error;+++    error = FT_Err_Invalid_Argument;++    aproperty->type = BDF_PROPERTY_TYPE_NONE;++    if ( face )+    {+      FT_Service_BDF  service;+++      FT_FACE_FIND_SERVICE( face, service, BDF );++      if ( service && service->get_property )+        error = service->get_property( face, prop_name, aproperty );+    }++    return  error;+  }+++/* END */
+ src/base/ftbitmap.c view
@@ -0,0 +1,663 @@+/***************************************************************************/+/*                                                                         */+/*  ftbitmap.c                                                             */+/*                                                                         */+/*    FreeType utility functions for bitmaps (body).                       */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_BITMAP_H+#include FT_IMAGE_H+#include FT_INTERNAL_OBJECTS_H+++  static+  const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( void )+  FT_Bitmap_New( FT_Bitmap  *abitmap )+  {+    *abitmap = null_bitmap;+  }+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Bitmap_Copy( FT_Library        library,+                  const FT_Bitmap  *source,+                  FT_Bitmap        *target)+  {+    FT_Memory  memory = library->memory;+    FT_Error   error  = FT_Err_Ok;+    FT_Int     pitch  = source->pitch;+    FT_ULong   size;+++    if ( source == target )+      return FT_Err_Ok;++    if ( source->buffer == NULL )+    {+      *target = *source;++      return FT_Err_Ok;+    }++    if ( pitch < 0 )+      pitch = -pitch;+    size = (FT_ULong)( pitch * source->rows );++    if ( target->buffer )+    {+      FT_Int    target_pitch = target->pitch;+      FT_ULong  target_size;+++      if ( target_pitch < 0  )+        target_pitch = -target_pitch;+      target_size = (FT_ULong)( target_pitch * target->rows );++      if ( target_size != size )+        (void)FT_QREALLOC( target->buffer, target_size, size );+    }+    else+      (void)FT_QALLOC( target->buffer, size );++    if ( !error )+    {+      unsigned char *p;+++      p = target->buffer;+      *target = *source;+      target->buffer = p;++      FT_MEM_COPY( target->buffer, source->buffer, size );+    }++    return error;+  }+++  static FT_Error+  ft_bitmap_assure_buffer( FT_Memory   memory,+                           FT_Bitmap*  bitmap,+                           FT_UInt     xpixels,+                           FT_UInt     ypixels )+  {+    FT_Error        error;+    int             pitch;+    int             new_pitch;+    FT_UInt         bpp;+    FT_Int          i, width, height;+    unsigned char*  buffer;+++    width  = bitmap->width;+    height = bitmap->rows;+    pitch  = bitmap->pitch;+    if ( pitch < 0 )+      pitch = -pitch;++    switch ( bitmap->pixel_mode )+    {+    case FT_PIXEL_MODE_MONO:+      bpp       = 1;+      new_pitch = ( width + xpixels + 7 ) >> 3;+      break;+    case FT_PIXEL_MODE_GRAY2:+      bpp       = 2;+      new_pitch = ( width + xpixels + 3 ) >> 2;+      break;+    case FT_PIXEL_MODE_GRAY4:+      bpp       = 4;+      new_pitch = ( width + xpixels + 1 ) >> 1;+      break;+    case FT_PIXEL_MODE_GRAY:+    case FT_PIXEL_MODE_LCD:+    case FT_PIXEL_MODE_LCD_V:+      bpp       = 8;+      new_pitch = ( width + xpixels );+      break;+    default:+      return FT_Err_Invalid_Glyph_Format;+    }++    /* if no need to allocate memory */+    if ( ypixels == 0 && new_pitch <= pitch )+    {+      /* zero the padding */+      FT_Int  bit_width = pitch * 8;+      FT_Int  bit_last  = ( width + xpixels ) * bpp;+++      if ( bit_last < bit_width )+      {+        FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );+        FT_Byte*  end   = bitmap->buffer + pitch;+        FT_Int    shift = bit_last & 7;+        FT_UInt   mask  = 0xFF00U >> shift;+        FT_Int    count = height;+++        for ( ; count > 0; count--, line += pitch, end += pitch )+        {+          FT_Byte*  write = line;+++          if ( shift > 0 )+          {+            write[0] = (FT_Byte)( write[0] & mask );+            write++;+          }+          if ( write < end )+            FT_MEM_ZERO( write, end-write );+        }+      }++      return FT_Err_Ok;+    }++    if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )+      return error;++    if ( bitmap->pitch > 0 )+    {+      FT_Int  len = ( width * bpp + 7 ) >> 3;+++      for ( i = 0; i < bitmap->rows; i++ )+        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),+                     bitmap->buffer + pitch * i, len );+    }+    else+    {+      FT_Int  len = ( width * bpp + 7 ) >> 3;+++      for ( i = 0; i < bitmap->rows; i++ )+        FT_MEM_COPY( buffer + new_pitch * i,+                     bitmap->buffer + pitch * i, len );+    }++    FT_FREE( bitmap->buffer );+    bitmap->buffer = buffer;++    if ( bitmap->pitch < 0 )+      new_pitch = -new_pitch;++    /* set pitch only, width and height are left untouched */+    bitmap->pitch = new_pitch;++    return FT_Err_Ok;+  }+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Bitmap_Embolden( FT_Library  library,+                      FT_Bitmap*  bitmap,+                      FT_Pos      xStrength,+                      FT_Pos      yStrength )+  {+    FT_Error        error;+    unsigned char*  p;+    FT_Int          i, x, y, pitch;+    FT_Int          xstr, ystr;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !bitmap || !bitmap->buffer )+      return FT_Err_Invalid_Argument;++    if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||+         ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )+      return FT_Err_Invalid_Argument;+       +    xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;+    ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;++    if ( xstr == 0 && ystr == 0 )+      return FT_Err_Ok;+    else if ( xstr < 0 || ystr < 0 )+      return FT_Err_Invalid_Argument;++    switch ( bitmap->pixel_mode )+    {+    case FT_PIXEL_MODE_GRAY2:+    case FT_PIXEL_MODE_GRAY4:+      {+        FT_Bitmap  tmp;+        FT_Int     align;+++        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )+          align = ( bitmap->width + xstr + 3 ) / 4;+        else+          align = ( bitmap->width + xstr + 1 ) / 2;++        FT_Bitmap_New( &tmp );++        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );+        if ( error )+          return error;++        FT_Bitmap_Done( library, bitmap );+        *bitmap = tmp;+      }+      break;++    case FT_PIXEL_MODE_MONO:+      if ( xstr > 8 )+        xstr = 8;+      break;++    case FT_PIXEL_MODE_LCD:+      xstr *= 3;+      break;++    case FT_PIXEL_MODE_LCD_V:+      ystr *= 3;+      break;+    }++    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );+    if ( error )+      return error;++    pitch = bitmap->pitch;+    if ( pitch > 0 )+      p = bitmap->buffer + pitch * ystr;+    else+    {+      pitch = -pitch;+      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );+    }++    /* for each row */+    for ( y = 0; y < bitmap->rows ; y++ )+    {+      /*+       * Horizontally:+       *+       * From the last pixel on, make each pixel or'ed with the+       * `xstr' pixels before it.+       */+      for ( x = pitch - 1; x >= 0; x-- )+      {+        unsigned char tmp;+++        tmp = p[x];+        for ( i = 1; i <= xstr; i++ )+        {+          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )+          {+            p[x] |= tmp >> i;++            /* the maximum value of 8 for `xstr' comes from here */+            if ( x > 0 )+              p[x] |= p[x - 1] << ( 8 - i );++#if 0+            if ( p[x] == 0xff )+              break;+#endif+          }+          else+          {+            if ( x - i >= 0 )+            {+              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )+              {+                p[x] = (unsigned char)(bitmap->num_grays - 1);+                break;+              }+              else+              {+                p[x] = (unsigned char)(p[x] + p[x-i]);+                if ( p[x] == bitmap->num_grays - 1 )+                  break;+              }+            }+            else+              break;+          }+        }+      }++      /*+       * Vertically:+       *+       * Make the above `ystr' rows or'ed with it.+       */+      for ( x = 1; x <= ystr; x++ )+      {+        unsigned char*  q;+++        q = p - bitmap->pitch * x;+        for ( i = 0; i < pitch; i++ )+          q[i] |= p[i];+      }++      p += bitmap->pitch;+    }++    bitmap->width += xstr;+    bitmap->rows += ystr;++    return FT_Err_Ok;+  }+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Bitmap_Convert( FT_Library        library,+                     const FT_Bitmap  *source,+                     FT_Bitmap        *target,+                     FT_Int            alignment )+  {+    FT_Error   error = FT_Err_Ok;+    FT_Memory  memory;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    memory = library->memory;++    switch ( source->pixel_mode )+    {+    case FT_PIXEL_MODE_MONO:+    case FT_PIXEL_MODE_GRAY:+    case FT_PIXEL_MODE_GRAY2:+    case FT_PIXEL_MODE_GRAY4:+    case FT_PIXEL_MODE_LCD:+    case FT_PIXEL_MODE_LCD_V:+      {+        FT_Int   pad;+        FT_Long  old_size;+++        old_size = target->rows * target->pitch;+        if ( old_size < 0 )+          old_size = -old_size;++        target->pixel_mode = FT_PIXEL_MODE_GRAY;+        target->rows       = source->rows;+        target->width      = source->width;++        pad = 0;+        if ( alignment > 0 )+        {+          pad = source->width % alignment;+          if ( pad != 0 )+            pad = alignment - pad;+        }++        target->pitch = source->width + pad;++        if ( target->rows * target->pitch > old_size             &&+             FT_QREALLOC( target->buffer,+                          old_size, target->rows * target->pitch ) )+          return error;+      }+      break;++    default:+      error = FT_Err_Invalid_Argument;+    }++    switch ( source->pixel_mode )+    {+    case FT_PIXEL_MODE_MONO:+      {+        FT_Byte*  s = source->buffer;+        FT_Byte*  t = target->buffer;+        FT_Int    i;+++        target->num_grays = 2;++        for ( i = source->rows; i > 0; i-- )+        {+          FT_Byte*  ss = s;+          FT_Byte*  tt = t;+          FT_Int    j;+++          /* get the full bytes */+          for ( j = source->width >> 3; j > 0; j-- )+          {+            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */+++            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );+            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );+            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );+            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );+            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );+            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );+            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );+            tt[7] = (FT_Byte)(   val & 0x01 );++            tt += 8;+            ss += 1;+          }++          /* get remaining pixels (if any) */+          j = source->width & 7;+          if ( j > 0 )+          {+            FT_Int  val = *ss;+++            for ( ; j > 0; j-- )+            {+              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);+              val <<= 1;+              tt   += 1;+            }+          }++          s += source->pitch;+          t += target->pitch;+        }+      }+      break;+++    case FT_PIXEL_MODE_GRAY:+    case FT_PIXEL_MODE_LCD:+    case FT_PIXEL_MODE_LCD_V:+      {+        FT_Int    width   = source->width;+        FT_Byte*  s       = source->buffer;+        FT_Byte*  t       = target->buffer;+        FT_Int    s_pitch = source->pitch;+        FT_Int    t_pitch = target->pitch;+        FT_Int    i;+++        target->num_grays = 256;++        for ( i = source->rows; i > 0; i-- )+        {+          FT_ARRAY_COPY( t, s, width );++          s += s_pitch;+          t += t_pitch;+        }+      }+      break;+++    case FT_PIXEL_MODE_GRAY2:+      {+        FT_Byte*  s = source->buffer;+        FT_Byte*  t = target->buffer;+        FT_Int    i;+++        target->num_grays = 4;++        for ( i = source->rows; i > 0; i-- )+        {+          FT_Byte*  ss = s;+          FT_Byte*  tt = t;+          FT_Int    j;+++          /* get the full bytes */+          for ( j = source->width >> 2; j > 0; j-- )+          {+            FT_Int  val = ss[0];+++            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );+            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );+            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );+            tt[3] = (FT_Byte)( ( val & 0x03 ) );++            ss += 1;+            tt += 4;+          }++          j = source->width & 3;+          if ( j > 0 )+          {+            FT_Int  val = ss[0];+++            for ( ; j > 0; j-- )+            {+              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );+              val  <<= 2;+              tt    += 1;+            }+          }++          s += source->pitch;+          t += target->pitch;+        }+      }+      break;+++    case FT_PIXEL_MODE_GRAY4:+      {+        FT_Byte*  s = source->buffer;+        FT_Byte*  t = target->buffer;+        FT_Int    i;+++        target->num_grays = 16;++        for ( i = source->rows; i > 0; i-- )+        {+          FT_Byte*  ss = s;+          FT_Byte*  tt = t;+          FT_Int    j;+++          /* get the full bytes */+          for ( j = source->width >> 1; j > 0; j-- )+          {+            FT_Int  val = ss[0];+++            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );+            tt[1] = (FT_Byte)( ( val & 0x0F ) );++            ss += 1;+            tt += 2;+          }++          if ( source->width & 1 )+            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );++          s += source->pitch;+          t += target->pitch;+        }+      }+      break;+++    default:+      ;+    }++    return error;+  }+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( FT_Error )+  FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot  slot )+  {+    if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP   &&+         !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )+    {+      FT_Bitmap  bitmap;+      FT_Error   error;+++      FT_Bitmap_New( &bitmap );+      error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );+      if ( error )+        return error;++      slot->bitmap = bitmap;+      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;+    }++    return FT_Err_Ok;+  }+++  /* documentation is in ftbitmap.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Bitmap_Done( FT_Library  library,+                  FT_Bitmap  *bitmap )+  {+    FT_Memory  memory;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !bitmap )+      return FT_Err_Invalid_Argument;++    memory = library->memory;++    FT_FREE( bitmap->buffer );+    *bitmap = null_bitmap;++    return FT_Err_Ok;+  }+++/* END */
+ src/base/ftcalc.c view
@@ -0,0 +1,957 @@+/***************************************************************************/+/*                                                                         */+/*  ftcalc.c                                                               */+/*                                                                         */+/*    Arithmetic computations (body).                                      */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* Support for 1-complement arithmetic has been totally dropped in this  */+  /* release.  You can still write your own code if you need it.           */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* Implementing basic computation routines.                              */+  /*                                                                       */+  /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(),   */+  /* and FT_FloorFix() are declared in freetype.h.                         */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_GLYPH_H+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H++#ifdef FT_MULFIX_INLINED+#undef FT_MulFix+#endif++/* we need to define a 64-bits data type here */++#ifdef FT_LONG64++  typedef FT_INT64  FT_Int64;++#else++  typedef struct  FT_Int64_+  {+    FT_UInt32  lo;+    FT_UInt32  hi;++  } FT_Int64;++#endif /* FT_LONG64 */+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_calc+++  /* The following three functions are available regardless of whether */+  /* FT_LONG64 is defined.                                             */++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_RoundFix( FT_Fixed  a )+  {+    return ( a >= 0 ) ?   ( a + 0x8000L ) & ~0xFFFFL+                      : -((-a + 0x8000L ) & ~0xFFFFL );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_CeilFix( FT_Fixed  a )+  {+    return ( a >= 0 ) ?   ( a + 0xFFFFL ) & ~0xFFFFL+                      : -((-a + 0xFFFFL ) & ~0xFFFFL );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_FloorFix( FT_Fixed  a )+  {+    return ( a >= 0 ) ?   a & ~0xFFFFL+                      : -((-a) & ~0xFFFFL );+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /* documentation is in ftcalc.h */++  FT_EXPORT_DEF( FT_Int32 )+  FT_Sqrt32( FT_Int32  x )+  {+    FT_UInt32  val, root, newroot, mask;+++    root = 0;+    mask = (FT_UInt32)0x40000000UL;+    val  = (FT_UInt32)x;++    do+    {+      newroot = root + mask;+      if ( newroot <= val )+      {+        val -= newroot;+        root = newroot + mask;+      }++      root >>= 1;+      mask >>= 2;++    } while ( mask != 0 );++    return root;+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++#ifdef FT_LONG64+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Long )+  FT_MulDiv( FT_Long  a,+             FT_Long  b,+             FT_Long  c )+  {+    FT_Int   s;+    FT_Long  d;+++    s = 1;+    if ( a < 0 ) { a = -a; s = -1; }+    if ( b < 0 ) { b = -b; s = -s; }+    if ( c < 0 ) { c = -c; s = -s; }++    d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c+                         : 0x7FFFFFFFL );++    return ( s > 0 ) ? d : -d;+  }+++#ifdef TT_USE_BYTECODE_INTERPRETER++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( FT_Long )+  FT_MulDiv_No_Round( FT_Long  a,+                      FT_Long  b,+                      FT_Long  c )+  {+    FT_Int   s;+    FT_Long  d;+++    s = 1;+    if ( a < 0 ) { a = -a; s = -1; }+    if ( b < 0 ) { b = -b; s = -s; }+    if ( c < 0 ) { c = -c; s = -s; }++    d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c+                         : 0x7FFFFFFFL );++    return ( s > 0 ) ? d : -d;+  }++#endif /* TT_USE_BYTECODE_INTERPRETER */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Long )+  FT_MulFix( FT_Long  a,+             FT_Long  b )+  {+#ifdef FT_MULFIX_ASSEMBLER++    return FT_MULFIX_ASSEMBLER( a, b );++#else++    FT_Int   s = 1;+    FT_Long  c;+++    if ( a < 0 )+    {+      a = -a;+      s = -1;+    }++    if ( b < 0 )+    {+      b = -b;+      s = -s;+    }++    c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );++    return ( s > 0 ) ? c : -c;++#endif /* FT_MULFIX_ASSEMBLER */+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Long )+  FT_DivFix( FT_Long  a,+             FT_Long  b )+  {+    FT_Int32   s;+    FT_UInt32  q;++    s = 1;+    if ( a < 0 ) { a = -a; s = -1; }+    if ( b < 0 ) { b = -b; s = -s; }++    if ( b == 0 )+      /* check for division by 0 */+      q = 0x7FFFFFFFL;+    else+      /* compute result directly */+      q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b );++    return ( s < 0 ? -(FT_Long)q : (FT_Long)q );+  }+++#else /* !FT_LONG64 */+++  static void+  ft_multo64( FT_UInt32  x,+              FT_UInt32  y,+              FT_Int64  *z )+  {+    FT_UInt32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;+++    lo1 = x & 0x0000FFFFU;  hi1 = x >> 16;+    lo2 = y & 0x0000FFFFU;  hi2 = y >> 16;++    lo = lo1 * lo2;+    i1 = lo1 * hi2;+    i2 = lo2 * hi1;+    hi = hi1 * hi2;++    /* Check carry overflow of i1 + i2 */+    i1 += i2;+    hi += (FT_UInt32)( i1 < i2 ) << 16;++    hi += i1 >> 16;+    i1  = i1 << 16;++    /* Check carry overflow of i1 + lo */+    lo += i1;+    hi += ( lo < i1 );++    z->lo = lo;+    z->hi = hi;+  }+++  static FT_UInt32+  ft_div64by32( FT_UInt32  hi,+                FT_UInt32  lo,+                FT_UInt32  y )+  {+    FT_UInt32  r, q;+    FT_Int     i;+++    q = 0;+    r = hi;++    if ( r >= y )+      return (FT_UInt32)0x7FFFFFFFL;++    i = 32;+    do+    {+      r <<= 1;+      q <<= 1;+      r  |= lo >> 31;++      if ( r >= (FT_UInt32)y )+      {+        r -= y;+        q |= 1;+      }+      lo <<= 1;+    } while ( --i );++    return q;+  }+++  static void+  FT_Add64( FT_Int64*  x,+            FT_Int64*  y,+            FT_Int64  *z )+  {+    register FT_UInt32  lo, hi;+++    lo = x->lo + y->lo;+    hi = x->hi + y->hi + ( lo < x->lo );++    z->lo = lo;+    z->hi = hi;+  }+++  /* documentation is in freetype.h */++  /* The FT_MulDiv function has been optimized thanks to ideas from      */+  /* Graham Asher.  The trick is to optimize computation when everything */+  /* fits within 32-bits (a rather common case).                         */+  /*                                                                     */+  /*  we compute 'a*b+c/2', then divide it by 'c'. (positive values)     */+  /*                                                                     */+  /*  46340 is FLOOR(SQRT(2^31-1)).                                      */+  /*                                                                     */+  /*  if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 )         */+  /*                                                                     */+  /*  0x7FFFFFFF - 0x7FFEA810 = 0x157F0                                  */+  /*                                                                     */+  /*  if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF )                */+  /*                                                                     */+  /*  and 2*0x157F0 = 176096                                             */+  /*                                                                     */++  FT_EXPORT_DEF( FT_Long )+  FT_MulDiv( FT_Long  a,+             FT_Long  b,+             FT_Long  c )+  {+    long  s;+++    /* XXX: this function does not allow 64-bit arguments */+    if ( a == 0 || b == c )+      return a;++    s  = a; a = FT_ABS( a );+    s ^= b; b = FT_ABS( b );+    s ^= c; c = FT_ABS( c );++    if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )+      a = ( a * b + ( c >> 1 ) ) / c;++    else if ( c > 0 )+    {+      FT_Int64  temp, temp2;+++      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );++      temp2.hi = 0;+      temp2.lo = (FT_UInt32)(c >> 1);+      FT_Add64( &temp, &temp2, &temp );+      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );+    }+    else+      a = 0x7FFFFFFFL;++    return ( s < 0 ? -a : a );+  }+++#ifdef TT_USE_BYTECODE_INTERPRETER++  FT_BASE_DEF( FT_Long )+  FT_MulDiv_No_Round( FT_Long  a,+                      FT_Long  b,+                      FT_Long  c )+  {+    long  s;+++    if ( a == 0 || b == c )+      return a;++    s  = a; a = FT_ABS( a );+    s ^= b; b = FT_ABS( b );+    s ^= c; c = FT_ABS( c );++    if ( a <= 46340L && b <= 46340L && c > 0 )+      a = a * b / c;++    else if ( c > 0 )+    {+      FT_Int64  temp;+++      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );+      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );+    }+    else+      a = 0x7FFFFFFFL;++    return ( s < 0 ? -a : a );+  }++#endif /* TT_USE_BYTECODE_INTERPRETER */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Long )+  FT_MulFix( FT_Long  a,+             FT_Long  b )+  {+#ifdef FT_MULFIX_ASSEMBLER++    return FT_MULFIX_ASSEMBLER( a, b );++#elif 0++    /*+     *  This code is nonportable.  See comment below.+     *+     *  However, on a platform where right-shift of a signed quantity fills+     *  the leftmost bits by copying the sign bit, it might be faster.+     */++    FT_Long   sa, sb;+    FT_ULong  ua, ub;+++    if ( a == 0 || b == 0x10000L )+      return a;++    /*+     *  This is a clever way of converting a signed number `a' into its+     *  absolute value (stored back into `a') and its sign.  The sign is+     *  stored in `sa'; 0 means `a' was positive or zero, and -1 means `a'+     *  was negative.  (Similarly for `b' and `sb').+     *+     *  Unfortunately, it doesn't work (at least not portably).+     *+     *  It makes the assumption that right-shift on a negative signed value+     *  fills the leftmost bits by copying the sign bit.  This is wrong. +     *  According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206,+     *  the result of right-shift of a negative signed value is+     *  implementation-defined.  At least one implementation fills the+     *  leftmost bits with 0s (i.e., it is exactly the same as an unsigned+     *  right shift).  This means that when `a' is negative, `sa' ends up+     *  with the value 1 rather than -1.  After that, everything else goes+     *  wrong.+     */+    sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );+    a  = ( a ^ sa ) - sa;+    sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );+    b  = ( b ^ sb ) - sb;++    ua = (FT_ULong)a;+    ub = (FT_ULong)b;++    if ( ua <= 2048 && ub <= 1048576L )+      ua = ( ua * ub + 0x8000U ) >> 16;+    else+    {+      FT_ULong  al = ua & 0xFFFFU;+++      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) ++           ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );+    }++    sa ^= sb,+    ua  = (FT_ULong)(( ua ^ sa ) - sa);++    return (FT_Long)ua;++#else /* 0 */++    FT_Long   s;+    FT_ULong  ua, ub;+++    if ( a == 0 || b == 0x10000L )+      return a;++    s  = a; a = FT_ABS( a );+    s ^= b; b = FT_ABS( b );++    ua = (FT_ULong)a;+    ub = (FT_ULong)b;++    if ( ua <= 2048 && ub <= 1048576L )+      ua = ( ua * ub + 0x8000UL ) >> 16;+    else+    {+      FT_ULong  al = ua & 0xFFFFUL;+++      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) ++           ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );+    }++    return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );++#endif /* 0 */++  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Long )+  FT_DivFix( FT_Long  a,+             FT_Long  b )+  {+    FT_Int32   s;+    FT_UInt32  q;+++    /* XXX: this function does not allow 64-bit arguments */+    s  = (FT_Int32)a; a = FT_ABS( a );+    s ^= (FT_Int32)b; b = FT_ABS( b );++    if ( b == 0 )+    {+      /* check for division by 0 */+      q = (FT_UInt32)0x7FFFFFFFL;+    }+    else if ( ( a >> 16 ) == 0 )+    {+      /* compute result directly */+      q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b;+    }+    else+    {+      /* we need more bits; we have to do it by hand */+      FT_Int64  temp, temp2;++      temp.hi  = (FT_Int32) (a >> 16);+      temp.lo  = (FT_UInt32)(a << 16);+      temp2.hi = 0;+      temp2.lo = (FT_UInt32)( b >> 1 );+      FT_Add64( &temp, &temp2, &temp );+      q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b );+    }++    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );+  }+++#if 0++  /* documentation is in ftcalc.h */++  FT_EXPORT_DEF( void )+  FT_MulTo64( FT_Int32   x,+              FT_Int32   y,+              FT_Int64  *z )+  {+    FT_Int32  s;+++    s  = x; x = FT_ABS( x );+    s ^= y; y = FT_ABS( y );++    ft_multo64( x, y, z );++    if ( s < 0 )+    {+      z->lo = (FT_UInt32)-(FT_Int32)z->lo;+      z->hi = ~z->hi + !( z->lo );+    }+  }+++  /* apparently, the second version of this code is not compiled correctly */+  /* on Mac machines with the MPW C compiler..  tsk, tsk, tsk...           */++#if 1++  FT_EXPORT_DEF( FT_Int32 )+  FT_Div64by32( FT_Int64*  x,+                FT_Int32   y )+  {+    FT_Int32   s;+    FT_UInt32  q, r, i, lo;+++    s  = x->hi;+    if ( s < 0 )+    {+      x->lo = (FT_UInt32)-(FT_Int32)x->lo;+      x->hi = ~x->hi + !x->lo;+    }+    s ^= y;  y = FT_ABS( y );++    /* Shortcut */+    if ( x->hi == 0 )+    {+      if ( y > 0 )+        q = x->lo / y;+      else+        q = 0x7FFFFFFFL;++      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );+    }++    r  = x->hi;+    lo = x->lo;++    if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */+      return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );+                             /* Return Max/Min Int32 if division overflow. */+                             /* This includes division by zero!            */+    q = 0;+    for ( i = 0; i < 32; i++ )+    {+      r <<= 1;+      q <<= 1;+      r  |= lo >> 31;++      if ( r >= (FT_UInt32)y )+      {+        r -= y;+        q |= 1;+      }+      lo <<= 1;+    }++    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );+  }++#else /* 0 */++  FT_EXPORT_DEF( FT_Int32 )+  FT_Div64by32( FT_Int64*  x,+                FT_Int32   y )+  {+    FT_Int32   s;+    FT_UInt32  q;+++    s  = x->hi;+    if ( s < 0 )+    {+      x->lo = (FT_UInt32)-(FT_Int32)x->lo;+      x->hi = ~x->hi + !x->lo;+    }+    s ^= y;  y = FT_ABS( y );++    /* Shortcut */+    if ( x->hi == 0 )+    {+      if ( y > 0 )+        q = ( x->lo + ( y >> 1 ) ) / y;+      else+        q = 0x7FFFFFFFL;++      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );+    }++    q = ft_div64by32( x->hi, x->lo, y );++    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );+  }++#endif /* 0 */++#endif /* 0 */+++#endif /* FT_LONG64 */+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( void )+  FT_Matrix_Multiply( const FT_Matrix*  a,+                      FT_Matrix        *b )+  {+    FT_Fixed  xx, xy, yx, yy;+++    if ( !a || !b )+      return;++    xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );+    xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );+    yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );+    yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );++    b->xx = xx;  b->xy = xy;+    b->yx = yx;  b->yy = yy;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Matrix_Invert( FT_Matrix*  matrix )+  {+    FT_Pos  delta, xx, yy;+++    if ( !matrix )+      return FT_Err_Invalid_Argument;++    /* compute discriminant */+    delta = FT_MulFix( matrix->xx, matrix->yy ) -+            FT_MulFix( matrix->xy, matrix->yx );++    if ( !delta )+      return FT_Err_Invalid_Argument;  /* matrix can't be inverted */++    matrix->xy = - FT_DivFix( matrix->xy, delta );+    matrix->yx = - FT_DivFix( matrix->yx, delta );++    xx = matrix->xx;+    yy = matrix->yy;++    matrix->xx = FT_DivFix( yy, delta );+    matrix->yy = FT_DivFix( xx, delta );++    return FT_Err_Ok;+  }+++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( void )+  FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,+                             FT_Matrix        *b,+                             FT_Long           scaling )+  {+    FT_Fixed  xx, xy, yx, yy;++    FT_Long   val = 0x10000L * scaling;+++    if ( !a || !b )+      return;++    xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val );+    xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val );+    yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val );+    yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val );++    b->xx = xx;  b->xy = xy;+    b->yx = yx;  b->yy = yy;+  }+++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( void )+  FT_Vector_Transform_Scaled( FT_Vector*        vector,+                              const FT_Matrix*  matrix,+                              FT_Long           scaling )+  {+    FT_Pos   xz, yz;++    FT_Long  val = 0x10000L * scaling;+++    if ( !vector || !matrix )+      return;++    xz = FT_MulDiv( vector->x, matrix->xx, val ) ++         FT_MulDiv( vector->y, matrix->xy, val );++    yz = FT_MulDiv( vector->x, matrix->yx, val ) ++         FT_MulDiv( vector->y, matrix->yy, val );++    vector->x = xz;+    vector->y = yz;+  }+++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( FT_Int32 )+  FT_SqrtFixed( FT_Int32  x )+  {+    FT_UInt32  root, rem_hi, rem_lo, test_div;+    FT_Int     count;+++    root = 0;++    if ( x > 0 )+    {+      rem_hi = 0;+      rem_lo = x;+      count  = 24;+      do+      {+        rem_hi   = ( rem_hi << 2 ) | ( rem_lo >> 30 );+        rem_lo <<= 2;+        root   <<= 1;+        test_div = ( root << 1 ) + 1;++        if ( rem_hi >= test_div )+        {+          rem_hi -= test_div;+          root   += 1;+        }+      } while ( --count );+    }++    return (FT_Int32)root;+  }+++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( FT_Int )+  ft_corner_orientation( FT_Pos  in_x,+                         FT_Pos  in_y,+                         FT_Pos  out_x,+                         FT_Pos  out_y )+  {+    FT_Long  result; /* avoid overflow on 16-bit system */+++    /* deal with the trivial cases quickly */+    if ( in_y == 0 )+    {+      if ( in_x >= 0 )+        result = out_y;+      else+        result = -out_y;+    }+    else if ( in_x == 0 )+    {+      if ( in_y >= 0 )+        result = -out_x;+      else+        result = out_x;+    }+    else if ( out_y == 0 )+    {+      if ( out_x >= 0 )+        result = in_y;+      else+        result = -in_y;+    }+    else if ( out_x == 0 )+    {+      if ( out_y >= 0 )+        result = -in_x;+      else+        result =  in_x;+    }+    else /* general case */+    {+#ifdef FT_LONG64++      FT_Int64  delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;+++      if ( delta == 0 )+        result = 0;+      else+        result = 1 - 2 * ( delta < 0 );++#else++      FT_Int64  z1, z2;+++      /* XXX: this function does not allow 64-bit arguments */+      ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 );+      ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 );++      if ( z1.hi > z2.hi )+        result = +1;+      else if ( z1.hi < z2.hi )+        result = -1;+      else if ( z1.lo > z2.lo )+        result = +1;+      else if ( z1.lo < z2.lo )+        result = -1;+      else+        result = 0;++#endif+    }++    /* XXX: only the sign of return value, +1/0/-1 must be used */+    return (FT_Int)result;+  }+++  /* documentation is in ftcalc.h */++  FT_BASE_DEF( FT_Int )+  ft_corner_is_flat( FT_Pos  in_x,+                     FT_Pos  in_y,+                     FT_Pos  out_x,+                     FT_Pos  out_y )+  {+    FT_Pos  ax = in_x;+    FT_Pos  ay = in_y;++    FT_Pos  d_in, d_out, d_corner;+++    if ( ax < 0 )+      ax = -ax;+    if ( ay < 0 )+      ay = -ay;+    d_in = ax + ay;++    ax = out_x;+    if ( ax < 0 )+      ax = -ax;+    ay = out_y;+    if ( ay < 0 )+      ay = -ay;+    d_out = ax + ay;++    ax = out_x + in_x;+    if ( ax < 0 )+      ax = -ax;+    ay = out_y + in_y;+    if ( ay < 0 )+      ay = -ay;+    d_corner = ax + ay;++    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );+  }+++/* END */
+ src/base/ftcid.c view
@@ -0,0 +1,117 @@+/***************************************************************************/+/*                                                                         */+/*  ftcid.c                                                                */+/*                                                                         */+/*    FreeType API for accessing CID font information.                     */+/*                                                                         */+/*  Copyright 2007, 2009 by Derek Clegg, Michael Toftdal.                  */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CID_H+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_CID_H+++  /* documentation is in ftcid.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_CID_Registry_Ordering_Supplement( FT_Face       face,+                                           const char*  *registry,+                                           const char*  *ordering,+                                           FT_Int       *supplement)+  {+    FT_Error     error;+    const char*  r = NULL;+    const char*  o = NULL;+    FT_Int       s = 0;+++    error = FT_Err_Invalid_Argument;++    if ( face )+    {+      FT_Service_CID  service;+++      FT_FACE_FIND_SERVICE( face, service, CID );++      if ( service && service->get_ros )+        error = service->get_ros( face, &r, &o, &s );+    }++    if ( registry )+      *registry = r;++    if ( ordering )+      *ordering = o;++    if ( supplement )+      *supplement = s;++    return error;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Get_CID_Is_Internally_CID_Keyed( FT_Face   face,+                                      FT_Bool  *is_cid )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+    FT_Bool   ic = 0;+++    if ( face )+    {+      FT_Service_CID  service;+++      FT_FACE_FIND_SERVICE( face, service, CID );++      if ( service && service->get_is_cid )+        error = service->get_is_cid( face, &ic);+    }++    if ( is_cid )+      *is_cid = ic;++    return error;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Get_CID_From_Glyph_Index( FT_Face   face,+                               FT_UInt   glyph_index,+                               FT_UInt  *cid )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+    FT_UInt   c = 0;+++    if ( face )+    {+      FT_Service_CID  service;+++      FT_FACE_FIND_SERVICE( face, service, CID );++      if ( service && service->get_cid_from_glyph_index )+        error = service->get_cid_from_glyph_index( face, glyph_index, &c);+    }++    if ( cid )+      *cid = c;++    return error;+  }+++/* END */
+ src/base/ftdbgmem.c view
@@ -0,0 +1,997 @@+/***************************************************************************/+/*                                                                         */+/*  ftdbgmem.c                                                             */+/*                                                                         */+/*    Memory debugger (body).                                              */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2009 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_MEMORY_H+#include FT_SYSTEM_H+#include FT_ERRORS_H+#include FT_TYPES_H+++#ifdef FT_DEBUG_MEMORY++#define  KEEPALIVE /* `Keep alive' means that freed blocks aren't released+                    * to the heap.  This is useful to detect double-frees+                    * or weird heap corruption, but it uses large amounts of+                    * memory, however.+                    */++#include FT_CONFIG_STANDARD_LIBRARY_H++  FT_BASE_DEF( const char* )  _ft_debug_file   = 0;+  FT_BASE_DEF( long )         _ft_debug_lineno = 0;++  extern void+  FT_DumpMemory( FT_Memory  memory );+++  typedef struct FT_MemSourceRec_*  FT_MemSource;+  typedef struct FT_MemNodeRec_*    FT_MemNode;+  typedef struct FT_MemTableRec_*   FT_MemTable;+++#define FT_MEM_VAL( addr )  ((FT_PtrDist)(FT_Pointer)( addr ))++  /*+   *  This structure holds statistics for a single allocation/release+   *  site.  This is useful to know where memory operations happen the+   *  most.+   */+  typedef struct  FT_MemSourceRec_+  {+    const char*   file_name;+    long          line_no;++    FT_Long       cur_blocks;   /* current number of allocated blocks */+    FT_Long       max_blocks;   /* max. number of allocated blocks    */+    FT_Long       all_blocks;   /* total number of blocks allocated   */++    FT_Long       cur_size;     /* current cumulative allocated size */+    FT_Long       max_size;     /* maximum cumulative allocated size */+    FT_Long       all_size;     /* total cumulative allocated size   */++    FT_Long       cur_max;      /* current maximum allocated size */++    FT_UInt32     hash;+    FT_MemSource  link;++  } FT_MemSourceRec;+++  /*+   *  We don't need a resizable array for the memory sources, because+   *  their number is pretty limited within FreeType.+   */+#define FT_MEM_SOURCE_BUCKETS  128++  /*+   *  This structure holds information related to a single allocated+   *  memory block.  If KEEPALIVE is defined, blocks that are freed by+   *  FreeType are never released to the system.  Instead, their `size'+   *  field is set to -size.  This is mainly useful to detect double frees,+   *  at the price of large memory footprint during execution.+   */+  typedef struct  FT_MemNodeRec_+  {+    FT_Byte*      address;+    FT_Long       size;     /* < 0 if the block was freed */++    FT_MemSource  source;++#ifdef KEEPALIVE+    const char*   free_file_name;+    FT_Long       free_line_no;+#endif++    FT_MemNode    link;++  } FT_MemNodeRec;+++  /*+   *  The global structure, containing compound statistics and all hash+   *  tables.+   */+  typedef struct  FT_MemTableRec_+  {+    FT_ULong         size;+    FT_ULong         nodes;+    FT_MemNode*      buckets;++    FT_ULong         alloc_total;+    FT_ULong         alloc_current;+    FT_ULong         alloc_max;+    FT_ULong         alloc_count;++    FT_Bool          bound_total;+    FT_ULong         alloc_total_max;++    FT_Bool          bound_count;+    FT_ULong         alloc_count_max;++    FT_MemSource     sources[FT_MEM_SOURCE_BUCKETS];++    FT_Bool          keep_alive;++    FT_Memory        memory;+    FT_Pointer       memory_user;+    FT_Alloc_Func    alloc;+    FT_Free_Func     free;+    FT_Realloc_Func  realloc;++  } FT_MemTableRec;+++#define FT_MEM_SIZE_MIN  7+#define FT_MEM_SIZE_MAX  13845163++#define FT_FILENAME( x )  ((x) ? (x) : "unknown file")+++  /*+   *  Prime numbers are ugly to handle.  It would be better to implement+   *  L-Hashing, which is 10% faster and doesn't require divisions.+   */+  static const FT_UInt  ft_mem_primes[] =+  {+    7,+    11,+    19,+    37,+    73,+    109,+    163,+    251,+    367,+    557,+    823,+    1237,+    1861,+    2777,+    4177,+    6247,+    9371,+    14057,+    21089,+    31627,+    47431,+    71143,+    106721,+    160073,+    240101,+    360163,+    540217,+    810343,+    1215497,+    1823231,+    2734867,+    4102283,+    6153409,+    9230113,+    13845163,+  };+++  static FT_ULong+  ft_mem_closest_prime( FT_ULong  num )+  {+    FT_UInt  i;+++    for ( i = 0;+          i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ )+      if ( ft_mem_primes[i] > num )+        return ft_mem_primes[i];++    return FT_MEM_SIZE_MAX;+  }+++  extern void+  ft_mem_debug_panic( const char*  fmt,+                      ... )+  {+    va_list  ap;+++    printf( "FreeType.Debug: " );++    va_start( ap, fmt );+    vprintf( fmt, ap );+    va_end( ap );++    printf( "\n" );+    exit( EXIT_FAILURE );+  }+++  static FT_Pointer+  ft_mem_table_alloc( FT_MemTable  table,+                      FT_Long      size )+  {+    FT_Memory   memory = table->memory;+    FT_Pointer  block;+++    memory->user = table->memory_user;+    block = table->alloc( memory, size );+    memory->user = table;++    return block;+  }+++  static void+  ft_mem_table_free( FT_MemTable  table,+                     FT_Pointer   block )+  {+    FT_Memory  memory = table->memory;+++    memory->user = table->memory_user;+    table->free( memory, block );+    memory->user = table;+  }+++  static void+  ft_mem_table_resize( FT_MemTable  table )+  {+    FT_ULong  new_size;+++    new_size = ft_mem_closest_prime( table->nodes );+    if ( new_size != table->size )+    {+      FT_MemNode*  new_buckets;+      FT_ULong     i;+++      new_buckets = (FT_MemNode *)+                      ft_mem_table_alloc( table,+                                          new_size * sizeof ( FT_MemNode ) );+      if ( new_buckets == NULL )+        return;++      FT_ARRAY_ZERO( new_buckets, new_size );++      for ( i = 0; i < table->size; i++ )+      {+        FT_MemNode  node, next, *pnode;+        FT_PtrDist  hash;+++        node = table->buckets[i];+        while ( node )+        {+          next  = node->link;+          hash  = FT_MEM_VAL( node->address ) % new_size;+          pnode = new_buckets + hash;++          node->link = pnode[0];+          pnode[0]   = node;++          node = next;+        }+      }++      if ( table->buckets )+        ft_mem_table_free( table, table->buckets );++      table->buckets = new_buckets;+      table->size    = new_size;+    }+  }+++  static FT_MemTable+  ft_mem_table_new( FT_Memory  memory )+  {+    FT_MemTable  table;+++    table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );+    if ( table == NULL )+      goto Exit;++    FT_ZERO( table );++    table->size  = FT_MEM_SIZE_MIN;+    table->nodes = 0;++    table->memory = memory;++    table->memory_user = memory->user;++    table->alloc   = memory->alloc;+    table->realloc = memory->realloc;+    table->free    = memory->free;++    table->buckets = (FT_MemNode *)+                       memory->alloc( memory,+                                      table->size * sizeof ( FT_MemNode ) );+    if ( table->buckets )+      FT_ARRAY_ZERO( table->buckets, table->size );+    else+    {+      memory->free( memory, table );+      table = NULL;+    }++  Exit:+    return table;+  }+++  static void+  ft_mem_table_destroy( FT_MemTable  table )+  {+    FT_ULong  i;+++    FT_DumpMemory( table->memory );++    if ( table )+    {+      FT_Long   leak_count = 0;+      FT_ULong  leaks      = 0;+++      /* remove all blocks from the table, revealing leaked ones */+      for ( i = 0; i < table->size; i++ )+      {+        FT_MemNode  *pnode = table->buckets + i, next, node = *pnode;+++        while ( node )+        {+          next       = node->link;+          node->link = 0;++          if ( node->size > 0 )+          {+            printf(+              "leaked memory block at address %p, size %8ld in (%s:%ld)\n",+              node->address, node->size,+              FT_FILENAME( node->source->file_name ),+              node->source->line_no );++            leak_count++;+            leaks += node->size;++            ft_mem_table_free( table, node->address );+          }++          node->address = NULL;+          node->size    = 0;++          ft_mem_table_free( table, node );+          node = next;+        }+        table->buckets[i] = 0;+      }++      ft_mem_table_free( table, table->buckets );+      table->buckets = NULL;++      table->size  = 0;+      table->nodes = 0;++      /* remove all sources */+      for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ )+      {+        FT_MemSource  source, next;+++        for ( source = table->sources[i]; source != NULL; source = next )+        {+          next = source->link;+          ft_mem_table_free( table, source );+        }++        table->sources[i] = NULL;+      }++      printf(+        "FreeType: total memory allocations = %ld\n", table->alloc_total );+      printf(+        "FreeType: maximum memory footprint = %ld\n", table->alloc_max );++      ft_mem_table_free( table, table );++      if ( leak_count > 0 )+        ft_mem_debug_panic(+          "FreeType: %ld bytes of memory leaked in %ld blocks\n",+          leaks, leak_count );++      printf( "FreeType: no memory leaks detected\n" );+    }+  }+++  static FT_MemNode*+  ft_mem_table_get_nodep( FT_MemTable  table,+                          FT_Byte*     address )+  {+    FT_PtrDist   hash;+    FT_MemNode  *pnode, node;+++    hash  = FT_MEM_VAL( address );+    pnode = table->buckets + ( hash % table->size );++    for (;;)+    {+      node = pnode[0];+      if ( !node )+        break;++      if ( node->address == address )+        break;++      pnode = &node->link;+    }+    return pnode;+  }+++  static FT_MemSource+  ft_mem_table_get_source( FT_MemTable  table )+  {+    FT_UInt32     hash;+    FT_MemSource  node, *pnode;+++    /* cast to FT_PtrDist first since void* can be larger */+    /* than FT_UInt32 and GCC 4.1.1 emits a warning       */+    hash  = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file ++              (FT_UInt32)( 5 * _ft_debug_lineno );+    pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];++    for ( ;; )+    {+      node = *pnode;+      if ( node == NULL )+        break;++      if ( node->file_name == _ft_debug_file &&+           node->line_no   == _ft_debug_lineno   )+        goto Exit;++      pnode = &node->link;+    }++    node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );+    if ( node == NULL )+      ft_mem_debug_panic(+        "not enough memory to perform memory debugging\n" );++    node->file_name = _ft_debug_file;+    node->line_no   = _ft_debug_lineno;++    node->cur_blocks = 0;+    node->max_blocks = 0;+    node->all_blocks = 0;++    node->cur_size   = 0;+    node->max_size   = 0;+    node->all_size   = 0;++    node->cur_max    = 0;++    node->link = NULL;+    node->hash = hash;+    *pnode     = node;++  Exit:+    return node;+  }+++  static void+  ft_mem_table_set( FT_MemTable  table,+                    FT_Byte*     address,+                    FT_ULong     size,+                    FT_Long      delta )+  {+    FT_MemNode  *pnode, node;+++    if ( table )+    {+      FT_MemSource  source;+++      pnode = ft_mem_table_get_nodep( table, address );+      node  = *pnode;+      if ( node )+      {+        if ( node->size < 0 )+        {+          /* This block was already freed.  Our memory is now completely */+          /* corrupted!                                                  */+          /* This can only happen in keep-alive mode.                    */+          ft_mem_debug_panic(+            "memory heap corrupted (allocating freed block)" );+        }+        else+        {+          /* This block was already allocated.  This means that our memory */+          /* is also corrupted!                                            */+          ft_mem_debug_panic(+            "memory heap corrupted (re-allocating allocated block at"+            " %p, of size %ld)\n"+            "org=%s:%d new=%s:%d\n",+            node->address, node->size,+            FT_FILENAME( node->source->file_name ), node->source->line_no,+            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );+        }+      }++      /* we need to create a new node in this table */+      node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );+      if ( node == NULL )+        ft_mem_debug_panic( "not enough memory to run memory tests" );++      node->address = address;+      node->size    = size;+      node->source  = source = ft_mem_table_get_source( table );++      if ( delta == 0 )+      {+        /* this is an allocation */+        source->all_blocks++;+        source->cur_blocks++;+        if ( source->cur_blocks > source->max_blocks )+          source->max_blocks = source->cur_blocks;+      }++      if ( size > (FT_ULong)source->cur_max )+        source->cur_max = size;++      if ( delta != 0 )+      {+        /* we are growing or shrinking a reallocated block */+        source->cur_size     += delta;+        table->alloc_current += delta;+      }+      else+      {+        /* we are allocating a new block */+        source->cur_size     += size;+        table->alloc_current += size;+      }++      source->all_size += size;++      if ( source->cur_size > source->max_size )+        source->max_size = source->cur_size;++      node->free_file_name = NULL;+      node->free_line_no   = 0;++      node->link = pnode[0];++      pnode[0] = node;+      table->nodes++;++      table->alloc_total += size;++      if ( table->alloc_current > table->alloc_max )+        table->alloc_max = table->alloc_current;++      if ( table->nodes * 3 < table->size  ||+           table->size  * 3 < table->nodes )+        ft_mem_table_resize( table );+    }+  }+++  static void+  ft_mem_table_remove( FT_MemTable  table,+                       FT_Byte*     address,+                       FT_Long      delta )+  {+    if ( table )+    {+      FT_MemNode  *pnode, node;+++      pnode = ft_mem_table_get_nodep( table, address );+      node  = *pnode;+      if ( node )+      {+        FT_MemSource  source;+++        if ( node->size < 0 )+          ft_mem_debug_panic(+            "freeing memory block at %p more than once at (%s:%ld)\n"+            "block allocated at (%s:%ld) and released at (%s:%ld)",+            address,+            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,+            FT_FILENAME( node->source->file_name ), node->source->line_no,+            FT_FILENAME( node->free_file_name ), node->free_line_no );++        /* scramble the node's content for additional safety */+        FT_MEM_SET( address, 0xF3, node->size );++        if ( delta == 0 )+        {+          source = node->source;++          source->cur_blocks--;+          source->cur_size -= node->size;++          table->alloc_current -= node->size;+        }++        if ( table->keep_alive )+        {+          /* we simply invert the node's size to indicate that the node */+          /* was freed.                                                 */+          node->size           = -node->size;+          node->free_file_name = _ft_debug_file;+          node->free_line_no   = _ft_debug_lineno;+        }+        else+        {+          table->nodes--;++          *pnode = node->link;++          node->size   = 0;+          node->source = NULL;++          ft_mem_table_free( table, node );++          if ( table->nodes * 3 < table->size  ||+               table->size  * 3 < table->nodes )+            ft_mem_table_resize( table );+        }+      }+      else+        ft_mem_debug_panic(+          "trying to free unknown block at %p in (%s:%ld)\n",+          address,+          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );+    }+  }+++  extern FT_Pointer+  ft_mem_debug_alloc( FT_Memory  memory,+                      FT_Long    size )+  {+    FT_MemTable  table = (FT_MemTable)memory->user;+    FT_Byte*     block;+++    if ( size <= 0 )+      ft_mem_debug_panic( "negative block size allocation (%ld)", size );++    /* return NULL if the maximum number of allocations was reached */+    if ( table->bound_count                           &&+         table->alloc_count >= table->alloc_count_max )+      return NULL;++    /* return NULL if this allocation would overflow the maximum heap size */+    if ( table->bound_total                                             &&+         table->alloc_total_max - table->alloc_current > (FT_ULong)size )+      return NULL;++    block = (FT_Byte *)ft_mem_table_alloc( table, size );+    if ( block )+    {+      ft_mem_table_set( table, block, (FT_ULong)size, 0 );++      table->alloc_count++;+    }++    _ft_debug_file   = "<unknown>";+    _ft_debug_lineno = 0;++    return (FT_Pointer)block;+  }+++  extern void+  ft_mem_debug_free( FT_Memory   memory,+                     FT_Pointer  block )+  {+    FT_MemTable  table = (FT_MemTable)memory->user;+++    if ( block == NULL )+      ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",+                          FT_FILENAME( _ft_debug_file ),+                          _ft_debug_lineno );++    ft_mem_table_remove( table, (FT_Byte*)block, 0 );++    if ( !table->keep_alive )+      ft_mem_table_free( table, block );++    table->alloc_count--;++    _ft_debug_file   = "<unknown>";+    _ft_debug_lineno = 0;+  }+++  extern FT_Pointer+  ft_mem_debug_realloc( FT_Memory   memory,+                        FT_Long     cur_size,+                        FT_Long     new_size,+                        FT_Pointer  block )+  {+    FT_MemTable  table = (FT_MemTable)memory->user;+    FT_MemNode   node, *pnode;+    FT_Pointer   new_block;+    FT_Long      delta;++    const char*  file_name = FT_FILENAME( _ft_debug_file );+    FT_Long      line_no   = _ft_debug_lineno;+++    /* unlikely, but possible */+    if ( new_size == cur_size )+      return block;++    /* the following is valid according to ANSI C */+#if 0+    if ( block == NULL || cur_size == 0 )+      ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",+                          file_name, line_no );+#endif++    /* while the following is allowed in ANSI C also, we abort since */+    /* such case should be handled by FreeType.                      */+    if ( new_size <= 0 )+      ft_mem_debug_panic(+        "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)",+        block, cur_size, file_name, line_no );++    /* check `cur_size' value */+    pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block );+    node  = *pnode;+    if ( !node )+      ft_mem_debug_panic(+        "trying to reallocate unknown block at %p in (%s:%ld)",+        block, file_name, line_no );++    if ( node->size <= 0 )+      ft_mem_debug_panic(+        "trying to reallocate freed block at %p in (%s:%ld)",+        block, file_name, line_no );++    if ( node->size != cur_size )+      ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is "+                          "%ld instead of %ld in (%s:%ld)",+                          block, cur_size, node->size, file_name, line_no );++    /* return NULL if the maximum number of allocations was reached */+    if ( table->bound_count                           &&+         table->alloc_count >= table->alloc_count_max )+      return NULL;++    delta = (FT_Long)( new_size - cur_size );++    /* return NULL if this allocation would overflow the maximum heap size */+    if ( delta > 0                                                       &&+         table->bound_total                                              &&+         table->alloc_current + (FT_ULong)delta > table->alloc_total_max )+      return NULL;++    new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );+    if ( new_block == NULL )+      return NULL;++    ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );++    ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );++    ft_mem_table_remove( table, (FT_Byte*)block, delta );++    _ft_debug_file   = "<unknown>";+    _ft_debug_lineno = 0;++    if ( !table->keep_alive )+      ft_mem_table_free( table, block );++    return new_block;+  }+++  extern FT_Int+  ft_mem_debug_init( FT_Memory  memory )+  {+    FT_MemTable  table;+    FT_Int       result = 0;+++    if ( getenv( "FT2_DEBUG_MEMORY" ) )+    {+      table = ft_mem_table_new( memory );+      if ( table )+      {+        const char*  p;+++        memory->user    = table;+        memory->alloc   = ft_mem_debug_alloc;+        memory->realloc = ft_mem_debug_realloc;+        memory->free    = ft_mem_debug_free;++        p = getenv( "FT2_ALLOC_TOTAL_MAX" );+        if ( p != NULL )+        {+          FT_Long   total_max = ft_atol( p );+++          if ( total_max > 0 )+          {+            table->bound_total     = 1;+            table->alloc_total_max = (FT_ULong)total_max;+          }+        }++        p = getenv( "FT2_ALLOC_COUNT_MAX" );+        if ( p != NULL )+        {+          FT_Long  total_count = ft_atol( p );+++          if ( total_count > 0 )+          {+            table->bound_count     = 1;+            table->alloc_count_max = (FT_ULong)total_count;+          }+        }++        p = getenv( "FT2_KEEP_ALIVE" );+        if ( p != NULL )+        {+          FT_Long  keep_alive = ft_atol( p );+++          if ( keep_alive > 0 )+            table->keep_alive = 1;+        }++        result = 1;+      }+    }+    return result;+  }+++  extern void+  ft_mem_debug_done( FT_Memory  memory )+  {+    FT_MemTable  table = (FT_MemTable)memory->user;+++    if ( table )+    {+      memory->free    = table->free;+      memory->realloc = table->realloc;+      memory->alloc   = table->alloc;++      ft_mem_table_destroy( table );+      memory->user = NULL;+    }+  }++++  static int+  ft_mem_source_compare( const void*  p1,+                         const void*  p2 )+  {+    FT_MemSource  s1 = *(FT_MemSource*)p1;+    FT_MemSource  s2 = *(FT_MemSource*)p2;+++    if ( s2->max_size > s1->max_size )+      return 1;+    else if ( s2->max_size < s1->max_size )+      return -1;+    else+      return 0;+  }+++  extern void+  FT_DumpMemory( FT_Memory  memory )+  {+    FT_MemTable  table = (FT_MemTable)memory->user;+++    if ( table )+    {+      FT_MemSource*  bucket = table->sources;+      FT_MemSource*  limit  = bucket + FT_MEM_SOURCE_BUCKETS;+      FT_MemSource*  sources;+      FT_UInt        nn, count;+      const char*    fmt;+++      count = 0;+      for ( ; bucket < limit; bucket++ )+      {+        FT_MemSource  source = *bucket;+++        for ( ; source; source = source->link )+          count++;+      }++      sources = (FT_MemSource*)ft_mem_table_alloc(+                                 table, sizeof ( *sources ) * count );++      count = 0;+      for ( bucket = table->sources; bucket < limit; bucket++ )+      {+        FT_MemSource  source = *bucket;+++        for ( ; source; source = source->link )+          sources[count++] = source;+      }++      ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );++      printf( "FreeType Memory Dump: "+              "current=%ld max=%ld total=%ld count=%ld\n",+              table->alloc_current, table->alloc_max,+              table->alloc_total, table->alloc_count );+      printf( " block  block    sizes    sizes    sizes   source\n" );+      printf( " count   high      sum  highsum      max   location\n" );+      printf( "-------------------------------------------------\n" );++      fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n";++      for ( nn = 0; nn < count; nn++ )+      {+        FT_MemSource  source = sources[nn];+++        printf( fmt,+                source->cur_blocks, source->max_blocks,+                source->cur_size, source->max_size, source->cur_max,+                FT_FILENAME( source->file_name ),+                source->line_no );+      }+      printf( "------------------------------------------------\n" );++      ft_mem_table_free( table, sources );+    }+  }++#else  /* !FT_DEBUG_MEMORY */++  /* ANSI C doesn't like empty source files */+  typedef int  _debug_mem_dummy;++#endif /* !FT_DEBUG_MEMORY */+++/* END */
+ src/base/ftdebug.c view
@@ -0,0 +1,246 @@+/***************************************************************************/+/*                                                                         */+/*  ftdebug.c                                                              */+/*                                                                         */+/*    Debugging and logging component (body).                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2008 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This component contains various macros and functions used to ease the */+  /* debugging of the FreeType engine.  Its main purpose is in assertion   */+  /* checking, tracing, and error detection.                               */+  /*                                                                       */+  /* There are now three debugging modes:                                  */+  /*                                                                       */+  /* - trace mode                                                          */+  /*                                                                       */+  /*   Error and trace messages are sent to the log file (which can be the */+  /*   standard error output).                                             */+  /*                                                                       */+  /* - error mode                                                          */+  /*                                                                       */+  /*   Only error messages are generated.                                  */+  /*                                                                       */+  /* - release mode:                                                       */+  /*                                                                       */+  /*   No error message is sent or generated.  The code is free from any   */+  /*   debugging parts.                                                    */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_DEBUG_H+++#ifdef FT_DEBUG_LEVEL_ERROR++  /* documentation is in ftdebug.h */++  FT_BASE_DEF( void )+  FT_Message( const char*  fmt, ... )+  {+    va_list  ap;+++    va_start( ap, fmt );+    vfprintf( stderr, fmt, ap );+    va_end( ap );+  }+++  /* documentation is in ftdebug.h */++  FT_BASE_DEF( void )+  FT_Panic( const char*  fmt, ... )+  {+    va_list  ap;+++    va_start( ap, fmt );+    vfprintf( stderr, fmt, ap );+    va_end( ap );++    exit( EXIT_FAILURE );+  }++#endif /* FT_DEBUG_LEVEL_ERROR */++++#ifdef FT_DEBUG_LEVEL_TRACE++  /* array of trace levels, initialized to 0 */+  int  ft_trace_levels[trace_count];+++  /* define array of trace toggle names */+#define FT_TRACE_DEF( x )  #x ,++  static const char*  ft_trace_toggles[trace_count + 1] =+  {+#include FT_INTERNAL_TRACE_H+    NULL+  };++#undef FT_TRACE_DEF+++  /* documentation is in ftdebug.h */++  FT_BASE_DEF( FT_Int )+  FT_Trace_Get_Count( void )+  {+    return trace_count;+  }+++  /* documentation is in ftdebug.h */++  FT_BASE_DEF( const char * )+  FT_Trace_Get_Name( FT_Int  idx )+  {+    int  max = FT_Trace_Get_Count();+++    if ( idx < max )+      return ft_trace_toggles[idx];+    else+      return NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Initialize the tracing sub-system.  This is done by retrieving the    */+  /* value of the `FT2_DEBUG' environment variable.  It must be a list of  */+  /* toggles, separated by spaces, `;', or `,'.  Example:                  */+  /*                                                                       */+  /*    export FT2_DEBUG="any:3 memory:7 stream:5"                         */+  /*                                                                       */+  /* This requests that all levels be set to 3, except the trace level for */+  /* the memory and stream components which are set to 7 and 5,            */+  /* respectively.                                                         */+  /*                                                                       */+  /* See the file <include/freetype/internal/fttrace.h> for details of the */+  /* available toggle names.                                               */+  /*                                                                       */+  /* The level must be between 0 and 7; 0 means quiet (except for serious  */+  /* runtime errors), and 7 means _very_ verbose.                          */+  /*                                                                       */+  FT_BASE_DEF( void )+  ft_debug_init( void )+  {+    const char*  ft2_debug = getenv( "FT2_DEBUG" );+++    if ( ft2_debug )+    {+      const char*  p = ft2_debug;+      const char*  q;+++      for ( ; *p; p++ )+      {+        /* skip leading whitespace and separators */+        if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )+          continue;++        /* read toggle name, followed by ':' */+        q = p;+        while ( *p && *p != ':' )+          p++;++        if ( *p == ':' && p > q )+        {+          FT_Int  n, i, len = (FT_Int)( p - q );+          FT_Int  level = -1, found = -1;+++          for ( n = 0; n < trace_count; n++ )+          {+            const char*  toggle = ft_trace_toggles[n];+++            for ( i = 0; i < len; i++ )+            {+              if ( toggle[i] != q[i] )+                break;+            }++            if ( i == len && toggle[i] == 0 )+            {+              found = n;+              break;+            }+          }++          /* read level */+          p++;+          if ( *p )+          {+            level = *p++ - '0';+            if ( level < 0 || level > 7 )+              level = -1;+          }++          if ( found >= 0 && level >= 0 )+          {+            if ( found == trace_any )+            {+              /* special case for `any' */+              for ( n = 0; n < trace_count; n++ )+                ft_trace_levels[n] = level;+            }+            else+              ft_trace_levels[found] = level;+          }+        }+      }+    }+  }+++#else  /* !FT_DEBUG_LEVEL_TRACE */+++  FT_BASE_DEF( void )+  ft_debug_init( void )+  {+    /* nothing */+  }+++  FT_BASE_DEF( FT_Int )+  FT_Trace_Get_Count( void )+  {+    return 0;+  }+++  FT_BASE_DEF( const char * )+  FT_Trace_Get_Name( FT_Int  idx )+  {+    FT_UNUSED( idx );++    return NULL;+  }+++#endif /* !FT_DEBUG_LEVEL_TRACE */+++/* END */
+ src/base/ftfstype.c view
@@ -0,0 +1,62 @@+/***************************************************************************/+/*                                                                         */+/*  ftfstype.c                                                             */+/*                                                                         */+/*    FreeType utility file to access FSType data (body).                  */+/*                                                                         */+/*  Copyright 2008, 2009 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_TYPE1_TABLES_H+#include FT_TRUETYPE_TABLES_H+#include FT_INTERNAL_SERVICE_H+#include FT_SERVICE_POSTSCRIPT_INFO_H+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UShort )+  FT_Get_FSType_Flags( FT_Face  face )+  {+    TT_OS2*  os2;+++    /* first, try to get the fs_type directly from the font */+    if ( face )+    {+      FT_Service_PsInfo  service = NULL;+++      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );++      if ( service && service->ps_get_font_extra )+      {+        PS_FontExtraRec  extra;+++        if ( !service->ps_get_font_extra( face, &extra ) &&+             extra.fs_type != 0                          )+          return extra.fs_type;+      }+    }++    /* look at FSType before fsType for Type42 */++    if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL &&+         os2->version != 0xFFFFU                                           )+      return os2->fsType;++    return 0;+  }+++/* END */
+ src/base/ftgasp.c view
@@ -0,0 +1,61 @@+/***************************************************************************/+/*                                                                         */+/*  ftgasp.c                                                               */+/*                                                                         */+/*    Access of TrueType's `gasp' table (body).                            */+/*                                                                         */+/*  Copyright 2007 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_GASP_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++  FT_EXPORT_DEF( FT_Int )+  FT_Get_Gasp( FT_Face  face,+               FT_UInt  ppem )+  {+    FT_Int  result = FT_GASP_NO_TABLE;+++    if ( face && FT_IS_SFNT( face ) )+    {+      TT_Face  ttface = (TT_Face)face;+++      if ( ttface->gasp.numRanges > 0 )+      {+        TT_GaspRange  range     = ttface->gasp.gaspRanges;+        TT_GaspRange  range_end = range + ttface->gasp.numRanges;+++        while ( ppem > range->maxPPEM )+        {+          range++;+          if ( range >= range_end )+            goto Exit;+        }++        result = range->gaspFlag;++        /* ensure that we don't have spurious bits */+        if ( ttface->gasp.version == 0 )+          result &= 3;+      }+    }+  Exit:+    return result;+  }+++/* END */
+ src/base/ftgloadr.c view
@@ -0,0 +1,401 @@+/***************************************************************************/+/*                                                                         */+/*  ftgloadr.c                                                             */+/*                                                                         */+/*    The FreeType glyph loader (body).                                    */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2010 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg                       */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_GLYPH_LOADER_H+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_OBJECTS_H++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_gloader+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                                                               *****/+  /*****                    G L Y P H   L O A D E R                    *****/+  /*****                                                               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* The glyph loader is a simple object which is used to load a set of    */+  /* glyphs easily.  It is critical for the correct loading of composites. */+  /*                                                                       */+  /* Ideally, one can see it as a stack of abstract `glyph' objects.       */+  /*                                                                       */+  /*   loader.base     Is really the bottom of the stack.  It describes a  */+  /*                   single glyph image made of the juxtaposition of     */+  /*                   several glyphs (those `in the stack').              */+  /*                                                                       */+  /*   loader.current  Describes the top of the stack, on which a new      */+  /*                   glyph can be loaded.                                */+  /*                                                                       */+  /*   Rewind          Clears the stack.                                   */+  /*   Prepare         Set up `loader.current' for addition of a new glyph */+  /*                   image.                                              */+  /*   Add             Add the `current' glyph image to the `base' one,    */+  /*                   and prepare for another one.                        */+  /*                                                                       */+  /* The glyph loader is now a base object.  Each driver used to           */+  /* re-implement it in one way or the other, which wasted code and        */+  /* energy.                                                               */+  /*                                                                       */+  /*************************************************************************/+++  /* create a new glyph loader */+  FT_BASE_DEF( FT_Error )+  FT_GlyphLoader_New( FT_Memory        memory,+                      FT_GlyphLoader  *aloader )+  {+    FT_GlyphLoader  loader = NULL;+    FT_Error        error;+++    if ( !FT_NEW( loader ) )+    {+      loader->memory = memory;+      *aloader       = loader;+    }+    return error;+  }+++  /* rewind the glyph loader - reset counters to 0 */+  FT_BASE_DEF( void )+  FT_GlyphLoader_Rewind( FT_GlyphLoader  loader )+  {+    FT_GlyphLoad  base    = &loader->base;+    FT_GlyphLoad  current = &loader->current;+++    base->outline.n_points   = 0;+    base->outline.n_contours = 0;+    base->num_subglyphs      = 0;++    *current = *base;+  }+++  /* reset the glyph loader, frees all allocated tables */+  /* and starts from zero                               */+  FT_BASE_DEF( void )+  FT_GlyphLoader_Reset( FT_GlyphLoader  loader )+  {+    FT_Memory memory = loader->memory;+++    FT_FREE( loader->base.outline.points );+    FT_FREE( loader->base.outline.tags );+    FT_FREE( loader->base.outline.contours );+    FT_FREE( loader->base.extra_points );+    FT_FREE( loader->base.subglyphs );++    loader->base.extra_points2 = NULL;++    loader->max_points    = 0;+    loader->max_contours  = 0;+    loader->max_subglyphs = 0;++    FT_GlyphLoader_Rewind( loader );+  }+++  /* delete a glyph loader */+  FT_BASE_DEF( void )+  FT_GlyphLoader_Done( FT_GlyphLoader  loader )+  {+    if ( loader )+    {+      FT_Memory memory = loader->memory;+++      FT_GlyphLoader_Reset( loader );+      FT_FREE( loader );+    }+  }+++  /* re-adjust the `current' outline fields */+  static void+  FT_GlyphLoader_Adjust_Points( FT_GlyphLoader  loader )+  {+    FT_Outline*  base    = &loader->base.outline;+    FT_Outline*  current = &loader->current.outline;+++    current->points   = base->points   + base->n_points;+    current->tags     = base->tags     + base->n_points;+    current->contours = base->contours + base->n_contours;++    /* handle extra points table - if any */+    if ( loader->use_extra )+    {+      loader->current.extra_points  = loader->base.extra_points ++                                      base->n_points;++      loader->current.extra_points2 = loader->base.extra_points2 ++                                      base->n_points;+    }+  }+++  FT_BASE_DEF( FT_Error )+  FT_GlyphLoader_CreateExtra( FT_GlyphLoader  loader )+  {+    FT_Error   error;+    FT_Memory  memory = loader->memory;+++    if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )+    {+      loader->use_extra          = 1;+      loader->base.extra_points2 = loader->base.extra_points ++                                   loader->max_points;++      FT_GlyphLoader_Adjust_Points( loader );+    }+    return error;+  }+++  /* re-adjust the `current' subglyphs field */+  static void+  FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader  loader )+  {+    FT_GlyphLoad  base    = &loader->base;+    FT_GlyphLoad  current = &loader->current;+++    current->subglyphs = base->subglyphs + base->num_subglyphs;+  }+++  /* Ensure that we can add `n_points' and `n_contours' to our glyph.      */+  /* This function reallocates its outline tables if necessary.  Note that */+  /* it DOESN'T change the number of points within the loader!             */+  /*                                                                       */+  FT_BASE_DEF( FT_Error )+  FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,+                              FT_UInt         n_points,+                              FT_UInt         n_contours )+  {+    FT_Memory    memory  = loader->memory;+    FT_Error     error   = FT_Err_Ok;+    FT_Outline*  base    = &loader->base.outline;+    FT_Outline*  current = &loader->current.outline;+    FT_Bool      adjust  = 0;++    FT_UInt      new_max, old_max;+++    /* check points & tags */+    new_max = base->n_points + current->n_points + n_points;+    old_max = loader->max_points;++    if ( new_max > old_max )+    {+      new_max = FT_PAD_CEIL( new_max, 8 );++      if ( new_max > FT_OUTLINE_POINTS_MAX )+        return FT_Err_Array_Too_Large;++      if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||+           FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )+        goto Exit;++      if ( loader->use_extra )+      {+        if ( FT_RENEW_ARRAY( loader->base.extra_points,+                             old_max * 2, new_max * 2 ) )+          goto Exit;++        FT_ARRAY_MOVE( loader->base.extra_points + new_max,+                       loader->base.extra_points + old_max,+                       old_max );++        loader->base.extra_points2 = loader->base.extra_points + new_max;+      }++      adjust = 1;+      loader->max_points = new_max;+    }++    /* check contours */+    old_max = loader->max_contours;+    new_max = base->n_contours + current->n_contours ++              n_contours;+    if ( new_max > old_max )+    {+      new_max = FT_PAD_CEIL( new_max, 4 );++      if ( new_max > FT_OUTLINE_CONTOURS_MAX )+        return FT_Err_Array_Too_Large;++      if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )+        goto Exit;++      adjust = 1;+      loader->max_contours = new_max;+    }++    if ( adjust )+      FT_GlyphLoader_Adjust_Points( loader );++  Exit:+    return error;+  }+++  /* Ensure that we can add `n_subglyphs' to our glyph. this function */+  /* reallocates its subglyphs table if necessary.  Note that it DOES */+  /* NOT change the number of subglyphs within the loader!            */+  /*                                                                  */+  FT_BASE_DEF( FT_Error )+  FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader  loader,+                                 FT_UInt         n_subs )+  {+    FT_Memory     memory = loader->memory;+    FT_Error      error  = FT_Err_Ok;+    FT_UInt       new_max, old_max;++    FT_GlyphLoad  base    = &loader->base;+    FT_GlyphLoad  current = &loader->current;+++    new_max = base->num_subglyphs + current->num_subglyphs + n_subs;+    old_max = loader->max_subglyphs;+    if ( new_max > old_max )+    {+      new_max = FT_PAD_CEIL( new_max, 2 );+      if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) )+        goto Exit;++      loader->max_subglyphs = new_max;++      FT_GlyphLoader_Adjust_Subglyphs( loader );+    }++  Exit:+    return error;+  }+++  /* prepare loader for the addition of a new glyph on top of the base one */+  FT_BASE_DEF( void )+  FT_GlyphLoader_Prepare( FT_GlyphLoader  loader )+  {+    FT_GlyphLoad  current = &loader->current;+++    current->outline.n_points   = 0;+    current->outline.n_contours = 0;+    current->num_subglyphs      = 0;++    FT_GlyphLoader_Adjust_Points   ( loader );+    FT_GlyphLoader_Adjust_Subglyphs( loader );+  }+++  /* add current glyph to the base image - and prepare for another */+  FT_BASE_DEF( void )+  FT_GlyphLoader_Add( FT_GlyphLoader  loader )+  {+    FT_GlyphLoad  base;+    FT_GlyphLoad  current;++    FT_UInt       n_curr_contours;+    FT_UInt       n_base_points;+    FT_UInt       n;+++    if ( !loader )+      return;++    base    = &loader->base;+    current = &loader->current;++    n_curr_contours = current->outline.n_contours;+    n_base_points   = base->outline.n_points;++    base->outline.n_points =+      (short)( base->outline.n_points + current->outline.n_points );+    base->outline.n_contours =+      (short)( base->outline.n_contours + current->outline.n_contours );++    base->num_subglyphs += current->num_subglyphs;++    /* adjust contours count in newest outline */+    for ( n = 0; n < n_curr_contours; n++ )+      current->outline.contours[n] =+        (short)( current->outline.contours[n] + n_base_points );++    /* prepare for another new glyph image */+    FT_GlyphLoader_Prepare( loader );+  }+++  FT_BASE_DEF( FT_Error )+  FT_GlyphLoader_CopyPoints( FT_GlyphLoader  target,+                             FT_GlyphLoader  source )+  {+    FT_Error  error;+    FT_UInt   num_points   = source->base.outline.n_points;+    FT_UInt   num_contours = source->base.outline.n_contours;+++    error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );+    if ( !error )+    {+      FT_Outline*  out = &target->base.outline;+      FT_Outline*  in  = &source->base.outline;+++      FT_ARRAY_COPY( out->points, in->points,+                     num_points );+      FT_ARRAY_COPY( out->tags, in->tags,+                     num_points );+      FT_ARRAY_COPY( out->contours, in->contours,+                     num_contours );++      /* do we need to copy the extra points? */+      if ( target->use_extra && source->use_extra )+      {+        FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points,+                       num_points );+        FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2,+                       num_points );+      }++      out->n_points   = (short)num_points;+      out->n_contours = (short)num_contours;++      FT_GlyphLoader_Adjust_Points( target );+    }++    return error;+  }+++/* END */
+ src/base/ftglyph.c view
@@ -0,0 +1,627 @@+/***************************************************************************/+/*                                                                         */+/*  ftglyph.c                                                              */+/*                                                                         */+/*    FreeType convenience functions to handle glyphs (body).              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /*  This file contains the definition of several convenience functions   */+  /*  that can be used by client applications to easily retrieve glyph     */+  /*  bitmaps and outlines from a given face.                              */+  /*                                                                       */+  /*  These functions should be optional if you are writing a font server  */+  /*  or text layout engine on top of FreeType.  However, they are pretty  */+  /*  handy for many other simple uses of the library.                     */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_GLYPH_H+#include FT_OUTLINE_H+#include FT_BITMAP_H+#include FT_INTERNAL_OBJECTS_H++#include "basepic.h"++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_glyph+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****   FT_BitmapGlyph support                                        ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/++  FT_CALLBACK_DEF( FT_Error )+  ft_bitmap_glyph_init( FT_Glyph      bitmap_glyph,+                        FT_GlyphSlot  slot )+  {+    FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;+    FT_Error        error   = FT_Err_Ok;+    FT_Library      library = FT_GLYPH( glyph )->library;+++    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )+    {+      error = FT_Err_Invalid_Glyph_Format;+      goto Exit;+    }++    glyph->left = slot->bitmap_left;+    glyph->top  = slot->bitmap_top;++    /* do lazy copying whenever possible */+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )+    {+      glyph->bitmap = slot->bitmap;+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;+    }+    else+    {+      FT_Bitmap_New( &glyph->bitmap );+      error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );+    }++  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  ft_bitmap_glyph_copy( FT_Glyph  bitmap_source,+                        FT_Glyph  bitmap_target )+  {+    FT_Library      library = bitmap_source->library;+    FT_BitmapGlyph  source  = (FT_BitmapGlyph)bitmap_source;+    FT_BitmapGlyph  target  = (FT_BitmapGlyph)bitmap_target;+++    target->left = source->left;+    target->top  = source->top;++    return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap );+  }+++  FT_CALLBACK_DEF( void )+  ft_bitmap_glyph_done( FT_Glyph  bitmap_glyph )+  {+    FT_BitmapGlyph  glyph   = (FT_BitmapGlyph)bitmap_glyph;+    FT_Library      library = FT_GLYPH( glyph )->library;+++    FT_Bitmap_Done( library, &glyph->bitmap );+  }+++  FT_CALLBACK_DEF( void )+  ft_bitmap_glyph_bbox( FT_Glyph  bitmap_glyph,+                        FT_BBox*  cbox )+  {+    FT_BitmapGlyph  glyph = (FT_BitmapGlyph)bitmap_glyph;+++    cbox->xMin = glyph->left << 6;+    cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );+    cbox->yMax = glyph->top << 6;+    cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );+  }+++  FT_DEFINE_GLYPH(ft_bitmap_glyph_class,+    sizeof ( FT_BitmapGlyphRec ),+    FT_GLYPH_FORMAT_BITMAP,++    ft_bitmap_glyph_init,+    ft_bitmap_glyph_done,+    ft_bitmap_glyph_copy,+    0,                          /* FT_Glyph_TransformFunc */+    ft_bitmap_glyph_bbox,+    0                           /* FT_Glyph_PrepareFunc   */+  )+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****   FT_OutlineGlyph support                                       ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_CALLBACK_DEF( FT_Error )+  ft_outline_glyph_init( FT_Glyph      outline_glyph,+                         FT_GlyphSlot  slot )+  {+    FT_OutlineGlyph  glyph   = (FT_OutlineGlyph)outline_glyph;+    FT_Error         error   = FT_Err_Ok;+    FT_Library       library = FT_GLYPH( glyph )->library;+    FT_Outline*      source  = &slot->outline;+    FT_Outline*      target  = &glyph->outline;+++    /* check format in glyph slot */+    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )+    {+      error = FT_Err_Invalid_Glyph_Format;+      goto Exit;+    }++    /* allocate new outline */+    error = FT_Outline_New( library, source->n_points, source->n_contours,+                            &glyph->outline );+    if ( error )+      goto Exit;++    FT_Outline_Copy( source, target );++  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( void )+  ft_outline_glyph_done( FT_Glyph  outline_glyph )+  {+    FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;+++    FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );+  }+++  FT_CALLBACK_DEF( FT_Error )+  ft_outline_glyph_copy( FT_Glyph  outline_source,+                         FT_Glyph  outline_target )+  {+    FT_OutlineGlyph  source  = (FT_OutlineGlyph)outline_source;+    FT_OutlineGlyph  target  = (FT_OutlineGlyph)outline_target;+    FT_Error         error;+    FT_Library       library = FT_GLYPH( source )->library;+++    error = FT_Outline_New( library, source->outline.n_points,+                            source->outline.n_contours, &target->outline );+    if ( !error )+      FT_Outline_Copy( &source->outline, &target->outline );++    return error;+  }+++  FT_CALLBACK_DEF( void )+  ft_outline_glyph_transform( FT_Glyph          outline_glyph,+                              const FT_Matrix*  matrix,+                              const FT_Vector*  delta )+  {+    FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;+++    if ( matrix )+      FT_Outline_Transform( &glyph->outline, matrix );++    if ( delta )+      FT_Outline_Translate( &glyph->outline, delta->x, delta->y );+  }+++  FT_CALLBACK_DEF( void )+  ft_outline_glyph_bbox( FT_Glyph  outline_glyph,+                         FT_BBox*  bbox )+  {+    FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;+++    FT_Outline_Get_CBox( &glyph->outline, bbox );+  }+++  FT_CALLBACK_DEF( FT_Error )+  ft_outline_glyph_prepare( FT_Glyph      outline_glyph,+                            FT_GlyphSlot  slot )+  {+    FT_OutlineGlyph  glyph = (FT_OutlineGlyph)outline_glyph;+++    slot->format         = FT_GLYPH_FORMAT_OUTLINE;+    slot->outline        = glyph->outline;+    slot->outline.flags &= ~FT_OUTLINE_OWNER;++    return FT_Err_Ok;+  }+++  FT_DEFINE_GLYPH( ft_outline_glyph_class, +    sizeof ( FT_OutlineGlyphRec ),+    FT_GLYPH_FORMAT_OUTLINE,++    ft_outline_glyph_init,+    ft_outline_glyph_done,+    ft_outline_glyph_copy,+    ft_outline_glyph_transform,+    ft_outline_glyph_bbox,+    ft_outline_glyph_prepare+  )+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****   FT_Glyph class and API                                        ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/++   static FT_Error+   ft_new_glyph( FT_Library             library,+                 const FT_Glyph_Class*  clazz,+                 FT_Glyph*              aglyph )+   {+     FT_Memory  memory = library->memory;+     FT_Error   error;+     FT_Glyph   glyph  = NULL;+++     *aglyph = 0;++     if ( !FT_ALLOC( glyph, clazz->glyph_size ) )+     {+       glyph->library = library;+       glyph->clazz   = clazz;+       glyph->format  = clazz->glyph_format;++       *aglyph = glyph;+     }++     return error;+   }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Glyph_Copy( FT_Glyph   source,+                 FT_Glyph  *target )+  {+    FT_Glyph               copy;+    FT_Error               error;+    const FT_Glyph_Class*  clazz;+++    /* check arguments */+    if ( !target )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    *target = 0;++    if ( !source || !source->clazz )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    clazz = source->clazz;+    error = ft_new_glyph( source->library, clazz, &copy );+    if ( error )+      goto Exit;++    copy->advance = source->advance;+    copy->format  = source->format;++    if ( clazz->glyph_copy )+      error = clazz->glyph_copy( source, copy );++    if ( error )+      FT_Done_Glyph( copy );+    else+      *target = copy;++  Exit:+    return error;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Glyph( FT_GlyphSlot  slot,+                FT_Glyph     *aglyph )+  {+    FT_Library  library;+    FT_Error    error;+    FT_Glyph    glyph;++    const FT_Glyph_Class*  clazz = 0;+++    if ( !slot )+      return FT_Err_Invalid_Slot_Handle;++    library = slot->library;++    if ( !aglyph )+      return FT_Err_Invalid_Argument;++    /* if it is a bitmap, that's easy :-) */+    if ( slot->format == FT_GLYPH_FORMAT_BITMAP )+      clazz = FT_BITMAP_GLYPH_CLASS_GET;++    /* if it is an outline */+    else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )+      clazz = FT_OUTLINE_GLYPH_CLASS_GET;++    else+    {+      /* try to find a renderer that supports the glyph image format */+      FT_Renderer  render = FT_Lookup_Renderer( library, slot->format, 0 );+++      if ( render )+        clazz = &render->glyph_class;+    }++    if ( !clazz )+    {+      error = FT_Err_Invalid_Glyph_Format;+      goto Exit;+    }++    /* create FT_Glyph object */+    error = ft_new_glyph( library, clazz, &glyph );+    if ( error )+      goto Exit;++    /* copy advance while converting it to 16.16 format */+    glyph->advance.x = slot->advance.x << 10;+    glyph->advance.y = slot->advance.y << 10;++    /* now import the image from the glyph slot */+    error = clazz->glyph_init( glyph, slot );++    /* if an error occurred, destroy the glyph */+    if ( error )+      FT_Done_Glyph( glyph );+    else+      *aglyph = glyph;++  Exit:+    return error;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Glyph_Transform( FT_Glyph    glyph,+                      FT_Matrix*  matrix,+                      FT_Vector*  delta )+  {+    const FT_Glyph_Class*  clazz;+    FT_Error               error = FT_Err_Ok;+++    if ( !glyph || !glyph->clazz )+      error = FT_Err_Invalid_Argument;+    else+    {+      clazz = glyph->clazz;+      if ( clazz->glyph_transform )+      {+        /* transform glyph image */+        clazz->glyph_transform( glyph, matrix, delta );++        /* transform advance vector */+        if ( matrix )+          FT_Vector_Transform( &glyph->advance, matrix );+      }+      else+        error = FT_Err_Invalid_Glyph_Format;+    }+    return error;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( void )+  FT_Glyph_Get_CBox( FT_Glyph  glyph,+                     FT_UInt   bbox_mode,+                     FT_BBox  *acbox )+  {+    const FT_Glyph_Class*  clazz;+++    if ( !acbox )+      return;++    acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;++    if ( !glyph || !glyph->clazz )+      return;+    else+    {+      clazz = glyph->clazz;+      if ( !clazz->glyph_bbox )+        return;+      else+      {+        /* retrieve bbox in 26.6 coordinates */+        clazz->glyph_bbox( glyph, acbox );++        /* perform grid fitting if needed */+        if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT ||+             bbox_mode == FT_GLYPH_BBOX_PIXELS  )+        {+          acbox->xMin = FT_PIX_FLOOR( acbox->xMin );+          acbox->yMin = FT_PIX_FLOOR( acbox->yMin );+          acbox->xMax = FT_PIX_CEIL( acbox->xMax );+          acbox->yMax = FT_PIX_CEIL( acbox->yMax );+        }++        /* convert to integer pixels if needed */+        if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE ||+             bbox_mode == FT_GLYPH_BBOX_PIXELS   )+        {+          acbox->xMin >>= 6;+          acbox->yMin >>= 6;+          acbox->xMax >>= 6;+          acbox->yMax >>= 6;+        }+      }+    }+    return;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Glyph_To_Bitmap( FT_Glyph*       the_glyph,+                      FT_Render_Mode  render_mode,+                      FT_Vector*      origin,+                      FT_Bool         destroy )+  {+    FT_GlyphSlotRec           dummy;+    FT_GlyphSlot_InternalRec  dummy_internal;+    FT_Error                  error = FT_Err_Ok;+    FT_Glyph                  glyph;+    FT_BitmapGlyph            bitmap = NULL;++    const FT_Glyph_Class*     clazz;++#ifdef FT_CONFIG_OPTION_PIC+    FT_Library                library = FT_GLYPH( glyph )->library;+#endif+++    /* check argument */+    if ( !the_glyph )+      goto Bad;++    /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */+    /* then calling FT_Render_Glyph_Internal()                            */++    glyph = *the_glyph;+    if ( !glyph )+      goto Bad;++    clazz = glyph->clazz;++    /* when called with a bitmap glyph, do nothing and return successfully */+    if ( clazz == FT_BITMAP_GLYPH_CLASS_GET )+      goto Exit;++    if ( !clazz || !clazz->glyph_prepare )+      goto Bad;++    FT_MEM_ZERO( &dummy, sizeof ( dummy ) );+    FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );+    dummy.internal = &dummy_internal;+    dummy.library  = glyph->library;+    dummy.format   = clazz->glyph_format;++    /* create result bitmap glyph */+    error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET,+                          (FT_Glyph*)(void*)&bitmap );+    if ( error )+      goto Exit;++#if 1+    /* if `origin' is set, translate the glyph image */+    if ( origin )+      FT_Glyph_Transform( glyph, 0, origin );+#else+    FT_UNUSED( origin );+#endif++    /* prepare dummy slot for rendering */+    error = clazz->glyph_prepare( glyph, &dummy );+    if ( !error )+      error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );++#if 1+    if ( !destroy && origin )+    {+      FT_Vector  v;+++      v.x = -origin->x;+      v.y = -origin->y;+      FT_Glyph_Transform( glyph, 0, &v );+    }+#endif++    if ( error )+      goto Exit;++    /* in case of success, copy the bitmap to the glyph bitmap */+    error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy );+    if ( error )+      goto Exit;++    /* copy advance */+    bitmap->root.advance = glyph->advance;++    if ( destroy )+      FT_Done_Glyph( glyph );++    *the_glyph = FT_GLYPH( bitmap );++  Exit:+    if ( error && bitmap )+      FT_Done_Glyph( FT_GLYPH( bitmap ) );++    return error;++  Bad:+    error = FT_Err_Invalid_Argument;+    goto Exit;+  }+++  /* documentation is in ftglyph.h */++  FT_EXPORT_DEF( void )+  FT_Done_Glyph( FT_Glyph  glyph )+  {+    if ( glyph )+    {+      FT_Memory              memory = glyph->library->memory;+      const FT_Glyph_Class*  clazz  = glyph->clazz;+++      if ( clazz->glyph_done )+        clazz->glyph_done( glyph );++      FT_FREE( glyph );+    }+  }+++/* END */
+ src/base/ftgxval.c view
@@ -0,0 +1,140 @@+/***************************************************************************/+/*                                                                         */+/*  ftgxval.c                                                              */+/*                                                                         */+/*    FreeType API for validating TrueTyepGX/AAT tables (body).            */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2010 by                                    */+/*  Masatake YAMATO, Redhat K.K,                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/***************************************************************************/+/*                                                                         */+/* gxvalid is derived from both gxlayout module and otvalid module.        */+/* Development of gxlayout is supported by the Information-technology      */+/* Promotion Agency(IPA), Japan.                                           */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_GX_VALIDATE_H+++  /* documentation is in ftgxval.h */++  FT_EXPORT_DEF( FT_Error )+  FT_TrueTypeGX_Validate( FT_Face   face,+                          FT_UInt   validation_flags,+                          FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],+                          FT_UInt   table_length )+  {+    FT_Service_GXvalidate  service;+    FT_Error               error;+++    if ( !face )+    {+      error = FT_Err_Invalid_Face_Handle;+      goto Exit;+    }++    if ( tables == NULL )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE );++    if ( service )+      error = service->validate( face,+                                 validation_flags,+                                 tables,+                                 table_length );+    else+      error = FT_Err_Unimplemented_Feature;++  Exit:+    return error;+  }+++  FT_EXPORT_DEF( void )+  FT_TrueTypeGX_Free( FT_Face   face,+                      FT_Bytes  table )+  {+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );++    FT_FREE( table );+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_ClassicKern_Validate( FT_Face    face,+                           FT_UInt    validation_flags,+                           FT_Bytes  *ckern_table )+  {+    FT_Service_CKERNvalidate  service;+    FT_Error                  error;+++    if ( !face )+    {+      error = FT_Err_Invalid_Face_Handle;+      goto Exit;+    }++    if ( ckern_table == NULL )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE );++    if ( service )+      error = service->validate( face,+                                 validation_flags,+                                 ckern_table );+    else+      error = FT_Err_Unimplemented_Feature;++  Exit:+    return error;+  }+++  FT_EXPORT_DEF( void )+  FT_ClassicKern_Free( FT_Face   face,+                       FT_Bytes  table )+  {+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );+++    FT_FREE( table );+  }+++/* END */
+ src/base/ftinit.c view
@@ -0,0 +1,253 @@+/***************************************************************************/+/*                                                                         */+/*  ftinit.c                                                               */+/*                                                                         */+/*    FreeType initialization layer (body).                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2005, 2007, 2009 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /*  The purpose of this file is to implement the following two           */+  /*  functions:                                                           */+  /*                                                                       */+  /*  FT_Add_Default_Modules():                                            */+  /*     This function is used to add the set of default modules to a      */+  /*     fresh new library object.  The set is taken from the header file  */+  /*     `freetype/config/ftmodule.h'.  See the document `FreeType 2.0     */+  /*     Build System' for more information.                               */+  /*                                                                       */+  /*  FT_Init_FreeType():                                                  */+  /*     This function creates a system object for the current platform,   */+  /*     builds a library out of it, then calls FT_Default_Drivers().      */+  /*                                                                       */+  /*  Note that even if FT_Init_FreeType() uses the implementation of the  */+  /*  system object defined at build time, client applications are still   */+  /*  able to provide their own `ftsystem.c'.                              */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_MODULE_H+#include "basepic.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_init++#ifndef FT_CONFIG_OPTION_PIC++#undef  FT_USE_MODULE+#ifdef __cplusplus+#define FT_USE_MODULE( type, x )  extern "C" const type  x;+#else+#define FT_USE_MODULE( type, x )  extern const type  x;+#endif+++#include FT_CONFIG_MODULES_H+++#undef  FT_USE_MODULE+#define FT_USE_MODULE( type, x )  (const FT_Module_Class*)&(x),++  static+  const FT_Module_Class*  const ft_default_modules[] =+  {+#include FT_CONFIG_MODULES_H+    0+  };++#else /* FT_CONFIG_OPTION_PIC */++#ifdef __cplusplus+#define FT_EXTERNC  extern "C"+#else+#define FT_EXTERNC  extern+#endif++  /* declare the module's class creation/destruction functions */+#undef  FT_USE_MODULE+#define FT_USE_MODULE( type, x )  \+  FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \+  FT_EXTERNC void     FT_Destroy_Class_##x( FT_Library library, FT_Module_Class*  clazz );++#include FT_CONFIG_MODULES_H+++  /* count all module classes */+#undef  FT_USE_MODULE+#define FT_USE_MODULE( type, x )  MODULE_CLASS_##x,++  enum+  {+#include FT_CONFIG_MODULES_H+    FT_NUM_MODULE_CLASSES+  };++  /* destroy all module classes */  +#undef  FT_USE_MODULE+#define FT_USE_MODULE( type, x )  \+  if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \+  i++;                                                             \++  FT_BASE_DEF( void )+  ft_destroy_default_module_classes( FT_Library  library )+  {+    FT_Module_Class** classes;+    FT_Memory         memory;+    FT_UInt           i;+    BasePIC*          pic_container = (BasePIC*)library->pic_container.base;++    if ( !pic_container->default_module_classes )+      return;++    memory = library->memory;+    classes = pic_container->default_module_classes;+    i = 0;++#include FT_CONFIG_MODULES_H++    FT_FREE( classes );+    pic_container->default_module_classes = 0;+  }++  /* initialize all module classes and the pointer table */+#undef  FT_USE_MODULE+#define FT_USE_MODULE( type, x )                \+  error = FT_Create_Class_##x(library, &clazz); \+  if (error) goto Exit;                         \+  classes[i++] = clazz;++  FT_BASE_DEF( FT_Error )+  ft_create_default_module_classes( FT_Library  library )+  {+    FT_Error          error;+    FT_Memory         memory;+    FT_Module_Class** classes;+    FT_Module_Class*  clazz;+    FT_UInt           i;+    BasePIC*          pic_container = (BasePIC*)library->pic_container.base;++    memory = library->memory;  +    pic_container->default_module_classes = 0;++    if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) )+      return error;+    /* initialize all pointers to 0, especially the last one */+    for (i = 0; i < FT_NUM_MODULE_CLASSES; i++)+      classes[i] = 0;+    classes[FT_NUM_MODULE_CLASSES] = 0;++    i = 0;++#include FT_CONFIG_MODULES_H++Exit:    +    if (error) ft_destroy_default_module_classes( library );+    else pic_container->default_module_classes = classes;++    return error;    +  }+++#endif /* FT_CONFIG_OPTION_PIC */++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( void )+  FT_Add_Default_Modules( FT_Library  library )+  {+    FT_Error                       error;+    const FT_Module_Class* const*  cur;+++    /* test for valid `library' delayed to FT_Add_Module() */++    cur = FT_DEFAULT_MODULES_GET;+    while ( *cur )+    {+      error = FT_Add_Module( library, *cur );+      /* notify errors, but don't stop */+      if ( error )+        FT_TRACE0(( "FT_Add_Default_Module:"+                    " Cannot install `%s', error = 0x%x\n",+                    (*cur)->module_name, error ));+      cur++;+    }+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Init_FreeType( FT_Library  *alibrary )+  {+    FT_Error   error;+    FT_Memory  memory;+++    /* First of all, allocate a new system object -- this function is part */+    /* of the system-specific component, i.e. `ftsystem.c'.                */++    memory = FT_New_Memory();+    if ( !memory )+    {+      FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));+      return FT_Err_Unimplemented_Feature;+    }++    /* build a library out of it, then fill it with the set of */+    /* default drivers.                                        */++    error = FT_New_Library( memory, alibrary );+    if ( error )+      FT_Done_Memory( memory );+    else+      FT_Add_Default_Modules( *alibrary );++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Done_FreeType( FT_Library  library )+  {+    if ( library )+    {+      FT_Memory  memory = library->memory;+++      /* Discard the library object */+      FT_Done_Library( library );++      /* discard memory manager */+      FT_Done_Memory( memory );+    }++    return FT_Err_Ok;+  }+++/* END */
+ src/base/ftlcdfil.c view
@@ -0,0 +1,376 @@+/***************************************************************************/+/*                                                                         */+/*  ftlcdfil.c                                                             */+/*                                                                         */+/*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */+/*                                                                         */+/*  Copyright 2006, 2008, 2009, 2010 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_LCD_FILTER_H+#include FT_IMAGE_H+#include FT_INTERNAL_OBJECTS_H+++#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING++/* define USE_LEGACY to implement the legacy filter */+#define  USE_LEGACY++  /* FIR filter used by the default and light filters */+  static void+  _ft_lcd_filter_fir( FT_Bitmap*      bitmap,+                      FT_Render_Mode  mode,+                      FT_Library      library )+  {+    FT_Byte*  weights = library->lcd_weights;+    FT_UInt   width   = (FT_UInt)bitmap->width;+    FT_UInt   height  = (FT_UInt)bitmap->rows;+++    /* horizontal in-place FIR filter */+    if ( mode == FT_RENDER_MODE_LCD && width >= 4 )+    {+      FT_Byte*  line = bitmap->buffer;+++      for ( ; height > 0; height--, line += bitmap->pitch )+      {+        FT_UInt  fir[5];+        FT_UInt  val1, xx;+++        val1   = line[0];+        fir[0] = weights[2] * val1;+        fir[1] = weights[3] * val1;+        fir[2] = weights[4] * val1;+        fir[3] = 0;+        fir[4] = 0;++        val1    = line[1];+        fir[0] += weights[1] * val1;+        fir[1] += weights[2] * val1;+        fir[2] += weights[3] * val1;+        fir[3] += weights[4] * val1;++        for ( xx = 2; xx < width; xx++ )+        {+          FT_UInt  val, pix;+++          val    = line[xx];+          pix    = fir[0] + weights[0] * val;+          fir[0] = fir[1] + weights[1] * val;+          fir[1] = fir[2] + weights[2] * val;+          fir[2] = fir[3] + weights[3] * val;+          fir[3] =          weights[4] * val;++          pix        >>= 8;+          pix         |= -( pix >> 8 );+          line[xx - 2] = (FT_Byte)pix;+        }++        {+          FT_UInt  pix;+++          pix          = fir[0] >> 8;+          pix         |= -( pix >> 8 );+          line[xx - 2] = (FT_Byte)pix;++          pix          = fir[1] >> 8;+          pix         |= -( pix >> 8 );+          line[xx - 1] = (FT_Byte)pix;+        }+      }+    }++    /* vertical in-place FIR filter */+    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )+    {+      FT_Byte*  column = bitmap->buffer;+      FT_Int    pitch  = bitmap->pitch;+++      for ( ; width > 0; width--, column++ )+      {+        FT_Byte*  col = column;+        FT_UInt   fir[5];+        FT_UInt   val1, yy;+++        val1   = col[0];+        fir[0] = weights[2] * val1;+        fir[1] = weights[3] * val1;+        fir[2] = weights[4] * val1;+        fir[3] = 0;+        fir[4] = 0;+        col   += pitch;++        val1    = col[0];+        fir[0] += weights[1] * val1;+        fir[1] += weights[2] * val1;+        fir[2] += weights[3] * val1;+        fir[3] += weights[4] * val1;+        col    += pitch;++        for ( yy = 2; yy < height; yy++ )+        {+          FT_UInt  val, pix;+++          val    = col[0];+          pix    = fir[0] + weights[0] * val;+          fir[0] = fir[1] + weights[1] * val;+          fir[1] = fir[2] + weights[2] * val;+          fir[2] = fir[3] + weights[3] * val;+          fir[3] =          weights[4] * val;++          pix           >>= 8;+          pix            |= -( pix >> 8 );+          col[-2 * pitch] = (FT_Byte)pix;+          col            += pitch;+        }++        {+          FT_UInt  pix;+++          pix             = fir[0] >> 8;+          pix            |= -( pix >> 8 );+          col[-2 * pitch] = (FT_Byte)pix;++          pix         = fir[1] >> 8;+          pix        |= -( pix >> 8 );+          col[-pitch] = (FT_Byte)pix;+        }+      }+    }+  }+++#ifdef USE_LEGACY++  /* intra-pixel filter used by the legacy filter */+  static void+  _ft_lcd_filter_legacy( FT_Bitmap*      bitmap,+                         FT_Render_Mode  mode,+                         FT_Library      library )+  {+    FT_UInt  width  = (FT_UInt)bitmap->width;+    FT_UInt  height = (FT_UInt)bitmap->rows;+    FT_Int   pitch  = bitmap->pitch;++    static const int  filters[3][3] =+    {+      { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },+      { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },+      { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }+    };++    FT_UNUSED( library );+++    /* horizontal in-place intra-pixel filter */+    if ( mode == FT_RENDER_MODE_LCD && width >= 3 )+    {+      FT_Byte*  line = bitmap->buffer;+++      for ( ; height > 0; height--, line += pitch )+      {+        FT_UInt  xx;+++        for ( xx = 0; xx < width; xx += 3 )+        {+          FT_UInt  r = 0;+          FT_UInt  g = 0;+          FT_UInt  b = 0;+          FT_UInt  p;+++          p  = line[xx];+          r += filters[0][0] * p;+          g += filters[0][1] * p;+          b += filters[0][2] * p;++          p  = line[xx + 1];+          r += filters[1][0] * p;+          g += filters[1][1] * p;+          b += filters[1][2] * p;++          p  = line[xx + 2];+          r += filters[2][0] * p;+          g += filters[2][1] * p;+          b += filters[2][2] * p;++          line[xx]     = (FT_Byte)( r / 65536 );+          line[xx + 1] = (FT_Byte)( g / 65536 );+          line[xx + 2] = (FT_Byte)( b / 65536 );+        }+      }+    }+    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )+    {+      FT_Byte*  column = bitmap->buffer;+++      for ( ; width > 0; width--, column++ )+      {+        FT_Byte*  col     = column;+        FT_Byte*  col_end = col + height * pitch;+++        for ( ; col < col_end; col += 3 * pitch )+        {+          FT_UInt  r = 0;+          FT_UInt  g = 0;+          FT_UInt  b = 0;+          FT_UInt  p;+++          p  = col[0];+          r += filters[0][0] * p;+          g += filters[0][1] * p;+          b += filters[0][2] * p;++          p  = col[pitch];+          r += filters[1][0] * p;+          g += filters[1][1] * p;+          b += filters[1][2] * p;++          p  = col[pitch * 2];+          r += filters[2][0] * p;+          g += filters[2][1] * p;+          b += filters[2][2] * p;++          col[0]         = (FT_Byte)( r / 65536 );+          col[pitch]     = (FT_Byte)( g / 65536 );+          col[2 * pitch] = (FT_Byte)( b / 65536 );+        }+      }+    }+  }++#endif /* USE_LEGACY */+++  FT_EXPORT_DEF( FT_Error )+  FT_Library_SetLcdFilterWeights( FT_Library      library,+                                  unsigned char  *weights )+  {+    if ( !library || !weights )+      return FT_Err_Invalid_Argument;++    ft_memcpy( library->lcd_weights, weights, 5 );++    return FT_Err_Ok;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Library_SetLcdFilter( FT_Library    library,+                           FT_LcdFilter  filter )+  {+    static const FT_Byte  light_filter[5] =+                            { 0x00, 0x55, 0x56, 0x55, 0x00 };+    /* the values here sum up to a value larger than 256, */+    /* providing a cheap gamma correction                 */+    static const FT_Byte  default_filter[5] =+                            { 0x10, 0x40, 0x70, 0x40, 0x10 };+++    if ( !library )+      return FT_Err_Invalid_Argument;++    switch ( filter )+    {+    case FT_LCD_FILTER_NONE:+      library->lcd_filter_func = NULL;+      library->lcd_extra       = 0;+      break;++    case FT_LCD_FILTER_DEFAULT:+#if defined( FT_FORCE_LEGACY_LCD_FILTER )++      library->lcd_filter_func = _ft_lcd_filter_legacy;+      library->lcd_extra       = 0;++#elif defined( FT_FORCE_LIGHT_LCD_FILTER )++      ft_memcpy( library->lcd_weights, light_filter, 5 );+      library->lcd_filter_func = _ft_lcd_filter_fir;+      library->lcd_extra       = 2;++#else++      ft_memcpy( library->lcd_weights, default_filter, 5 );+      library->lcd_filter_func = _ft_lcd_filter_fir;+      library->lcd_extra       = 2;++#endif++      break;++    case FT_LCD_FILTER_LIGHT:+      ft_memcpy( library->lcd_weights, light_filter, 5 );+      library->lcd_filter_func = _ft_lcd_filter_fir;+      library->lcd_extra       = 2;+      break;++#ifdef USE_LEGACY++    case FT_LCD_FILTER_LEGACY:+      library->lcd_filter_func = _ft_lcd_filter_legacy;+      library->lcd_extra       = 0;+      break;++#endif++    default:+      return FT_Err_Invalid_Argument;+    }++    library->lcd_filter = filter;++    return FT_Err_Ok;+  }++#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */++  FT_EXPORT_DEF( FT_Error )+  FT_Library_SetLcdFilterWeights( FT_Library      library,+                                  unsigned char  *weights )+  {+    FT_UNUSED( library );+    FT_UNUSED( weights );++    return FT_Err_Unimplemented_Feature;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Library_SetLcdFilter( FT_Library    library,+                           FT_LcdFilter  filter )+  {+    FT_UNUSED( library );+    FT_UNUSED( filter );++    return FT_Err_Unimplemented_Feature;+  }++#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */+++/* END */
+ src/base/ftmac.c view
@@ -0,0 +1,1057 @@+/***************************************************************************/+/*                                                                         */+/*  ftmac.c                                                                */+/*                                                                         */+/*    Mac FOND support.  Written by just@letterror.com.                    */+/*  Heavily modified by mpsuzuki, George Williams, and Sean McBride.       */+/*                                                                         */+/*  This file is for Mac OS X only; see builds/mac/ftoldmac.c for          */+/*  classic platforms built by MPW.                                        */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,         */+/*            2009 by                                                      */+/*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*+    Notes++    Mac suitcase files can (and often do!) contain multiple fonts.  To+    support this I use the face_index argument of FT_(Open|New)_Face()+    functions, and pretend the suitcase file is a collection.++    Warning: fbit and NFNT bitmap resources are not supported yet.  In old+    sfnt fonts, bitmap glyph data for each size is stored in each `NFNT'+    resources instead of the `bdat' table in the sfnt resource.  Therefore,+    face->num_fixed_sizes is set to 0, because bitmap data in `NFNT'+    resource is unavailable at present.++    The Mac FOND support works roughly like this:++    - Check whether the offered stream points to a Mac suitcase file.  This+      is done by checking the file type: it has to be 'FFIL' or 'tfil'.  The+      stream that gets passed to our init_face() routine is a stdio stream,+      which isn't usable for us, since the FOND resources live in the+      resource fork.  So we just grab the stream->pathname field.++    - Read the FOND resource into memory, then check whether there is a+      TrueType font and/or(!) a Type 1 font available.++    - If there is a Type 1 font available (as a separate `LWFN' file), read+      its data into memory, massage it slightly so it becomes PFB data, wrap+      it into a memory stream, load the Type 1 driver and delegate the rest+      of the work to it by calling FT_Open_Face().  (XXX TODO: after this+      has been done, the kerning data from the FOND resource should be+      appended to the face: On the Mac there are usually no AFM files+      available.  However, this is tricky since we need to map Mac char+      codes to ps glyph names to glyph ID's...)++    - If there is a TrueType font (an `sfnt' resource), read it into memory,+      wrap it into a memory stream, load the TrueType driver and delegate+      the rest of the work to it, by calling FT_Open_Face().++    - Some suitcase fonts (notably Onyx) might point the `LWFN' file to+      itself, even though it doesn't contains `POST' resources.  To handle+      this special case without opening the file an extra time, we just+      ignore errors from the `LWFN' and fallback to the `sfnt' if both are+      available.+  */+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TRUETYPE_TAGS_H+#include FT_INTERNAL_STREAM_H+#include "ftbase.h"++  /* This is for Mac OS X.  Without redefinition, OS_INLINE */+  /* expands to `static inline' which doesn't survive the   */+  /* -ansi compilation flag of GCC.                         */+#if !HAVE_ANSI_OS_INLINE+#undef  OS_INLINE+#define OS_INLINE  static __inline__+#endif++  /* `configure' checks the availability of `ResourceIndex' strictly */+  /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always.  If it is      */+  /* not set (e.g., a build without `configure'), the availability   */+  /* is guessed from the SDK version.                                */+#ifndef HAVE_TYPE_RESOURCE_INDEX+#if !defined( MAC_OS_X_VERSION_10_5 ) || \+    ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 )+#define HAVE_TYPE_RESOURCE_INDEX 0+#else+#define HAVE_TYPE_RESOURCE_INDEX 1+#endif+#endif /* !HAVE_TYPE_RESOURCE_INDEX */++#if ( HAVE_TYPE_RESOURCE_INDEX == 0 )+  typedef short  ResourceIndex;+#endif++#include <CoreServices/CoreServices.h>+#include <ApplicationServices/ApplicationServices.h>+#include <sys/syslimits.h> /* PATH_MAX */++  /* Don't want warnings about our own use of deprecated functions. */+#define FT_DEPRECATED_ATTRIBUTE++#include FT_MAC_H++#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */+#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault+#endif+++  /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over+     TrueType in case *both* are available (this is not common,+     but it *is* possible). */+#ifndef PREFER_LWFN+#define PREFER_LWFN  1+#endif+++  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */+  FT_EXPORT_DEF( FT_Error )+  FT_GetFile_From_Mac_Name( const char*  fontName,+                            FSSpec*      pathSpec,+                            FT_Long*     face_index )+  {+    FT_UNUSED( fontName );+    FT_UNUSED( pathSpec );+    FT_UNUSED( face_index );++    return FT_Err_Unimplemented_Feature;+  }+++  /* Private function.                                         */+  /* The FSSpec type has been discouraged for a long time,     */+  /* unfortunately an FSRef replacement API for                */+  /* ATSFontGetFileSpecification() is only available in        */+  /* Mac OS X 10.5 and later.                                  */+  static OSStatus+  FT_ATSFontGetFileReference( ATSFontRef  ats_font_id,+                              FSRef*      ats_font_ref )+  {+#if defined( MAC_OS_X_VERSION_10_5 ) && \+    ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )+ +    OSStatus  err;++    err = ATSFontGetFileReference( ats_font_id, ats_font_ref );++    return err;+#elif __LP64__ /* No 64bit Carbon API on legacy platforms */+    FT_UNUSED( ats_font_id );+    FT_UNUSED( ats_font_ref );+++    return fnfErr;+#else /* 32bit Carbon API on legacy platforms */+    OSStatus  err;+    FSSpec    spec;+++    err = ATSFontGetFileSpecification( ats_font_id, &spec );+    if ( noErr == err )+      err = FSpMakeFSRef( &spec, ats_font_ref );++    return err;+#endif+  }+++  static FT_Error+  FT_GetFileRef_From_Mac_ATS_Name( const char*  fontName,+                                   FSRef*       ats_font_ref,+                                   FT_Long*     face_index )+  {+    CFStringRef  cf_fontName;+    ATSFontRef   ats_font_id;+++    *face_index = 0;++    cf_fontName = CFStringCreateWithCString( NULL, fontName,+                                             kCFStringEncodingMacRoman );+    ats_font_id = ATSFontFindFromName( cf_fontName,+                                       kATSOptionFlagsUnRestrictedScope );+    CFRelease( cf_fontName );++    if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )+      return FT_Err_Unknown_File_Format;++    if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) )+      return FT_Err_Unknown_File_Format;++    /* face_index calculation by searching preceding fontIDs */+    /* with same FSRef                                       */+    {+      ATSFontRef  id2 = ats_font_id - 1;+      FSRef       ref2;+++      while ( id2 > 0 )+      {+        if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) )+          break;+        if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) )+          break;++        id2 --;+      }+      *face_index = ats_font_id - ( id2 + 1 );+    }++    return FT_Err_Ok;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,+                                    UInt8*       path,+                                    UInt32       maxPathSize,+                                    FT_Long*     face_index )+  {+    FSRef     ref;+    FT_Error  err;+++    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );+    if ( FT_Err_Ok != err )+      return err;++    if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) )+      return FT_Err_Unknown_File_Format;++    return FT_Err_Ok;+  }+++  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */+  FT_EXPORT_DEF( FT_Error )+  FT_GetFile_From_Mac_ATS_Name( const char*  fontName,+                                FSSpec*      pathSpec,+                                FT_Long*     face_index )+  {+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )+    FT_UNUSED( fontName );+    FT_UNUSED( pathSpec );+    FT_UNUSED( face_index );++    return FT_Err_Unimplemented_Feature;+#else+    FSRef     ref;+    FT_Error  err;+++    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );+    if ( FT_Err_Ok != err )+      return err;++    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL,+                                    pathSpec, NULL ) )+      return FT_Err_Unknown_File_Format;++    return FT_Err_Ok;+#endif+  }+++  static OSErr+  FT_FSPathMakeRes( const UInt8*    pathname,+                    ResFileRefNum*  res )+  {+    OSErr  err;+    FSRef  ref;+++    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )+      return FT_Err_Cannot_Open_Resource;++    /* at present, no support for dfont format */+    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );+    if ( noErr == err )+      return err;++    /* fallback to original resource-fork font */+    *res = FSOpenResFile( &ref, fsRdPerm );+    err  = ResError();++    return err;+  }+++  /* Return the file type for given pathname */+  static OSType+  get_file_type_from_path( const UInt8*  pathname )+  {+    FSRef          ref;+    FSCatalogInfo  info;+++    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )+      return ( OSType ) 0;++    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info,+                                    NULL, NULL, NULL ) )+      return ( OSType ) 0;++    return ((FInfo *)(info.finderInfo))->fdType;+  }+++  /* Given a PostScript font name, create the Macintosh LWFN file name. */+  static void+  create_lwfn_name( char*   ps_name,+                    Str255  lwfn_file_name )+  {+    int       max = 5, count = 0;+    FT_Byte*  p = lwfn_file_name;+    FT_Byte*  q = (FT_Byte*)ps_name;+++    lwfn_file_name[0] = 0;++    while ( *q )+    {+      if ( ft_isupper( *q ) )+      {+        if ( count )+          max = 3;+        count = 0;+      }+      if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) )+      {+        *++p = *q;+        lwfn_file_name[0]++;+        count++;+      }+      q++;+    }+  }+++  static short+  count_faces_sfnt( char*  fond_data )+  {+    /* The count is 1 greater than the value in the FOND.  */+    /* Isn't that cute? :-)                                */++    return EndianS16_BtoN( *( (short*)( fond_data ++                                        sizeof ( FamRec ) ) ) ) + 1;+  }+++  static short+  count_faces_scalable( char*  fond_data )+  {+    AsscEntry*  assoc;+    FamRec*     fond;+    short       i, face, face_all;+++    fond     = (FamRec*)fond_data;+    face_all = EndianS16_BtoN( *( (short *)( fond_data ++                                             sizeof ( FamRec ) ) ) ) + 1;+    assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );+    face     = 0;++    for ( i = 0; i < face_all; i++ )+    {+      if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )+        face++;+    }+    return face;+  }+++  /* Look inside the FOND data, answer whether there should be an SFNT+     resource, and answer the name of a possible LWFN Type 1 file.++     Thanks to Paul Miller (paulm@profoundeffects.com) for the fix+     to load a face OTHER than the first one in the FOND!+  */+++  static void+  parse_fond( char*   fond_data,+              short*  have_sfnt,+              ResID*  sfnt_id,+              Str255  lwfn_file_name,+              short   face_index )+  {+    AsscEntry*  assoc;+    AsscEntry*  base_assoc;+    FamRec*     fond;+++    *sfnt_id          = 0;+    *have_sfnt        = 0;+    lwfn_file_name[0] = 0;++    fond       = (FamRec*)fond_data;+    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );+    base_assoc = assoc;++    /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */+    if ( 47 < face_index )+      return;++    /* Let's do a little range checking before we get too excited here */+    if ( face_index < count_faces_sfnt( fond_data ) )+    {+      assoc += face_index;        /* add on the face_index! */++      /* if the face at this index is not scalable,+         fall back to the first one (old behavior) */+      if ( EndianS16_BtoN( assoc->fontSize ) == 0 )+      {+        *have_sfnt = 1;+        *sfnt_id   = EndianS16_BtoN( assoc->fontID );+      }+      else if ( base_assoc->fontSize == 0 )+      {+        *have_sfnt = 1;+        *sfnt_id   = EndianS16_BtoN( base_assoc->fontID );+      }+    }++    if ( EndianS32_BtoN( fond->ffStylOff ) )+    {+      unsigned char*  p = (unsigned char*)fond_data;+      StyleTable*     style;+      unsigned short  string_count;+      char            ps_name[256];+      unsigned char*  names[64];+      int             i;+++      p += EndianS32_BtoN( fond->ffStylOff );+      style = (StyleTable*)p;+      p += sizeof ( StyleTable );+      string_count = EndianS16_BtoN( *(short*)(p) );+      p += sizeof ( short );++      for ( i = 0; i < string_count && i < 64; i++ )+      {+        names[i] = p;+        p       += names[i][0];+        p++;+      }++      {+        size_t  ps_name_len = (size_t)names[0][0];+++        if ( ps_name_len != 0 )+        {+          ft_memcpy(ps_name, names[0] + 1, ps_name_len);+          ps_name[ps_name_len] = 0;+        }+        if ( style->indexes[face_index] > 1 &&+             style->indexes[face_index] <= FT_MIN( string_count, 64 ) )+        {+          unsigned char*  suffixes = names[style->indexes[face_index] - 1];+++          for ( i = 1; i <= suffixes[0]; i++ )+          {+            unsigned char*  s;+            size_t          j = suffixes[i] - 1;+++            if ( j < string_count && ( s = names[j] ) != NULL )+            {+              size_t  s_len = (size_t)s[0];+++              if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )+              {+                ft_memcpy( ps_name + ps_name_len, s + 1, s_len );+                ps_name_len += s_len;+                ps_name[ps_name_len] = 0;+              }+            }+          }+        }+      }++      create_lwfn_name( ps_name, lwfn_file_name );+    }+  }+++  static  FT_Error+  lookup_lwfn_by_fond( const UInt8*      path_fond,+                       ConstStr255Param  base_lwfn,+                       UInt8*            path_lwfn,+                       size_t            path_size )+  {+    FSRef   ref, par_ref;+    size_t  dirname_len;+++    /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */+    /* We should not extract parent directory by string manipulation.      */++    if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) )+      return FT_Err_Invalid_Argument;++    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,+                                    NULL, NULL, NULL, &par_ref ) )+      return FT_Err_Invalid_Argument;++    if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) )+      return FT_Err_Invalid_Argument;++    if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )+      return FT_Err_Invalid_Argument;++    /* now we have absolute dirname in path_lwfn */+    ft_strcat( (char *)path_lwfn, "/" );+    dirname_len = ft_strlen( (char *)path_lwfn );+    ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 );+    path_lwfn[dirname_len + base_lwfn[0]] = '\0';++    if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) )+      return FT_Err_Cannot_Open_Resource;++    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,+                                    NULL, NULL, NULL, NULL ) )+      return FT_Err_Cannot_Open_Resource;++    return FT_Err_Ok;+  }+++  static short+  count_faces( Handle        fond,+               const UInt8*  pathname )+  {+    ResID     sfnt_id;+    short     have_sfnt, have_lwfn;+    Str255    lwfn_file_name;+    UInt8     buff[PATH_MAX];+    FT_Error  err;+    short     num_faces;+++    have_sfnt = have_lwfn = 0;++    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );++    if ( lwfn_file_name[0] )+    {+      err = lookup_lwfn_by_fond( pathname, lwfn_file_name,+                                 buff, sizeof ( buff )  );+      if ( FT_Err_Ok == err )+        have_lwfn = 1;+    }++    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )+      num_faces = 1;+    else+      num_faces = count_faces_scalable( *fond );++    return num_faces;+  }+++  /* Read Type 1 data from the POST resources inside the LWFN file,+     return a PFB buffer.  This is somewhat convoluted because the FT2+     PFB parser wants the ASCII header as one chunk, and the LWFN+     chunks are often not organized that way, so we glue chunks+     of the same type together. */+  static FT_Error+  read_lwfn( FT_Memory      memory,+             ResFileRefNum  res,+             FT_Byte**      pfb_data,+             FT_ULong*      size )+  {+    FT_Error       error = FT_Err_Ok;+    ResID          res_id;+    unsigned char  *buffer, *p, *size_p = NULL;+    FT_ULong       total_size = 0;+    FT_ULong       old_total_size = 0;+    FT_ULong       post_size, pfb_chunk_size;+    Handle         post_data;+    char           code, last_code;+++    UseResFile( res );++    /* First pass: load all POST resources, and determine the size of */+    /* the output buffer.                                             */+    res_id    = 501;+    last_code = -1;++    for (;;)+    {+      post_data = Get1Resource( TTAG_POST, res_id++ );+      if ( post_data == NULL )+        break;  /* we are done */++      code = (*post_data)[0];++      if ( code != last_code )+      {+        if ( code == 5 )+          total_size += 2; /* just the end code */+        else+          total_size += 6; /* code + 4 bytes chunk length */+      }++      total_size += GetHandleSize( post_data ) - 2;+      last_code = code;++      /* detect integer overflows */+      if ( total_size < old_total_size )+      {+        error = FT_Err_Array_Too_Large;+        goto Error;+      }++      old_total_size = total_size;+    }++    if ( FT_ALLOC( buffer, (FT_Long)total_size ) )+      goto Error;++    /* Second pass: append all POST data to the buffer, add PFB fields. */+    /* Glue all consecutive chunks of the same type together.           */+    p              = buffer;+    res_id         = 501;+    last_code      = -1;+    pfb_chunk_size = 0;++    for (;;)+    {+      post_data = Get1Resource( TTAG_POST, res_id++ );+      if ( post_data == NULL )+        break;  /* we are done */++      post_size = (FT_ULong)GetHandleSize( post_data ) - 2;+      code = (*post_data)[0];++      if ( code != last_code )+      {+        if ( last_code != -1 )+        {+          /* we are done adding a chunk, fill in the size field */+          if ( size_p != NULL )+          {+            *size_p++ = (FT_Byte)(   pfb_chunk_size         & 0xFF );+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8  ) & 0xFF );+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );+          }+          pfb_chunk_size = 0;+        }++        *p++ = 0x80;+        if ( code == 5 )+          *p++ = 0x03;  /* the end */+        else if ( code == 2 )+          *p++ = 0x02;  /* binary segment */+        else+          *p++ = 0x01;  /* ASCII segment */++        if ( code != 5 )+        {+          size_p = p;   /* save for later */+          p += 4;       /* make space for size field */+        }+      }++      ft_memcpy( p, *post_data + 2, post_size );+      pfb_chunk_size += post_size;+      p += post_size;+      last_code = code;+    }++    *pfb_data = buffer;+    *size = total_size;++  Error:+    CloseResFile( res );+    return error;+  }+++  /* Create a new FT_Face from a file path to an LWFN file. */+  static FT_Error+  FT_New_Face_From_LWFN( FT_Library    library,+                         const UInt8*  pathname,+                         FT_Long       face_index,+                         FT_Face*      aface )+  {+    FT_Byte*       pfb_data;+    FT_ULong       pfb_size;+    FT_Error       error;+    ResFileRefNum  res;+++    if ( noErr != FT_FSPathMakeRes( pathname, &res ) )+      return FT_Err_Cannot_Open_Resource;++    pfb_data = NULL;+    pfb_size = 0;+    error = read_lwfn( library->memory, res, &pfb_data, &pfb_size );+    CloseResFile( res ); /* PFB is already loaded, useless anymore */+    if ( error )+      return error;++    return open_face_from_buffer( library,+                                  pfb_data,+                                  pfb_size,+                                  face_index,+                                  "type1",+                                  aface );+  }+++  /* Create a new FT_Face from an SFNT resource, specified by res ID. */+  static FT_Error+  FT_New_Face_From_SFNT( FT_Library  library,+                         ResID       sfnt_id,+                         FT_Long     face_index,+                         FT_Face*    aface )+  {+    Handle     sfnt = NULL;+    FT_Byte*   sfnt_data;+    size_t     sfnt_size;+    FT_Error   error  = FT_Err_Ok;+    FT_Memory  memory = library->memory;+    int        is_cff, is_sfnt_ps;+++    sfnt = GetResource( TTAG_sfnt, sfnt_id );+    if ( sfnt == NULL )+      return FT_Err_Invalid_Handle;++    sfnt_size = (FT_ULong)GetHandleSize( sfnt );+    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )+    {+      ReleaseResource( sfnt );+      return error;+    }++    ft_memcpy( sfnt_data, *sfnt, sfnt_size );+    ReleaseResource( sfnt );++    is_cff     = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );+    is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 );++    if ( is_sfnt_ps )+    {+      FT_Stream  stream;+++      if ( FT_NEW( stream ) )+        goto Try_OpenType;++      FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );+      if ( !open_face_PS_from_sfnt_stream( library,+                                           stream,+                                           face_index,+                                           0, NULL,+                                           aface ) )+      {+        FT_Stream_Close( stream );+        FT_FREE( stream );+        FT_FREE( sfnt_data );+        goto Exit;+      }++      FT_FREE( stream );+    }+  Try_OpenType:+    error = open_face_from_buffer( library,+                                   sfnt_data,+                                   sfnt_size,+                                   face_index,+                                   is_cff ? "cff" : "truetype",+                                   aface );+  Exit:+    return error;+  }+++  /* Create a new FT_Face from a file path to a suitcase file. */+  static FT_Error+  FT_New_Face_From_Suitcase( FT_Library    library,+                             const UInt8*  pathname,+                             FT_Long       face_index,+                             FT_Face*      aface )+  {+    FT_Error       error = FT_Err_Cannot_Open_Resource;+    ResFileRefNum  res_ref;+    ResourceIndex  res_index;+    Handle         fond;+    short          num_faces_in_res, num_faces_in_fond;+++    if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) )+      return FT_Err_Cannot_Open_Resource;++    UseResFile( res_ref );+    if ( ResError() )+      return FT_Err_Cannot_Open_Resource;++    num_faces_in_res = 0;+    for ( res_index = 1; ; ++res_index )+    {+      fond = Get1IndResource( TTAG_FOND, res_index );+      if ( ResError() )+        break;++      num_faces_in_fond  = count_faces( fond, pathname );+      num_faces_in_res  += num_faces_in_fond;++      if ( 0 <= face_index && face_index < num_faces_in_fond && error )+        error = FT_New_Face_From_FOND( library, fond, face_index, aface );++      face_index -= num_faces_in_fond;+    }++    CloseResFile( res_ref );+    if ( FT_Err_Ok == error && NULL != aface && NULL != *aface )+      (*aface)->num_faces = num_faces_in_res;+    return error;+  }+++  /* documentation is in ftmac.h */++  FT_EXPORT_DEF( FT_Error )+  FT_New_Face_From_FOND( FT_Library  library,+                         Handle      fond,+                         FT_Long     face_index,+                         FT_Face*    aface )+  {+    short     have_sfnt, have_lwfn = 0;+    ResID     sfnt_id, fond_id;+    OSType    fond_type;+    Str255    fond_name;+    Str255    lwfn_file_name;+    UInt8     path_lwfn[PATH_MAX];+    OSErr     err;+    FT_Error  error = FT_Err_Ok;+++    GetResInfo( fond, &fond_id, &fond_type, fond_name );+    if ( ResError() != noErr || fond_type != TTAG_FOND )+      return FT_Err_Invalid_File_Format;++    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );++    if ( lwfn_file_name[0] )+    {+      ResFileRefNum  res;+++      res = HomeResFile( fond );+      if ( noErr != ResError() )+        goto found_no_lwfn_file;++      {+        UInt8  path_fond[PATH_MAX];+        FSRef  ref;+++        err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum,+                               NULL, NULL, NULL, &ref, NULL );+        if ( noErr != err )+          goto found_no_lwfn_file;++        err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) );+        if ( noErr != err )+          goto found_no_lwfn_file;++        error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,+                                     path_lwfn, sizeof ( path_lwfn ) );+        if ( FT_Err_Ok == error )+          have_lwfn = 1;+      }+    }++    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )+      error = FT_New_Face_From_LWFN( library,+                                     path_lwfn,+                                     face_index,+                                     aface );+    else+      error = FT_Err_Unknown_File_Format;++  found_no_lwfn_file:+    if ( have_sfnt && FT_Err_Ok != error )+      error = FT_New_Face_From_SFNT( library,+                                     sfnt_id,+                                     face_index,+                                     aface );++    return error;+  }+++  /* Common function to load a new FT_Face from a resource file. */+  static FT_Error+  FT_New_Face_From_Resource( FT_Library    library,+                             const UInt8*  pathname,+                             FT_Long       face_index,+                             FT_Face*      aface )+  {+    OSType    file_type;+    FT_Error  error;+++    /* LWFN is a (very) specific file format, check for it explicitly */+    file_type = get_file_type_from_path( pathname );+    if ( file_type == TTAG_LWFN )+      return FT_New_Face_From_LWFN( library, pathname, face_index, aface );++    /* Otherwise the file type doesn't matter (there are more than  */+    /* `FFIL' and `tfil').  Just try opening it as a font suitcase; */+    /* if it works, fine.                                           */++    error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface );+    if ( error == 0 )+      return error;++    /* let it fall through to normal loader (.ttf, .otf, etc.); */+    /* we signal this by returning no error and no FT_Face      */+    *aface = NULL;+    return 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This is the Mac-specific implementation of FT_New_Face.  In        */+  /*    addition to the standard FT_New_Face() functionality, it also      */+  /*    accepts pathnames to Mac suitcase files.  For further              */+  /*    documentation see the original FT_New_Face() in freetype.h.        */+  /*                                                                       */+  FT_EXPORT_DEF( FT_Error )+  FT_New_Face( FT_Library   library,+               const char*  pathname,+               FT_Long      face_index,+               FT_Face*     aface )+  {+    FT_Open_Args  args;+    FT_Error      error;+++    /* test for valid `library' and `aface' delayed to FT_Open_Face() */+    if ( !pathname )+      return FT_Err_Invalid_Argument;++    error  = FT_Err_Ok;+    *aface = NULL;++    /* try resourcefork based font: LWFN, FFIL */+    error = FT_New_Face_From_Resource( library, (UInt8 *)pathname,+                                       face_index, aface );+    if ( error != 0 || *aface != NULL )+      return error;++    /* let it fall through to normal loader (.ttf, .otf, etc.) */+    args.flags    = FT_OPEN_PATHNAME;+    args.pathname = (char*)pathname;+    return FT_Open_Face( library, &args, face_index, aface );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face_From_FSRef                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FT_New_Face_From_FSRef is identical to FT_New_Face except it       */+  /*    accepts an FSRef instead of a path.                                */+  /*                                                                       */+  /* This function is deprecated because Carbon data types (FSRef)         */+  /* are not cross-platform, and thus not suitable for the freetype API.   */+  FT_EXPORT_DEF( FT_Error )+  FT_New_Face_From_FSRef( FT_Library    library,+                          const FSRef*  ref,+                          FT_Long       face_index,+                          FT_Face*      aface )+  {+    FT_Error      error;+    FT_Open_Args  args;+    OSErr   err;+    UInt8   pathname[PATH_MAX];+++    if ( !ref )+      return FT_Err_Invalid_Argument;++    err = FSRefMakePath( ref, pathname, sizeof ( pathname ) );+    if ( err )+      error = FT_Err_Cannot_Open_Resource;++    error = FT_New_Face_From_Resource( library, pathname, face_index, aface );+    if ( error != 0 || *aface != NULL )+      return error;++    /* fallback to datafork font */+    args.flags    = FT_OPEN_PATHNAME;+    args.pathname = (char*)pathname;+    return FT_Open_Face( library, &args, face_index, aface );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_New_Face_From_FSSpec                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    FT_New_Face_From_FSSpec is identical to FT_New_Face except it      */+  /*    accepts an FSSpec instead of a path.                               */+  /*                                                                       */+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */+  FT_EXPORT_DEF( FT_Error )+  FT_New_Face_From_FSSpec( FT_Library     library,+                           const FSSpec*  spec,+                           FT_Long        face_index,+                           FT_Face*       aface )+  {+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )+    FT_UNUSED( library );+    FT_UNUSED( spec );+    FT_UNUSED( face_index );+    FT_UNUSED( aface );++    return FT_Err_Unimplemented_Feature;+#else+    FSRef  ref;+++    if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr )+      return FT_Err_Invalid_Argument;+    else+      return FT_New_Face_From_FSRef( library, &ref, face_index, aface );+#endif+  }+++/* END */
+ src/base/ftmm.c view
@@ -0,0 +1,202 @@+/***************************************************************************/+/*                                                                         */+/*  ftmm.c                                                                 */+/*                                                                         */+/*    Multiple Master font support (body).                                 */+/*                                                                         */+/*  Copyright 1996-2001, 2003, 2004, 2009 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_MULTIPLE_MASTERS_H+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_MULTIPLE_MASTERS_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_mm+++  static FT_Error+  ft_face_get_mm_service( FT_Face                   face,+                          FT_Service_MultiMasters  *aservice )+  {+    FT_Error  error;+++    *aservice = NULL;++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    error = FT_Err_Invalid_Argument;++    if ( FT_HAS_MULTIPLE_MASTERS( face ) )+    {+      FT_FACE_LOOKUP_SERVICE( face,+                              *aservice,+                              MULTI_MASTERS );++      if ( *aservice )+        error = FT_Err_Ok;+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Multi_Master( FT_Face           face,+                       FT_Multi_Master  *amaster )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->get_mm )+        error = service->get_mm( face, amaster );+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_MM_Var( FT_Face      face,+                 FT_MM_Var*  *amaster )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->get_mm_var )+        error = service->get_mm_var( face, amaster );+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_MM_Design_Coordinates( FT_Face   face,+                                FT_UInt   num_coords,+                                FT_Long*  coords )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->set_mm_design )+        error = service->set_mm_design( face, num_coords, coords );+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Var_Design_Coordinates( FT_Face    face,+                                 FT_UInt    num_coords,+                                 FT_Fixed*  coords )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->set_var_design )+        error = service->set_var_design( face, num_coords, coords );+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_MM_Blend_Coordinates( FT_Face    face,+                               FT_UInt    num_coords,+                               FT_Fixed*  coords )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->set_mm_blend )+         error = service->set_mm_blend( face, num_coords, coords );+    }++    return error;+  }+++  /* documentation is in ftmm.h */++  /* This is exactly the same as the previous function.  It exists for */+  /* orthogonality.                                                    */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Var_Blend_Coordinates( FT_Face    face,+                                FT_UInt    num_coords,+                                FT_Fixed*  coords )+  {+    FT_Error                 error;+    FT_Service_MultiMasters  service;+++    error = ft_face_get_mm_service( face, &service );+    if ( !error )+    {+      error = FT_Err_Invalid_Argument;+      if ( service->set_mm_blend )+         error = service->set_mm_blend( face, num_coords, coords );+    }++    return error;+  }+++/* END */
+ src/base/ftobjs.c view
@@ -0,0 +1,4664 @@+/***************************************************************************/+/*                                                                         */+/*  ftobjs.c                                                               */+/*                                                                         */+/*    The FreeType private base classes (body).                            */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_LIST_H+#include FT_OUTLINE_H+#include FT_INTERNAL_VALIDATE_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_RFORK_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H    /* for SFNT_Load_Table_Func */+#include FT_TRUETYPE_TABLES_H+#include FT_TRUETYPE_TAGS_H+#include FT_TRUETYPE_IDS_H++#include FT_SERVICE_SFNT_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_GLYPH_DICT_H+#include FT_SERVICE_TT_CMAP_H+#include FT_SERVICE_KERNING_H+#include FT_SERVICE_TRUETYPE_ENGINE_H++#ifdef FT_CONFIG_OPTION_MAC_FONTS+#include "ftbase.h"+#endif++#define GRID_FIT_METRICS+++  FT_BASE_DEF( FT_Pointer )+  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,+                          const char*     service_id )+  {+    FT_Pointer      result = NULL;+    FT_ServiceDesc  desc   = service_descriptors;+++    if ( desc && service_id )+    {+      for ( ; desc->serv_id != NULL; desc++ )+      {+        if ( ft_strcmp( desc->serv_id, service_id ) == 0 )+        {+          result = (FT_Pointer)desc->serv_data;+          break;+        }+      }+    }++    return result;+  }+++  FT_BASE_DEF( void )+  ft_validator_init( FT_Validator        valid,+                     const FT_Byte*      base,+                     const FT_Byte*      limit,+                     FT_ValidationLevel  level )+  {+    valid->base  = base;+    valid->limit = limit;+    valid->level = level;+    valid->error = FT_Err_Ok;+  }+++  FT_BASE_DEF( FT_Int )+  ft_validator_run( FT_Validator  valid )+  {+    /* This function doesn't work!  None should call it. */+    FT_UNUSED( valid );++    return -1;+  }+++  FT_BASE_DEF( void )+  ft_validator_error( FT_Validator  valid,+                      FT_Error      error )+  {+    /* since the cast below also disables the compiler's */+    /* type check, we introduce a dummy variable, which  */+    /* will be optimized away                            */+    volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;+++    valid->error = error;++    /* throw away volatileness; use `jump_buffer' or the  */+    /* compiler may warn about an unused local variable   */+    ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                           S T R E A M                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* create a new input stream from an FT_Open_Args structure */+  /*                                                          */+  FT_BASE_DEF( FT_Error )+  FT_Stream_New( FT_Library           library,+                 const FT_Open_Args*  args,+                 FT_Stream           *astream )+  {+    FT_Error   error;+    FT_Memory  memory;+    FT_Stream  stream;+++    *astream = 0;++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !args )+      return FT_Err_Invalid_Argument;++    memory = library->memory;++    if ( FT_NEW( stream ) )+      goto Exit;++    stream->memory = memory;++    if ( args->flags & FT_OPEN_MEMORY )+    {+      /* create a memory-based stream */+      FT_Stream_OpenMemory( stream,+                            (const FT_Byte*)args->memory_base,+                            args->memory_size );+    }+    else if ( args->flags & FT_OPEN_PATHNAME )+    {+      /* create a normal system stream */+      error = FT_Stream_Open( stream, args->pathname );+      stream->pathname.pointer = args->pathname;+    }+    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )+    {+      /* use an existing, user-provided stream */++      /* in this case, we do not need to allocate a new stream object */+      /* since the caller is responsible for closing it himself       */+      FT_FREE( stream );+      stream = args->stream;+    }+    else+      error = FT_Err_Invalid_Argument;++    if ( error )+      FT_FREE( stream );+    else+      stream->memory = memory;  /* just to be certain */++    *astream = stream;++  Exit:+    return error;+  }+++  FT_BASE_DEF( void )+  FT_Stream_Free( FT_Stream  stream,+                  FT_Int     external )+  {+    if ( stream )+    {+      FT_Memory  memory = stream->memory;+++      FT_Stream_Close( stream );++      if ( !external )+        FT_FREE( stream );+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_objs+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  static FT_Error+  ft_glyphslot_init( FT_GlyphSlot  slot )+  {+    FT_Driver         driver   = slot->face->driver;+    FT_Driver_Class   clazz    = driver->clazz;+    FT_Memory         memory   = driver->root.memory;+    FT_Error          error    = FT_Err_Ok;+    FT_Slot_Internal  internal = NULL;+++    slot->library = driver->root.library;++    if ( FT_NEW( internal ) )+      goto Exit;++    slot->internal = internal;++    if ( FT_DRIVER_USES_OUTLINES( driver ) )+      error = FT_GlyphLoader_New( memory, &internal->loader );++    if ( !error && clazz->init_slot )+      error = clazz->init_slot( slot );++  Exit:+    return error;+  }+++  FT_BASE_DEF( void )+  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot )+  {+    if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )+    {+      FT_Memory  memory = FT_FACE_MEMORY( slot->face );+++      FT_FREE( slot->bitmap.buffer );+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;+    }+    else+    {+      /* assume that the bitmap buffer was stolen or not */+      /* allocated from the heap                         */+      slot->bitmap.buffer = NULL;+    }+  }+++  FT_BASE_DEF( void )+  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,+                           FT_Byte*      buffer )+  {+    ft_glyphslot_free_bitmap( slot );++    slot->bitmap.buffer = buffer;++    FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );+  }+++  FT_BASE_DEF( FT_Error )+  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,+                             FT_ULong      size )+  {+    FT_Memory  memory = FT_FACE_MEMORY( slot->face );+    FT_Error   error;+++    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )+      FT_FREE( slot->bitmap.buffer );+    else+      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;++    (void)FT_ALLOC( slot->bitmap.buffer, size );+    return error;+  }+++  static void+  ft_glyphslot_clear( FT_GlyphSlot  slot )+  {+    /* free bitmap if needed */+    ft_glyphslot_free_bitmap( slot );++    /* clear all public fields in the glyph slot */+    FT_ZERO( &slot->metrics );+    FT_ZERO( &slot->outline );++    slot->bitmap.width      = 0;+    slot->bitmap.rows       = 0;+    slot->bitmap.pitch      = 0;+    slot->bitmap.pixel_mode = 0;+    /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */++    slot->bitmap_left   = 0;+    slot->bitmap_top    = 0;+    slot->num_subglyphs = 0;+    slot->subglyphs     = 0;+    slot->control_data  = 0;+    slot->control_len   = 0;+    slot->other         = 0;+    slot->format        = FT_GLYPH_FORMAT_NONE;++    slot->linearHoriAdvance = 0;+    slot->linearVertAdvance = 0;+    slot->lsb_delta         = 0;+    slot->rsb_delta         = 0;+  }+++  static void+  ft_glyphslot_done( FT_GlyphSlot  slot )+  {+    FT_Driver        driver = slot->face->driver;+    FT_Driver_Class  clazz  = driver->clazz;+    FT_Memory        memory = driver->root.memory;+++    if ( clazz->done_slot )+      clazz->done_slot( slot );++    /* free bitmap buffer if needed */+    ft_glyphslot_free_bitmap( slot );++    /* slot->internal might be NULL in out-of-memory situations */+    if ( slot->internal )+    {+      /* free glyph loader */+      if ( FT_DRIVER_USES_OUTLINES( driver ) )+      {+        FT_GlyphLoader_Done( slot->internal->loader );+        slot->internal->loader = 0;+      }++      FT_FREE( slot->internal );+    }+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( FT_Error )+  FT_New_GlyphSlot( FT_Face        face,+                    FT_GlyphSlot  *aslot )+  {+    FT_Error         error;+    FT_Driver        driver;+    FT_Driver_Class  clazz;+    FT_Memory        memory;+    FT_GlyphSlot     slot;+++    if ( !face || !face->driver )+      return FT_Err_Invalid_Argument;++    driver = face->driver;+    clazz  = driver->clazz;+    memory = driver->root.memory;++    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));+    if ( !FT_ALLOC( slot, clazz->slot_object_size ) )+    {+      slot->face = face;++      error = ft_glyphslot_init( slot );+      if ( error )+      {+        ft_glyphslot_done( slot );+        FT_FREE( slot );+        goto Exit;+      }++      slot->next  = face->glyph;+      face->glyph = slot;++      if ( aslot )+        *aslot = slot;+    }+    else if ( aslot )+      *aslot = 0;+++  Exit:+    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));+    return error;+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( void )+  FT_Done_GlyphSlot( FT_GlyphSlot  slot )+  {+    if ( slot )+    {+      FT_Driver     driver = slot->face->driver;+      FT_Memory     memory = driver->root.memory;+      FT_GlyphSlot  prev;+      FT_GlyphSlot  cur;+++      /* Remove slot from its parent face's list */+      prev = NULL;+      cur  = slot->face->glyph;++      while ( cur )+      {+        if ( cur == slot )+        {+          if ( !prev )+            slot->face->glyph = cur->next;+          else+            prev->next = cur->next;++          ft_glyphslot_done( slot );+          FT_FREE( slot );+          break;+        }+        prev = cur;+        cur  = cur->next;+      }+    }+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( void )+  FT_Set_Transform( FT_Face     face,+                    FT_Matrix*  matrix,+                    FT_Vector*  delta )+  {+    FT_Face_Internal  internal;+++    if ( !face )+      return;++    internal = face->internal;++    internal->transform_flags = 0;++    if ( !matrix )+    {+      internal->transform_matrix.xx = 0x10000L;+      internal->transform_matrix.xy = 0;+      internal->transform_matrix.yx = 0;+      internal->transform_matrix.yy = 0x10000L;+      matrix = &internal->transform_matrix;+    }+    else+      internal->transform_matrix = *matrix;++    /* set transform_flags bit flag 0 if `matrix' isn't the identity */+    if ( ( matrix->xy | matrix->yx ) ||+         matrix->xx != 0x10000L      ||+         matrix->yy != 0x10000L      )+      internal->transform_flags |= 1;++    if ( !delta )+    {+      internal->transform_delta.x = 0;+      internal->transform_delta.y = 0;+      delta = &internal->transform_delta;+    }+    else+      internal->transform_delta = *delta;++    /* set transform_flags bit flag 1 if `delta' isn't the null vector */+    if ( delta->x | delta->y )+      internal->transform_flags |= 2;+  }+++  static FT_Renderer+  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );+++#ifdef GRID_FIT_METRICS+  static void+  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot,+                                 FT_Bool       vertical )+  {+    FT_Glyph_Metrics*  metrics = &slot->metrics;+    FT_Pos             right, bottom;+++    if ( vertical )+    {+      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );+      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );++      right  = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );+      bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );++      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );+      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );++      metrics->width  = right - metrics->vertBearingX;+      metrics->height = bottom - metrics->vertBearingY;+    }+    else+    {+      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );+      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );++      right  = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );+      bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );++      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );+      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );++      metrics->width  = right - metrics->horiBearingX;+      metrics->height = metrics->horiBearingY - bottom;+    }++    metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );+    metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );+  }+#endif /* GRID_FIT_METRICS */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Load_Glyph( FT_Face   face,+                 FT_UInt   glyph_index,+                 FT_Int32  load_flags )+  {+    FT_Error      error;+    FT_Driver     driver;+    FT_GlyphSlot  slot;+    FT_Library    library;+    FT_Bool       autohint = FALSE;+    FT_Module     hinter;+++    if ( !face || !face->size || !face->glyph )+      return FT_Err_Invalid_Face_Handle;++    /* The validity test for `glyph_index' is performed by the */+    /* font drivers.                                           */++    slot = face->glyph;+    ft_glyphslot_clear( slot );++    driver  = face->driver;+    library = driver->root.library;+    hinter  = library->auto_hinter;++    /* resolve load flags dependencies */++    if ( load_flags & FT_LOAD_NO_RECURSE )+      load_flags |= FT_LOAD_NO_SCALE         |+                    FT_LOAD_IGNORE_TRANSFORM;++    if ( load_flags & FT_LOAD_NO_SCALE )+    {+      load_flags |= FT_LOAD_NO_HINTING |+                    FT_LOAD_NO_BITMAP;++      load_flags &= ~FT_LOAD_RENDER;+    }++    /*+     * Determine whether we need to auto-hint or not.+     * The general rules are:+     *+     * - Do only auto-hinting if we have a hinter module, a scalable font+     *   format dealing with outlines, and no transforms except simple+     *   slants and/or rotations by integer multiples of 90 degrees.+     *+     * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't+     *   have a native font hinter.+     *+     * - Otherwise, auto-hint for LIGHT hinting mode.+     *+     * - Exception: The font is `tricky' and requires the native hinter to+     *   load properly.+     */++    if ( hinter                                           &&+         !( load_flags & FT_LOAD_NO_HINTING )             &&+         !( load_flags & FT_LOAD_NO_AUTOHINT )            &&+         FT_DRIVER_IS_SCALABLE( driver )                  &&+         FT_DRIVER_USES_OUTLINES( driver )                &&+         !FT_IS_TRICKY( face )                            &&+         ( ( face->internal->transform_matrix.yx == 0 &&+             face->internal->transform_matrix.xx != 0 ) ||+           ( face->internal->transform_matrix.xx == 0 &&+             face->internal->transform_matrix.yx != 0 ) ) )+    {+      if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||+           !FT_DRIVER_HAS_HINTER( driver )         )+        autohint = TRUE;+      else+      {+        FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );+++        if ( mode == FT_RENDER_MODE_LIGHT             ||+             face->internal->ignore_unpatented_hinter )+          autohint = TRUE;+      }+    }++    if ( autohint )+    {+      FT_AutoHinter_Service  hinting;+++      /* try to load embedded bitmaps first if available            */+      /*                                                            */+      /* XXX: This is really a temporary hack that should disappear */+      /*      promptly with FreeType 2.1!                           */+      /*                                                            */+      if ( FT_HAS_FIXED_SIZES( face )             &&+          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )+      {+        error = driver->clazz->load_glyph( slot, face->size,+                                           glyph_index,+                                           load_flags | FT_LOAD_SBITS_ONLY );++        if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )+          goto Load_Ok;+      }++      {+        FT_Face_Internal  internal        = face->internal;+        FT_Int            transform_flags = internal->transform_flags;+++        /* since the auto-hinter calls FT_Load_Glyph by itself, */+        /* make sure that glyphs aren't transformed             */+        internal->transform_flags = 0;++        /* load auto-hinted outline */+        hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;++        error   = hinting->load_glyph( (FT_AutoHinter)hinter,+                                       slot, face->size,+                                       glyph_index, load_flags );++        internal->transform_flags = transform_flags;+      }+    }+    else+    {+      error = driver->clazz->load_glyph( slot,+                                         face->size,+                                         glyph_index,+                                         load_flags );+      if ( error )+        goto Exit;++      if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )+      {+        /* check that the loaded outline is correct */+        error = FT_Outline_Check( &slot->outline );+        if ( error )+          goto Exit;++#ifdef GRID_FIT_METRICS+        if ( !( load_flags & FT_LOAD_NO_HINTING ) )+          ft_glyphslot_grid_fit_metrics( slot,+              FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );+#endif+      }+    }++  Load_Ok:+    /* compute the advance */+    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )+    {+      slot->advance.x = 0;+      slot->advance.y = slot->metrics.vertAdvance;+    }+    else+    {+      slot->advance.x = slot->metrics.horiAdvance;+      slot->advance.y = 0;+    }++    /* compute the linear advance in 16.16 pixels */+    if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&+         ( FT_IS_SCALABLE( face ) )                  )+    {+      FT_Size_Metrics*  metrics = &face->size->metrics;+++      /* it's tricky! */+      slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,+                                           metrics->x_scale, 64 );++      slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,+                                           metrics->y_scale, 64 );+    }++    if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )+    {+      FT_Face_Internal  internal = face->internal;+++      /* now, transform the glyph image if needed */+      if ( internal->transform_flags )+      {+        /* get renderer */+        FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );+++        if ( renderer )+          error = renderer->clazz->transform_glyph(+                                     renderer, slot,+                                     &internal->transform_matrix,+                                     &internal->transform_delta );+        else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )+        {+          /* apply `standard' transformation if no renderer is available */+          if ( &internal->transform_matrix )+            FT_Outline_Transform( &slot->outline,+                                  &internal->transform_matrix );++          if ( &internal->transform_delta )+            FT_Outline_Translate( &slot->outline,+                                  internal->transform_delta.x,+                                  internal->transform_delta.y );+        }++        /* transform advance */+        FT_Vector_Transform( &slot->advance, &internal->transform_matrix );+      }+    }++    FT_TRACE5(( "  x advance: %d\n" , slot->advance.x ));+    FT_TRACE5(( "  y advance: %d\n" , slot->advance.y ));++    FT_TRACE5(( "  linear x advance: %d\n" , slot->linearHoriAdvance ));+    FT_TRACE5(( "  linear y advance: %d\n" , slot->linearVertAdvance ));++    /* do we need to render the image now? */+    if ( !error                                    &&+         slot->format != FT_GLYPH_FORMAT_BITMAP    &&+         slot->format != FT_GLYPH_FORMAT_COMPOSITE &&+         load_flags & FT_LOAD_RENDER )+    {+      FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );+++      if ( mode == FT_RENDER_MODE_NORMAL      &&+           (load_flags & FT_LOAD_MONOCHROME ) )+        mode = FT_RENDER_MODE_MONO;++      error = FT_Render_Glyph( slot, mode );+    }++  Exit:+    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Load_Char( FT_Face   face,+                FT_ULong  char_code,+                FT_Int32  load_flags )+  {+    FT_UInt  glyph_index;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    glyph_index = (FT_UInt)char_code;+    if ( face->charmap )+      glyph_index = FT_Get_Char_Index( face, char_code );++    return FT_Load_Glyph( face, glyph_index, load_flags );+  }+++  /* destructor for sizes list */+  static void+  destroy_size( FT_Memory  memory,+                FT_Size    size,+                FT_Driver  driver )+  {+    /* finalize client-specific data */+    if ( size->generic.finalizer )+      size->generic.finalizer( size );++    /* finalize format-specific stuff */+    if ( driver->clazz->done_size )+      driver->clazz->done_size( size );++    FT_FREE( size->internal );+    FT_FREE( size );+  }+++  static void+  ft_cmap_done_internal( FT_CMap  cmap );+++  static void+  destroy_charmaps( FT_Face    face,+                    FT_Memory  memory )+  {+    FT_Int  n;+++    if ( !face )+      return;++    for ( n = 0; n < face->num_charmaps; n++ )+    {+      FT_CMap  cmap = FT_CMAP( face->charmaps[n] );+++      ft_cmap_done_internal( cmap );++      face->charmaps[n] = NULL;+    }++    FT_FREE( face->charmaps );+    face->num_charmaps = 0;+  }+++  /* destructor for faces list */+  static void+  destroy_face( FT_Memory  memory,+                FT_Face    face,+                FT_Driver  driver )+  {+    FT_Driver_Class  clazz = driver->clazz;+++    /* discard auto-hinting data */+    if ( face->autohint.finalizer )+      face->autohint.finalizer( face->autohint.data );++    /* Discard glyph slots for this face.                           */+    /* Beware!  FT_Done_GlyphSlot() changes the field `face->glyph' */+    while ( face->glyph )+      FT_Done_GlyphSlot( face->glyph );++    /* discard all sizes for this face */+    FT_List_Finalize( &face->sizes_list,+                      (FT_List_Destructor)destroy_size,+                      memory,+                      driver );+    face->size = 0;++    /* now discard client data */+    if ( face->generic.finalizer )+      face->generic.finalizer( face );++    /* discard charmaps */+    destroy_charmaps( face, memory );++    /* finalize format-specific stuff */+    if ( clazz->done_face )+      clazz->done_face( face );++    /* close the stream for this face if needed */+    FT_Stream_Free(+      face->stream,+      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );++    face->stream = 0;++    /* get rid of it */+    if ( face->internal )+    {+      FT_FREE( face->internal );+    }+    FT_FREE( face );+  }+++  static void+  Destroy_Driver( FT_Driver  driver )+  {+    FT_List_Finalize( &driver->faces_list,+                      (FT_List_Destructor)destroy_face,+                      driver->root.memory,+                      driver );++    /* check whether we need to drop the driver's glyph loader */+    if ( FT_DRIVER_USES_OUTLINES( driver ) )+      FT_GlyphLoader_Done( driver->glyph_loader );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    find_unicode_charmap                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function finds a Unicode charmap, if there is one.            */+  /*    And if there is more than one, it tries to favour the more         */+  /*    extensive one, i.e., one that supports UCS-4 against those which   */+  /*    are limited to the BMP (said UCS-2 encoding.)                      */+  /*                                                                       */+  /*    This function is called from open_face() (just below), and also    */+  /*    from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).                */+  /*                                                                       */+  static FT_Error+  find_unicode_charmap( FT_Face  face )+  {+    FT_CharMap*  first;+    FT_CharMap*  cur;+++    /* caller should have already checked that `face' is valid */+    FT_ASSERT( face );++    first = face->charmaps;++    if ( !first )+      return FT_Err_Invalid_CharMap_Handle;++    /*+     *  The original TrueType specification(s) only specified charmap+     *  formats that are capable of mapping 8 or 16 bit character codes to+     *  glyph indices.+     *+     *  However, recent updates to the Apple and OpenType specifications+     *  introduced new formats that are capable of mapping 32-bit character+     *  codes as well.  And these are already used on some fonts, mainly to+     *  map non-BMP Asian ideographs as defined in Unicode.+     *+     *  For compatibility purposes, these fonts generally come with+     *  *several* Unicode charmaps:+     *+     *   - One of them in the "old" 16-bit format, that cannot access+     *     all glyphs in the font.+     *+     *   - Another one in the "new" 32-bit format, that can access all+     *     the glyphs.+     *+     *  This function has been written to always favor a 32-bit charmap+     *  when found.  Otherwise, a 16-bit one is returned when found.+     */++    /* Since the `interesting' table, with IDs (3,10), is normally the */+    /* last one, we loop backwards.  This loses with type1 fonts with  */+    /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP  */+    /* chars (.01% ?), and this is the same about 99.99% of the time!  */++    cur = first + face->num_charmaps;  /* points after the last one */++    for ( ; --cur >= first; )+    {+      if ( cur[0]->encoding == FT_ENCODING_UNICODE )+      {+        /* XXX If some new encodings to represent UCS-4 are added, */+        /*     they should be added here.                          */+        if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&+               cur[0]->encoding_id == TT_MS_ID_UCS_4        )     ||+             ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&+               cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32    ) )+        {+#ifdef FT_MAX_CHARMAP_CACHEABLE+          if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )+          {+            FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "+                       "at too late position (%d)\n", cur - first ));+            continue;+          }+#endif+          face->charmap = cur[0];+          return FT_Err_Ok;+        }+      }+    }++    /* We do not have any UCS-4 charmap.                */+    /* Do the loop again and search for UCS-2 charmaps. */+    cur = first + face->num_charmaps;++    for ( ; --cur >= first; )+    {+      if ( cur[0]->encoding == FT_ENCODING_UNICODE )+      {+#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "+                     "at too late position (%d)\n", cur - first ));+          continue;+        }+#endif+        face->charmap = cur[0];+        return FT_Err_Ok;+      }+    }++    return FT_Err_Invalid_CharMap_Handle;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    find_variant_selector_charmap                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function finds the variant selector charmap, if there is one. */+  /*    There can only be one (platform=0, specific=5, format=14).         */+  /*                                                                       */+  static FT_CharMap+  find_variant_selector_charmap( FT_Face  face )+  {+    FT_CharMap*  first;+    FT_CharMap*  end;+    FT_CharMap*  cur;+++    /* caller should have already checked that `face' is valid */+    FT_ASSERT( face );++    first = face->charmaps;++    if ( !first )+      return NULL;++    end = first + face->num_charmaps;  /* points after the last one */++    for ( cur = first; cur < end; ++cur )+    {+      if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&+           cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&+           FT_Get_CMap_Format( cur[0] ) == 14                  )+      {+#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "find_unicode_charmap: UVS cmap is found "+                     "at too late position (%d)\n", cur - first ));+          continue;+        }+#endif+        return cur[0];+      }+    }++    return NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    open_face                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function does some work for FT_Open_Face().                   */+  /*                                                                       */+  static FT_Error+  open_face( FT_Driver      driver,+             FT_Stream      stream,+             FT_Long        face_index,+             FT_Int         num_params,+             FT_Parameter*  params,+             FT_Face       *aface )+  {+    FT_Memory         memory;+    FT_Driver_Class   clazz;+    FT_Face           face = 0;+    FT_Error          error, error2;+    FT_Face_Internal  internal = NULL;+++    clazz  = driver->clazz;+    memory = driver->root.memory;++    /* allocate the face object and perform basic initialization */+    if ( FT_ALLOC( face, clazz->face_object_size ) )+      goto Fail;++    if ( FT_NEW( internal ) )+      goto Fail;++    face->internal = internal;++    face->driver   = driver;+    face->memory   = memory;+    face->stream   = stream;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    {+      int  i;+++      face->internal->incremental_interface = 0;+      for ( i = 0; i < num_params && !face->internal->incremental_interface;+            i++ )+        if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )+          face->internal->incremental_interface =+            (FT_Incremental_Interface)params[i].data;+    }+#endif++    if ( clazz->init_face )+      error = clazz->init_face( stream,+                                face,+                                (FT_Int)face_index,+                                num_params,+                                params );+    if ( error )+      goto Fail;++    /* select Unicode charmap by default */+    error2 = find_unicode_charmap( face );++    /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */+    /* is returned.                                                      */++    /* no error should happen, but we want to play safe */+    if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )+    {+      error = error2;+      goto Fail;+    }++    *aface = face;++  Fail:+    if ( error )+    {+      destroy_charmaps( face, memory );+      if ( clazz->done_face )+        clazz->done_face( face );+      FT_FREE( internal );+      FT_FREE( face );+      *aface = 0;+    }++    return error;+  }+++  /* there's a Mac-specific extended implementation of FT_New_Face() */+  /* in src/base/ftmac.c                                             */++#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_New_Face( FT_Library   library,+               const char*  pathname,+               FT_Long      face_index,+               FT_Face     *aface )+  {+    FT_Open_Args  args;+++    /* test for valid `library' and `aface' delayed to FT_Open_Face() */+    if ( !pathname )+      return FT_Err_Invalid_Argument;++    args.flags    = FT_OPEN_PATHNAME;+    args.pathname = (char*)pathname;+    args.stream   = NULL;++    return FT_Open_Face( library, &args, face_index, aface );+  }++#endif  /* defined( FT_MACINTOSH ) && !defined( DARWIN_NO_CARBON ) */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_New_Memory_Face( FT_Library      library,+                      const FT_Byte*  file_base,+                      FT_Long         file_size,+                      FT_Long         face_index,+                      FT_Face        *aface )+  {+    FT_Open_Args  args;+++    /* test for valid `library' and `face' delayed to FT_Open_Face() */+    if ( !file_base )+      return FT_Err_Invalid_Argument;++    args.flags       = FT_OPEN_MEMORY;+    args.memory_base = file_base;+    args.memory_size = file_size;+    args.stream      = NULL;++    return FT_Open_Face( library, &args, face_index, aface );+  }+++#ifdef FT_CONFIG_OPTION_MAC_FONTS++  /* The behavior here is very similar to that in base/ftmac.c, but it     */+  /* is designed to work on non-mac systems, so no mac specific calls.     */+  /*                                                                       */+  /* We look at the file and determine if it is a mac dfont file or a mac  */+  /* resource file, or a macbinary file containing a mac resource file.    */+  /*                                                                       */+  /* Unlike ftmac I'm not going to look at a `FOND'.  I don't really see   */+  /* the point, especially since there may be multiple `FOND' resources.   */+  /* Instead I'll just look for `sfnt' and `POST' resources, ordered as    */+  /* they occur in the file.                                               */+  /*                                                                       */+  /* Note that multiple `POST' resources do not mean multiple postscript   */+  /* fonts; they all get jammed together to make what is essentially a     */+  /* pfb file.                                                             */+  /*                                                                       */+  /* We aren't interested in `NFNT' or `FONT' bitmap resources.            */+  /*                                                                       */+  /* As soon as we get an `sfnt' load it into memory and pass it off to    */+  /* FT_Open_Face.                                                         */+  /*                                                                       */+  /* If we have a (set of) `POST' resources, massage them into a (memory)  */+  /* pfb file and pass that to FT_Open_Face.  (As with ftmac.c I'm not     */+  /* going to try to save the kerning info.  After all that lives in the   */+  /* `FOND' which isn't in the file containing the `POST' resources so     */+  /* we don't really have access to it.                                    */+++  /* Finalizer for a memory stream; gets called by FT_Done_Face(). */+  /* It frees the memory it uses.                                  */+  /* From ftmac.c.                                                 */+  static void+  memory_stream_close( FT_Stream  stream )+  {+    FT_Memory  memory = stream->memory;+++    FT_FREE( stream->base );++    stream->size  = 0;+    stream->base  = 0;+    stream->close = 0;+  }+++  /* Create a new memory stream from a buffer and a size. */+  /* From ftmac.c.                                        */+  static FT_Error+  new_memory_stream( FT_Library           library,+                     FT_Byte*             base,+                     FT_ULong             size,+                     FT_Stream_CloseFunc  close,+                     FT_Stream           *astream )+  {+    FT_Error   error;+    FT_Memory  memory;+    FT_Stream  stream;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !base )+      return FT_Err_Invalid_Argument;++    *astream = 0;+    memory = library->memory;+    if ( FT_NEW( stream ) )+      goto Exit;++    FT_Stream_OpenMemory( stream, base, size );++    stream->close = close;++    *astream = stream;++  Exit:+    return error;+  }+++  /* Create a new FT_Face given a buffer and a driver name. */+  /* from ftmac.c */+  FT_LOCAL_DEF( FT_Error )+  open_face_from_buffer( FT_Library   library,+                         FT_Byte*     base,+                         FT_ULong     size,+                         FT_Long      face_index,+                         const char*  driver_name,+                         FT_Face     *aface )+  {+    FT_Open_Args  args;+    FT_Error      error;+    FT_Stream     stream = NULL;+    FT_Memory     memory = library->memory;+++    error = new_memory_stream( library,+                               base,+                               size,+                               memory_stream_close,+                               &stream );+    if ( error )+    {+      FT_FREE( base );+      return error;+    }++    args.flags = FT_OPEN_STREAM;+    args.stream = stream;+    if ( driver_name )+    {+      args.flags = args.flags | FT_OPEN_DRIVER;+      args.driver = FT_Get_Module( library, driver_name );+    }++#ifdef FT_MACINTOSH+    /* At this point, face_index has served its purpose;      */+    /* whoever calls this function has already used it to     */+    /* locate the correct font data.  We should not propagate */+    /* this index to FT_Open_Face() (unless it is negative).  */++    if ( face_index > 0 )+      face_index = 0;+#endif++    error = FT_Open_Face( library, &args, face_index, aface );++    if ( error == FT_Err_Ok )+      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;+    else+#ifdef FT_MACINTOSH+      FT_Stream_Free( stream, 0 );+#else+    {+      FT_Stream_Close( stream );+      FT_FREE( stream );+    }+#endif++    return error;+  }+++  /* Look up `TYP1' or `CID ' table from sfnt table directory.       */+  /* `offset' and `length' must exclude the binary header in tables. */++  /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */+  /* format too.  Here, since we can't expect that the TrueType font */+  /* driver is loaded unconditially, we must parse the font by       */+  /* ourselves.  We are only interested in the name of the table and */+  /* the offset.                                                     */++  static FT_Error+  ft_lookup_PS_in_sfnt_stream( FT_Stream  stream,+                               FT_Long    face_index,+                               FT_ULong*  offset,+                               FT_ULong*  length,+                               FT_Bool*   is_sfnt_cid )+  {+    FT_Error   error;+    FT_UShort  numTables;+    FT_Long    pstable_index;+    FT_ULong   tag;+    int        i;+++    *offset = 0;+    *length = 0;+    *is_sfnt_cid = FALSE;++    /* TODO: support for sfnt-wrapped PS/CID in TTC format */++    /* version check for 'typ1' (should be ignored?) */+    if ( FT_READ_ULONG( tag ) )+      return error;+    if ( tag != TTAG_typ1 )+      return FT_Err_Unknown_File_Format;++    if ( FT_READ_USHORT( numTables ) )+      return error;+    if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */+      return error;++    pstable_index = -1;+    *is_sfnt_cid  = FALSE;++    for ( i = 0; i < numTables; i++ )+    {+      if ( FT_READ_ULONG( tag )     || FT_STREAM_SKIP( 4 )      ||+           FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )+        return error;++      if ( tag == TTAG_CID )+      {+        pstable_index++;+        *offset += 22;+        *length -= 22;+        *is_sfnt_cid = TRUE;+        if ( face_index < 0 )+          return FT_Err_Ok;+      }+      else if ( tag == TTAG_TYP1 )+      {+        pstable_index++;+        *offset += 24;+        *length -= 24;+        *is_sfnt_cid = FALSE;+        if ( face_index < 0 )+          return FT_Err_Ok;+      }+      if ( face_index >= 0 && pstable_index == face_index )+        return FT_Err_Ok;+    }+    return FT_Err_Table_Missing;+  }+++  FT_LOCAL_DEF( FT_Error )+  open_face_PS_from_sfnt_stream( FT_Library     library,+                                 FT_Stream      stream,+                                 FT_Long        face_index,+                                 FT_Int         num_params,+                                 FT_Parameter  *params,+                                 FT_Face       *aface )+  {+    FT_Error   error;+    FT_Memory  memory = library->memory;+    FT_ULong   offset, length;+    FT_Long    pos;+    FT_Bool    is_sfnt_cid;+    FT_Byte*   sfnt_ps;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+++    pos = FT_Stream_Pos( stream );++    error = ft_lookup_PS_in_sfnt_stream( stream,+                                         face_index,+                                         &offset,+                                         &length,+                                         &is_sfnt_cid );+    if ( error )+      goto Exit;++    if ( FT_Stream_Seek( stream, pos + offset ) )+      goto Exit;++    if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )+      goto Exit;++    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );+    if ( error )+      goto Exit;++    error = open_face_from_buffer( library,+                                   sfnt_ps,+                                   length,+                                   face_index < 0 ? face_index : 0,+                                   is_sfnt_cid ? "cid" : "type1",+                                   aface );+  Exit:+    {+      FT_Error  error1;+++      if ( error == FT_Err_Unknown_File_Format )+      {+        error1 = FT_Stream_Seek( stream, pos );+        if ( error1 )+          return error1;+      }++      return error;+    }+  }+++#if !defined( FT_MACINTOSH ) || defined( DARWIN_NO_CARBON )++  /* The resource header says we've got resource_cnt `POST' (type1) */+  /* resources in this file.  They all need to be coalesced into    */+  /* one lump which gets passed on to the type1 driver.             */+  /* Here can be only one PostScript font in a file so face_index   */+  /* must be 0 (or -1).                                             */+  /*                                                                */+  static FT_Error+  Mac_Read_POST_Resource( FT_Library  library,+                          FT_Stream   stream,+                          FT_Long    *offsets,+                          FT_Long     resource_cnt,+                          FT_Long     face_index,+                          FT_Face    *aface )+  {+    FT_Error   error  = FT_Err_Cannot_Open_Resource;+    FT_Memory  memory = library->memory;+    FT_Byte*   pfb_data;+    int        i, type, flags;+    FT_Long    len;+    FT_Long    pfb_len, pfb_pos, pfb_lenpos;+    FT_Long    rlen, temp;+++    if ( face_index == -1 )+      face_index = 0;+    if ( face_index != 0 )+      return error;++    /* Find the length of all the POST resources, concatenated.  Assume */+    /* worst case (each resource in its own section).                   */+    pfb_len = 0;+    for ( i = 0; i < resource_cnt; ++i )+    {+      error = FT_Stream_Seek( stream, offsets[i] );+      if ( error )+        goto Exit;+      if ( FT_READ_LONG( temp ) )+        goto Exit;+      pfb_len += temp + 6;+    }++    if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )+      goto Exit;++    pfb_data[0] = 0x80;+    pfb_data[1] = 1;            /* Ascii section */+    pfb_data[2] = 0;            /* 4-byte length, fill in later */+    pfb_data[3] = 0;+    pfb_data[4] = 0;+    pfb_data[5] = 0;+    pfb_pos     = 6;+    pfb_lenpos  = 2;++    len = 0;+    type = 1;+    for ( i = 0; i < resource_cnt; ++i )+    {+      error = FT_Stream_Seek( stream, offsets[i] );+      if ( error )+        goto Exit2;+      if ( FT_READ_LONG( rlen ) )+        goto Exit;+      if ( FT_READ_USHORT( flags ) )+        goto Exit;+      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",+                   i, offsets[i], rlen, flags ));++      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */+      if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */+        continue;++      /* the flags are part of the resource, so rlen >= 2.  */+      /* but some fonts declare rlen = 0 for empty fragment */+      if ( rlen > 2 )+        rlen -= 2;+      else+        rlen = 0;++      if ( ( flags >> 8 ) == type )+        len += rlen;+      else+      {+        if ( pfb_lenpos + 3 > pfb_len + 2 )+          goto Exit2;+        pfb_data[pfb_lenpos    ] = (FT_Byte)( len );+        pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );+        pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );+        pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );++        if ( ( flags >> 8 ) == 5 )      /* End of font mark */+          break;++        if ( pfb_pos + 6 > pfb_len + 2 )+          goto Exit2;+        pfb_data[pfb_pos++] = 0x80;++        type = flags >> 8;+        len = rlen;++        pfb_data[pfb_pos++] = (FT_Byte)type;+        pfb_lenpos          = pfb_pos;+        pfb_data[pfb_pos++] = 0;        /* 4-byte length, fill in later */+        pfb_data[pfb_pos++] = 0;+        pfb_data[pfb_pos++] = 0;+        pfb_data[pfb_pos++] = 0;+      }++      error = FT_Err_Cannot_Open_Resource;+      if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )+        goto Exit2;++      error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );+      if ( error )+        goto Exit2;+      pfb_pos += rlen;+    }++    if ( pfb_pos + 2 > pfb_len + 2 )+      goto Exit2;+    pfb_data[pfb_pos++] = 0x80;+    pfb_data[pfb_pos++] = 3;++    if ( pfb_lenpos + 3 > pfb_len + 2 )+      goto Exit2;+    pfb_data[pfb_lenpos    ] = (FT_Byte)( len );+    pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );+    pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );+    pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );++    return open_face_from_buffer( library,+                                  pfb_data,+                                  pfb_pos,+                                  face_index,+                                  "type1",+                                  aface );++  Exit2:+    FT_FREE( pfb_data );++  Exit:+    return error;+  }+++  /* The resource header says we've got resource_cnt `sfnt'      */+  /* (TrueType/OpenType) resources in this file.  Look through   */+  /* them for the one indicated by face_index, load it into mem, */+  /* pass it on the the truetype driver and return it.           */+  /*                                                             */+  static FT_Error+  Mac_Read_sfnt_Resource( FT_Library  library,+                          FT_Stream   stream,+                          FT_Long    *offsets,+                          FT_Long     resource_cnt,+                          FT_Long     face_index,+                          FT_Face    *aface )+  {+    FT_Memory  memory = library->memory;+    FT_Byte*   sfnt_data;+    FT_Error   error;+    FT_Long    flag_offset;+    FT_Long    rlen;+    int        is_cff;+    FT_Long    face_index_in_resource = 0;+++    if ( face_index == -1 )+      face_index = 0;+    if ( face_index >= resource_cnt )+      return FT_Err_Cannot_Open_Resource;++    flag_offset = offsets[face_index];+    error = FT_Stream_Seek( stream, flag_offset );+    if ( error )+      goto Exit;++    if ( FT_READ_LONG( rlen ) )+      goto Exit;+    if ( rlen == -1 )+      return FT_Err_Cannot_Open_Resource;++    error = open_face_PS_from_sfnt_stream( library,+                                           stream,+                                           face_index,+                                           0, NULL,+                                           aface );+    if ( !error )+      goto Exit;++    /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */+    if ( FT_Stream_Seek( stream, flag_offset + 4 ) )+      goto Exit;++    if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )+      return error;+    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );+    if ( error )+      goto Exit;++    is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );+    error = open_face_from_buffer( library,+                                   sfnt_data,+                                   rlen,+                                   face_index_in_resource,+                                   is_cff ? "cff" : "truetype",+                                   aface );++  Exit:+    return error;+  }+++  /* Check for a valid resource fork header, or a valid dfont    */+  /* header.  In a resource fork the first 16 bytes are repeated */+  /* at the location specified by bytes 4-7.  In a dfont bytes   */+  /* 4-7 point to 16 bytes of zeroes instead.                    */+  /*                                                             */+  static FT_Error+  IsMacResource( FT_Library  library,+                 FT_Stream   stream,+                 FT_Long     resource_offset,+                 FT_Long     face_index,+                 FT_Face    *aface )+  {+    FT_Memory  memory = library->memory;+    FT_Error   error;+    FT_Long    map_offset, rdara_pos;+    FT_Long    *data_offsets;+    FT_Long    count;+++    error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,+                                       &map_offset, &rdara_pos );+    if ( error )+      return error;++    error = FT_Raccess_Get_DataOffsets( library, stream,+                                        map_offset, rdara_pos,+                                        TTAG_POST,+                                        &data_offsets, &count );+    if ( !error )+    {+      error = Mac_Read_POST_Resource( library, stream, data_offsets, count,+                                      face_index, aface );+      FT_FREE( data_offsets );+      /* POST exists in an LWFN providing a single face */+      if ( !error )+        (*aface)->num_faces = 1;+      return error;+    }++    error = FT_Raccess_Get_DataOffsets( library, stream,+                                        map_offset, rdara_pos,+                                        TTAG_sfnt,+                                        &data_offsets, &count );+    if ( !error )+    {+      FT_Long  face_index_internal = face_index % count;+++      error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,+                                      face_index_internal, aface );+      FT_FREE( data_offsets );+      if ( !error )+        (*aface)->num_faces = count;+    }++    return error;+  }+++  /* Check for a valid macbinary header, and if we find one   */+  /* check that the (flattened) resource fork in it is valid. */+  /*                                                          */+  static FT_Error+  IsMacBinary( FT_Library  library,+               FT_Stream   stream,+               FT_Long     face_index,+               FT_Face    *aface )+  {+    unsigned char  header[128];+    FT_Error       error;+    FT_Long        dlen, offset;+++    if ( NULL == stream )+      return FT_Err_Invalid_Stream_Operation;++    error = FT_Stream_Seek( stream, 0 );+    if ( error )+      goto Exit;++    error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );+    if ( error )+      goto Exit;++    if (            header[ 0] !=  0 ||+                    header[74] !=  0 ||+                    header[82] !=  0 ||+                    header[ 1] ==  0 ||+                    header[ 1] >  33 ||+                    header[63] !=  0 ||+         header[2 + header[1]] !=  0 )+      return FT_Err_Unknown_File_Format;++    dlen = ( header[0x53] << 24 ) |+           ( header[0x54] << 16 ) |+           ( header[0x55] <<  8 ) |+             header[0x56];+#if 0+    rlen = ( header[0x57] << 24 ) |+           ( header[0x58] << 16 ) |+           ( header[0x59] <<  8 ) |+             header[0x5a];+#endif /* 0 */+    offset = 128 + ( ( dlen + 127 ) & ~127 );++    return IsMacResource( library, stream, offset, face_index, aface );++  Exit:+    return error;+  }+++  static FT_Error+  load_face_in_embedded_rfork( FT_Library           library,+                               FT_Stream            stream,+                               FT_Long              face_index,+                               FT_Face             *aface,+                               const FT_Open_Args  *args )+  {++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_raccess++    FT_Memory  memory = library->memory;+    FT_Error   error  = FT_Err_Unknown_File_Format;+    int        i;++    char *     file_names[FT_RACCESS_N_RULES];+    FT_Long    offsets[FT_RACCESS_N_RULES];+    FT_Error   errors[FT_RACCESS_N_RULES];+    FT_Bool    is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */++    FT_Open_Args  args2;+    FT_Stream     stream2 = 0;+++    FT_Raccess_Guess( library, stream,+                      args->pathname, file_names, offsets, errors );++    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )+    {+      is_darwin_vfs = raccess_rule_by_darwin_vfs( i );+      if ( is_darwin_vfs && vfs_rfork_has_no_font )+      {+        FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"+                    " is already checked and"+                    " no font is found\n", i ));+        continue;+      }  ++      if ( errors[i] )+      {+        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));+        continue;+      }++      args2.flags    = FT_OPEN_PATHNAME;+      args2.pathname = file_names[i] ? file_names[i] : args->pathname;++      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",+                  i, args2.pathname, offsets[i] ));++      error = FT_Stream_New( library, &args2, &stream2 );+      if ( is_darwin_vfs && error == FT_Err_Cannot_Open_Stream )+        vfs_rfork_has_no_font = TRUE;++      if ( error )+      {+        FT_TRACE3(( "failed\n" ));+        continue;+      }++      error = IsMacResource( library, stream2, offsets[i],+                             face_index, aface );+      FT_Stream_Free( stream2, 0 );++      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));++      if ( !error )+          break;+      else if ( is_darwin_vfs )+          vfs_rfork_has_no_font = TRUE;+    }++    for (i = 0; i < FT_RACCESS_N_RULES; i++)+    {+      if ( file_names[i] )+        FT_FREE( file_names[i] );+    }++    /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */+    if ( error )+      error = FT_Err_Unknown_File_Format;++    return error;++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_objs++  }+++  /* Check for some macintosh formats without Carbon framework.    */+  /* Is this a macbinary file?  If so look at the resource fork.   */+  /* Is this a mac dfont file?                                     */+  /* Is this an old style resource fork? (in data)                 */+  /* Else call load_face_in_embedded_rfork to try extra rules      */+  /* (defined in `ftrfork.c').                                     */+  /*                                                               */+  static FT_Error+  load_mac_face( FT_Library           library,+                 FT_Stream            stream,+                 FT_Long              face_index,+                 FT_Face             *aface,+                 const FT_Open_Args  *args )+  {+    FT_Error error;+    FT_UNUSED( args );+++    error = IsMacBinary( library, stream, face_index, aface );+    if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )+    {++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_raccess++      FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));++      error = IsMacResource( library, stream, 0, face_index, aface );++      FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_objs++    }++    if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format      ||+           FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&+         ( args->flags & FT_OPEN_PATHNAME )                            )+      error = load_face_in_embedded_rfork( library, stream,+                                           face_index, aface, args );+    return error;+  }+#endif++#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Open_Face( FT_Library           library,+                const FT_Open_Args*  args,+                FT_Long              face_index,+                FT_Face             *aface )+  {+    FT_Error     error;+    FT_Driver    driver;+    FT_Memory    memory;+    FT_Stream    stream = NULL;+    FT_Face      face   = NULL;+    FT_ListNode  node   = NULL;+    FT_Bool      external_stream;+    FT_Module*   cur;+    FT_Module*   limit;+++    /* test for valid `library' delayed to */+    /* FT_Stream_New()                     */++    if ( ( !aface && face_index >= 0 ) || !args )+      return FT_Err_Invalid_Argument;++    external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&+                               args->stream                     );++    /* create input stream */+    error = FT_Stream_New( library, args, &stream );+    if ( error )+      goto Fail3;++    memory = library->memory;++    /* If the font driver is specified in the `args' structure, use */+    /* it.  Otherwise, we scan the list of registered drivers.      */+    if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )+    {+      driver = FT_DRIVER( args->driver );++      /* not all modules are drivers, so check... */+      if ( FT_MODULE_IS_DRIVER( driver ) )+      {+        FT_Int         num_params = 0;+        FT_Parameter*  params     = 0;+++        if ( args->flags & FT_OPEN_PARAMS )+        {+          num_params = args->num_params;+          params     = args->params;+        }++        error = open_face( driver, stream, face_index,+                           num_params, params, &face );+        if ( !error )+          goto Success;+      }+      else+        error = FT_Err_Invalid_Handle;++      FT_Stream_Free( stream, external_stream );+      goto Fail;+    }+    else+    {+      /* check each font driver for an appropriate format */+      cur   = library->modules;+      limit = cur + library->num_modules;+++      for ( ; cur < limit; cur++ )+      {+        /* not all modules are font drivers, so check... */+        if ( FT_MODULE_IS_DRIVER( cur[0] ) )+        {+          FT_Int         num_params = 0;+          FT_Parameter*  params     = 0;+++          driver = FT_DRIVER( cur[0] );++          if ( args->flags & FT_OPEN_PARAMS )+          {+            num_params = args->num_params;+            params     = args->params;+          }++          error = open_face( driver, stream, face_index,+                             num_params, params, &face );+          if ( !error )+            goto Success;++#ifdef FT_CONFIG_OPTION_MAC_FONTS+          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&+               FT_ERROR_BASE( error ) == FT_Err_Table_Missing           )+          {+            /* TrueType but essential tables are missing */+            if ( FT_Stream_Seek( stream, 0 ) )+              break;++            error = open_face_PS_from_sfnt_stream( library,+                                                   stream,+                                                   face_index,+                                                   num_params,+                                                   params,+                                                   aface );+            if ( !error )+            {+              FT_Stream_Free( stream, external_stream );+              return error;+            }+          }+#endif++          if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )+            goto Fail3;+        }+      }++  Fail3:+    /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */+    /* it may be because we have an empty data fork, so we need to check   */+    /* the resource fork.                                                  */+    if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream       &&+         FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format      &&+         FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )+      goto Fail2;++#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )+    error = load_mac_face( library, stream, face_index, aface, args );+    if ( !error )+    {+      /* We don't want to go to Success here.  We've already done that. */+      /* On the other hand, if we succeeded we still need to close this */+      /* stream (we opened a different stream which extracted the       */+      /* interesting information out of this stream here.  That stream  */+      /* will still be open and the face will point to it).             */+      FT_Stream_Free( stream, external_stream );+      return error;+    }++    if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )+      goto Fail2;+#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */++      /* no driver is able to handle this format */+      error = FT_Err_Unknown_File_Format;++  Fail2:+      FT_Stream_Free( stream, external_stream );+      goto Fail;+    }++  Success:+    FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));++    /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */+    if ( external_stream )+      face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;++    /* add the face object to its driver's list */+    if ( FT_NEW( node ) )+      goto Fail;++    node->data = face;+    /* don't assume driver is the same as face->driver, so use */+    /* face->driver instead.                                   */+    FT_List_Add( &face->driver->faces_list, node );++    /* now allocate a glyph slot object for the face */+    FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));++    if ( face_index >= 0 )+    {+      error = FT_New_GlyphSlot( face, NULL );+      if ( error )+        goto Fail;++      /* finally, allocate a size object for the face */+      {+        FT_Size  size;+++        FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));++        error = FT_New_Size( face, &size );+        if ( error )+          goto Fail;++        face->size = size;+      }+    }++    /* some checks */++    if ( FT_IS_SCALABLE( face ) )+    {+      if ( face->height < 0 )+        face->height = (FT_Short)-face->height;++      if ( !FT_HAS_VERTICAL( face ) )+        face->max_advance_height = (FT_Short)face->height;+    }++    if ( FT_HAS_FIXED_SIZES( face ) )+    {+      FT_Int  i;+++      for ( i = 0; i < face->num_fixed_sizes; i++ )+      {+        FT_Bitmap_Size*  bsize = face->available_sizes + i;+++        if ( bsize->height < 0 )+          bsize->height = (FT_Short)-bsize->height;+        if ( bsize->x_ppem < 0 )+          bsize->x_ppem = (FT_Short)-bsize->x_ppem;+        if ( bsize->y_ppem < 0 )+          bsize->y_ppem = -bsize->y_ppem;+      }+    }++    /* initialize internal face data */+    {+      FT_Face_Internal  internal = face->internal;+++      internal->transform_matrix.xx = 0x10000L;+      internal->transform_matrix.xy = 0;+      internal->transform_matrix.yx = 0;+      internal->transform_matrix.yy = 0x10000L;++      internal->transform_delta.x = 0;+      internal->transform_delta.y = 0;++      internal->refcount = 1;+    }++    if ( aface )+      *aface = face;+    else+      FT_Done_Face( face );++    goto Exit;++  Fail:+    FT_Done_Face( face );++  Exit:+    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Attach_File( FT_Face      face,+                  const char*  filepathname )+  {+    FT_Open_Args  open;+++    /* test for valid `face' delayed to FT_Attach_Stream() */++    if ( !filepathname )+      return FT_Err_Invalid_Argument;++    open.stream   = NULL;+    open.flags    = FT_OPEN_PATHNAME;+    open.pathname = (char*)filepathname;++    return FT_Attach_Stream( face, &open );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Attach_Stream( FT_Face        face,+                    FT_Open_Args*  parameters )+  {+    FT_Stream  stream;+    FT_Error   error;+    FT_Driver  driver;++    FT_Driver_Class  clazz;+++    /* test for valid `parameters' delayed to FT_Stream_New() */++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    driver = face->driver;+    if ( !driver )+      return FT_Err_Invalid_Driver_Handle;++    error = FT_Stream_New( driver->root.library, parameters, &stream );+    if ( error )+      goto Exit;++    /* we implement FT_Attach_Stream in each driver through the */+    /* `attach_file' interface                                  */++    error = FT_Err_Unimplemented_Feature;+    clazz = driver->clazz;+    if ( clazz->attach_file )+      error = clazz->attach_file( face, stream );++    /* close the attached stream */+    FT_Stream_Free( stream,+                    (FT_Bool)( parameters->stream &&+                               ( parameters->flags & FT_OPEN_STREAM ) ) );++  Exit:+    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Reference_Face( FT_Face  face )+  {+    face->internal->refcount++;++    return FT_Err_Ok;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Done_Face( FT_Face  face )+  {+    FT_Error     error;+    FT_Driver    driver;+    FT_Memory    memory;+    FT_ListNode  node;+++    error = FT_Err_Invalid_Face_Handle;+    if ( face && face->driver )+    {+      face->internal->refcount--;+      if ( face->internal->refcount > 0 )+        error = FT_Err_Ok;+      else+      {+        driver = face->driver;+        memory = driver->root.memory;++        /* find face in driver's list */+        node = FT_List_Find( &driver->faces_list, face );+        if ( node )+        {+          /* remove face object from the driver's list */+          FT_List_Remove( &driver->faces_list, node );+          FT_FREE( node );++          /* now destroy the object proper */+          destroy_face( memory, face, driver );+          error = FT_Err_Ok;+        }+      }+    }++    return error;+  }+++  /* documentation is in ftobjs.h */++  FT_EXPORT_DEF( FT_Error )+  FT_New_Size( FT_Face   face,+               FT_Size  *asize )+  {+    FT_Error         error;+    FT_Memory        memory;+    FT_Driver        driver;+    FT_Driver_Class  clazz;++    FT_Size          size = 0;+    FT_ListNode      node = 0;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( !asize )+      return FT_Err_Invalid_Size_Handle;++    if ( !face->driver )+      return FT_Err_Invalid_Driver_Handle;++    *asize = 0;++    driver = face->driver;+    clazz  = driver->clazz;+    memory = face->memory;++    /* Allocate new size object and perform basic initialisation */+    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )+      goto Exit;++    size->face = face;++    /* for now, do not use any internal fields in size objects */+    size->internal = 0;++    if ( clazz->init_size )+      error = clazz->init_size( size );++    /* in case of success, add to the face's list */+    if ( !error )+    {+      *asize     = size;+      node->data = size;+      FT_List_Add( &face->sizes_list, node );+    }++  Exit:+    if ( error )+    {+      FT_FREE( node );+      FT_FREE( size );+    }++    return error;+  }+++  /* documentation is in ftobjs.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Done_Size( FT_Size  size )+  {+    FT_Error     error;+    FT_Driver    driver;+    FT_Memory    memory;+    FT_Face      face;+    FT_ListNode  node;+++    if ( !size )+      return FT_Err_Invalid_Size_Handle;++    face = size->face;+    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    driver = face->driver;+    if ( !driver )+      return FT_Err_Invalid_Driver_Handle;++    memory = driver->root.memory;++    error = FT_Err_Ok;+    node  = FT_List_Find( &face->sizes_list, size );+    if ( node )+    {+      FT_List_Remove( &face->sizes_list, node );+      FT_FREE( node );++      if ( face->size == size )+      {+        face->size = 0;+        if ( face->sizes_list.head )+          face->size = (FT_Size)(face->sizes_list.head->data);+      }++      destroy_size( memory, size, driver );+    }+    else+      error = FT_Err_Invalid_Size_Handle;++    return error;+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( FT_Error )+  FT_Match_Size( FT_Face          face,+                 FT_Size_Request  req,+                 FT_Bool          ignore_width,+                 FT_ULong*        size_index )+  {+    FT_Int   i;+    FT_Long  w, h;+++    if ( !FT_HAS_FIXED_SIZES( face ) )+      return FT_Err_Invalid_Face_Handle;++    /* FT_Bitmap_Size doesn't provide enough info... */+    if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )+      return FT_Err_Unimplemented_Feature;++    w = FT_REQUEST_WIDTH ( req );+    h = FT_REQUEST_HEIGHT( req );++    if ( req->width && !req->height )+      h = w;+    else if ( !req->width && req->height )+      w = h;++    w = FT_PIX_ROUND( w );+    h = FT_PIX_ROUND( h );++    for ( i = 0; i < face->num_fixed_sizes; i++ )+    {+      FT_Bitmap_Size*  bsize = face->available_sizes + i;+++      if ( h != FT_PIX_ROUND( bsize->y_ppem ) )+        continue;++      if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )+      {+        if ( size_index )+          *size_index = (FT_ULong)i;++        return FT_Err_Ok;+      }+    }++    return FT_Err_Invalid_Pixel_Size;+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( void )+  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,+                                  FT_Pos             advance )+  {+    FT_Pos  height = metrics->height;+++    /* compensate for glyph with bbox above/below the baseline */+    if ( metrics->horiBearingY < 0 )+    {+      if ( height < metrics->horiBearingY )+        height = metrics->horiBearingY;+    }+    else if ( metrics->horiBearingY > 0 )+      height -= metrics->horiBearingY;++    /* the factor 1.2 is a heuristical value */+    if ( !advance )+      advance = height * 12 / 10;++    metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;+    metrics->vertBearingY = ( advance - height ) / 2;+    metrics->vertAdvance  = advance;+  }+++  static void+  ft_recompute_scaled_metrics( FT_Face           face,+                               FT_Size_Metrics*  metrics )+  {+    /* Compute root ascender, descender, test height, and max_advance */++#ifdef GRID_FIT_METRICS+    metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender,+                                                   metrics->y_scale ) );++    metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender,+                                                    metrics->y_scale ) );++    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height,+                                                    metrics->y_scale ) );++    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,+                                                    metrics->x_scale ) );+#else /* !GRID_FIT_METRICS */+    metrics->ascender    = FT_MulFix( face->ascender,+                                      metrics->y_scale );++    metrics->descender   = FT_MulFix( face->descender,+                                      metrics->y_scale );++    metrics->height      = FT_MulFix( face->height,+                                      metrics->y_scale );++    metrics->max_advance = FT_MulFix( face->max_advance_width,+                                      metrics->x_scale );+#endif /* !GRID_FIT_METRICS */+  }+++  FT_BASE_DEF( void )+  FT_Select_Metrics( FT_Face   face,+                     FT_ULong  strike_index )+  {+    FT_Size_Metrics*  metrics;+    FT_Bitmap_Size*   bsize;+++    metrics = &face->size->metrics;+    bsize   = face->available_sizes + strike_index;++    metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );+    metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );++    if ( FT_IS_SCALABLE( face ) )+    {+      metrics->x_scale = FT_DivFix( bsize->x_ppem,+                                    face->units_per_EM );+      metrics->y_scale = FT_DivFix( bsize->y_ppem,+                                    face->units_per_EM );++      ft_recompute_scaled_metrics( face, metrics );+    }+    else+    {+      metrics->x_scale     = 1L << 16;+      metrics->y_scale     = 1L << 16;+      metrics->ascender    = bsize->y_ppem;+      metrics->descender   = 0;+      metrics->height      = bsize->height << 6;+      metrics->max_advance = bsize->x_ppem;+    }+  }+++  FT_BASE_DEF( void )+  FT_Request_Metrics( FT_Face          face,+                      FT_Size_Request  req )+  {+    FT_Size_Metrics*  metrics;+++    metrics = &face->size->metrics;++    if ( FT_IS_SCALABLE( face ) )+    {+      FT_Long  w = 0, h = 0, scaled_w = 0, scaled_h = 0;+++      switch ( req->type )+      {+      case FT_SIZE_REQUEST_TYPE_NOMINAL:+        w = h = face->units_per_EM;+        break;++      case FT_SIZE_REQUEST_TYPE_REAL_DIM:+        w = h = face->ascender - face->descender;+        break;++      case FT_SIZE_REQUEST_TYPE_BBOX:+        w = face->bbox.xMax - face->bbox.xMin;+        h = face->bbox.yMax - face->bbox.yMin;+        break;++      case FT_SIZE_REQUEST_TYPE_CELL:+        w = face->max_advance_width;+        h = face->ascender - face->descender;+        break;++      case FT_SIZE_REQUEST_TYPE_SCALES:+        metrics->x_scale = (FT_Fixed)req->width;+        metrics->y_scale = (FT_Fixed)req->height;+        if ( !metrics->x_scale )+          metrics->x_scale = metrics->y_scale;+        else if ( !metrics->y_scale )+          metrics->y_scale = metrics->x_scale;+        goto Calculate_Ppem;++      case FT_SIZE_REQUEST_TYPE_MAX:+        break;+      }++      /* to be on the safe side */+      if ( w < 0 )+        w = -w;++      if ( h < 0 )+        h = -h;++      scaled_w = FT_REQUEST_WIDTH ( req );+      scaled_h = FT_REQUEST_HEIGHT( req );++      /* determine scales */+      if ( req->width )+      {+        metrics->x_scale = FT_DivFix( scaled_w, w );++        if ( req->height )+        {+          metrics->y_scale = FT_DivFix( scaled_h, h );++          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )+          {+            if ( metrics->y_scale > metrics->x_scale )+              metrics->y_scale = metrics->x_scale;+            else+              metrics->x_scale = metrics->y_scale;+          }+        }+        else+        {+          metrics->y_scale = metrics->x_scale;+          scaled_h = FT_MulDiv( scaled_w, h, w );+        }+      }+      else+      {+        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );+        scaled_w = FT_MulDiv( scaled_h, w, h );+      }++  Calculate_Ppem:+      /* calculate the ppems */+      if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )+      {+        scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );+        scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );+      }++      metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );+      metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );++      ft_recompute_scaled_metrics( face, metrics );+    }+    else+    {+      FT_ZERO( metrics );+      metrics->x_scale = 1L << 16;+      metrics->y_scale = 1L << 16;+    }+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Select_Size( FT_Face  face,+                  FT_Int   strike_index )+  {+    FT_Driver_Class  clazz;+++    if ( !face || !FT_HAS_FIXED_SIZES( face ) )+      return FT_Err_Invalid_Face_Handle;++    if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )+      return FT_Err_Invalid_Argument;++    clazz = face->driver->clazz;++    if ( clazz->select_size )+      return clazz->select_size( face->size, (FT_ULong)strike_index );++    FT_Select_Metrics( face, (FT_ULong)strike_index );++    return FT_Err_Ok;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Request_Size( FT_Face          face,+                   FT_Size_Request  req )+  {+    FT_Driver_Class  clazz;+    FT_ULong         strike_index;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( !req || req->width < 0 || req->height < 0 ||+         req->type >= FT_SIZE_REQUEST_TYPE_MAX )+      return FT_Err_Invalid_Argument;++    clazz = face->driver->clazz;++    if ( clazz->request_size )+      return clazz->request_size( face->size, req );++    /*+     * The reason that a driver doesn't have `request_size' defined is+     * either that the scaling here suffices or that the supported formats+     * are bitmap-only and size matching is not implemented.+     *+     * In the latter case, a simple size matching is done.+     */+    if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )+    {+      FT_Error  error;+++      error = FT_Match_Size( face, req, 0, &strike_index );+      if ( error )+        return error;++      FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n",+                  strike_index ));++      return FT_Select_Size( face, (FT_Int)strike_index );+    }++    FT_Request_Metrics( face, req );++    return FT_Err_Ok;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Char_Size( FT_Face     face,+                    FT_F26Dot6  char_width,+                    FT_F26Dot6  char_height,+                    FT_UInt     horz_resolution,+                    FT_UInt     vert_resolution )+  {+    FT_Size_RequestRec  req;+++    if ( !char_width )+      char_width = char_height;+    else if ( !char_height )+      char_height = char_width;++    if ( !horz_resolution )+      horz_resolution = vert_resolution;+    else if ( !vert_resolution )+      vert_resolution = horz_resolution;++    if ( char_width  < 1 * 64 )+      char_width  = 1 * 64;+    if ( char_height < 1 * 64 )+      char_height = 1 * 64;++    if ( !horz_resolution )+      horz_resolution = vert_resolution = 72;++    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;+    req.width          = char_width;+    req.height         = char_height;+    req.horiResolution = horz_resolution;+    req.vertResolution = vert_resolution;++    return FT_Request_Size( face, &req );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Pixel_Sizes( FT_Face  face,+                      FT_UInt  pixel_width,+                      FT_UInt  pixel_height )+  {+    FT_Size_RequestRec  req;+++    if ( pixel_width == 0 )+      pixel_width = pixel_height;+    else if ( pixel_height == 0 )+      pixel_height = pixel_width;++    if ( pixel_width  < 1 )+      pixel_width  = 1;+    if ( pixel_height < 1 )+      pixel_height = 1;++    /* use `>=' to avoid potential compiler warning on 16bit platforms */+    if ( pixel_width  >= 0xFFFFU )+      pixel_width  = 0xFFFFU;+    if ( pixel_height >= 0xFFFFU )+      pixel_height = 0xFFFFU;++    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;+    req.width          = pixel_width << 6;+    req.height         = pixel_height << 6;+    req.horiResolution = 0;+    req.vertResolution = 0;++    return FT_Request_Size( face, &req );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Kerning( FT_Face     face,+                  FT_UInt     left_glyph,+                  FT_UInt     right_glyph,+                  FT_UInt     kern_mode,+                  FT_Vector  *akerning )+  {+    FT_Error   error = FT_Err_Ok;+    FT_Driver  driver;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( !akerning )+      return FT_Err_Invalid_Argument;++    driver = face->driver;++    akerning->x = 0;+    akerning->y = 0;++    if ( driver->clazz->get_kerning )+    {+      error = driver->clazz->get_kerning( face,+                                          left_glyph,+                                          right_glyph,+                                          akerning );+      if ( !error )+      {+        if ( kern_mode != FT_KERNING_UNSCALED )+        {+          akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );+          akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );++          if ( kern_mode != FT_KERNING_UNFITTED )+          {+            /* we scale down kerning values for small ppem values */+            /* to avoid that rounding makes them too big.         */+            /* `25' has been determined heuristically.            */+            if ( face->size->metrics.x_ppem < 25 )+              akerning->x = FT_MulDiv( akerning->x,+                                       face->size->metrics.x_ppem, 25 );+            if ( face->size->metrics.y_ppem < 25 )+              akerning->y = FT_MulDiv( akerning->y,+                                       face->size->metrics.y_ppem, 25 );++            akerning->x = FT_PIX_ROUND( akerning->x );+            akerning->y = FT_PIX_ROUND( akerning->y );+          }+        }+      }+    }++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Track_Kerning( FT_Face    face,+                        FT_Fixed   point_size,+                        FT_Int     degree,+                        FT_Fixed*  akerning )+  {+    FT_Service_Kerning  service;+    FT_Error            error = FT_Err_Ok;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( !akerning )+      return FT_Err_Invalid_Argument;++    FT_FACE_FIND_SERVICE( face, service, KERNING );+    if ( !service )+      return FT_Err_Unimplemented_Feature;++    error = service->get_track( face,+                                point_size,+                                degree,+                                akerning );++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Select_Charmap( FT_Face      face,+                     FT_Encoding  encoding )+  {+    FT_CharMap*  cur;+    FT_CharMap*  limit;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    if ( encoding == FT_ENCODING_NONE )+      return FT_Err_Invalid_Argument;++    /* FT_ENCODING_UNICODE is special.  We try to find the `best' Unicode */+    /* charmap available, i.e., one with UCS-4 characters, if possible.   */+    /*                                                                    */+    /* This is done by find_unicode_charmap() above, to share code.       */+    if ( encoding == FT_ENCODING_UNICODE )+      return find_unicode_charmap( face );++    cur = face->charmaps;+    if ( !cur )+      return FT_Err_Invalid_CharMap_Handle;++    limit = cur + face->num_charmaps;++    for ( ; cur < limit; cur++ )+    {+      if ( cur[0]->encoding == encoding )+      {+#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "+                     "but in too late position to cache\n",+                     cur - face->charmaps ));+          continue;+        }+#endif+        face->charmap = cur[0];+        return 0;+      }+    }++    return FT_Err_Invalid_Argument;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Charmap( FT_Face     face,+                  FT_CharMap  charmap )+  {+    FT_CharMap*  cur;+    FT_CharMap*  limit;+++    if ( !face )+      return FT_Err_Invalid_Face_Handle;++    cur = face->charmaps;+    if ( !cur )+      return FT_Err_Invalid_CharMap_Handle;+    if ( FT_Get_CMap_Format( charmap ) == 14 )+      return FT_Err_Invalid_Argument;++    limit = cur + face->num_charmaps;++    for ( ; cur < limit; cur++ )+    {+      if ( cur[0] == charmap )+      {+#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "+                     "but in too late position to cache\n",+                     cur - face->charmaps ));+          continue;+        }+#endif+        face->charmap = cur[0];+        return 0;+      }+    }+    return FT_Err_Invalid_Argument;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Int )+  FT_Get_Charmap_Index( FT_CharMap  charmap )+  {+    FT_Int  i;+++    if ( !charmap || !charmap->face )+      return -1;++    for ( i = 0; i < charmap->face->num_charmaps; i++ )+      if ( charmap->face->charmaps[i] == charmap )+        break;++    FT_ASSERT( i < charmap->face->num_charmaps );++#ifdef FT_MAX_CHARMAP_CACHEABLE+    if ( i > FT_MAX_CHARMAP_CACHEABLE )+    {+      FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "+                 "but in too late position to cache\n",+                 i ));+      return -i;+    }+#endif+    return i;+  }+++  static void+  ft_cmap_done_internal( FT_CMap  cmap )+  {+    FT_CMap_Class  clazz  = cmap->clazz;+    FT_Face        face   = cmap->charmap.face;+    FT_Memory      memory = FT_FACE_MEMORY(face);+++    if ( clazz->done )+      clazz->done( cmap );++    FT_FREE( cmap );+  }+++  FT_BASE_DEF( void )+  FT_CMap_Done( FT_CMap  cmap )+  {+    if ( cmap )+    {+      FT_Face    face   = cmap->charmap.face;+      FT_Memory  memory = FT_FACE_MEMORY( face );+      FT_Error   error;+      FT_Int     i, j;+++      for ( i = 0; i < face->num_charmaps; i++ )+      {+        if ( (FT_CMap)face->charmaps[i] == cmap )+        {+          FT_CharMap  last_charmap = face->charmaps[face->num_charmaps - 1];+++          if ( FT_RENEW_ARRAY( face->charmaps,+                               face->num_charmaps,+                               face->num_charmaps - 1 ) )+            return;++          /* remove it from our list of charmaps */+          for ( j = i + 1; j < face->num_charmaps; j++ )+          {+            if ( j == face->num_charmaps - 1 )+              face->charmaps[j - 1] = last_charmap;+            else+              face->charmaps[j - 1] = face->charmaps[j];+          }++          face->num_charmaps--;++          if ( (FT_CMap)face->charmap == cmap )+            face->charmap = NULL;++          ft_cmap_done_internal( cmap );++          break;+        }+      }+    }+  }+++  FT_BASE_DEF( FT_Error )+  FT_CMap_New( FT_CMap_Class  clazz,+               FT_Pointer     init_data,+               FT_CharMap     charmap,+               FT_CMap       *acmap )+  {+    FT_Error   error = FT_Err_Ok;+    FT_Face    face;+    FT_Memory  memory;+    FT_CMap    cmap;+++    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )+      return FT_Err_Invalid_Argument;++    face   = charmap->face;+    memory = FT_FACE_MEMORY( face );++    if ( !FT_ALLOC( cmap, clazz->size ) )+    {+      cmap->charmap = *charmap;+      cmap->clazz   = clazz;++      if ( clazz->init )+      {+        error = clazz->init( cmap, init_data );+        if ( error )+          goto Fail;+      }++      /* add it to our list of charmaps */+      if ( FT_RENEW_ARRAY( face->charmaps,+                           face->num_charmaps,+                           face->num_charmaps + 1 ) )+        goto Fail;++      face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;+    }++  Exit:+    if ( acmap )+      *acmap = cmap;++    return error;++  Fail:+    ft_cmap_done_internal( cmap );+    cmap = NULL;+    goto Exit;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt )+  FT_Get_Char_Index( FT_Face   face,+                     FT_ULong  charcode )+  {+    FT_UInt  result = 0;+++    if ( face && face->charmap )+    {+      FT_CMap  cmap = FT_CMAP( face->charmap );+++      if ( charcode > 0xFFFFFFFFUL )+      {+        FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));+        FT_TRACE1(( " 0x%x is truncated\n", charcode ));+      }+      result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );+    }+    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_ULong )+  FT_Get_First_Char( FT_Face   face,+                     FT_UInt  *agindex )+  {+    FT_ULong  result = 0;+    FT_UInt   gindex = 0;+++    if ( face && face->charmap && face->num_glyphs )+    {+      gindex = FT_Get_Char_Index( face, 0 );+      if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )+        result = FT_Get_Next_Char( face, 0, &gindex );+    }++    if ( agindex )+      *agindex = gindex;++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_ULong )+  FT_Get_Next_Char( FT_Face   face,+                    FT_ULong  charcode,+                    FT_UInt  *agindex )+  {+    FT_ULong  result = 0;+    FT_UInt   gindex = 0;+++    if ( face && face->charmap && face->num_glyphs )+    {+      FT_UInt32  code = (FT_UInt32)charcode;+      FT_CMap    cmap = FT_CMAP( face->charmap );+++      do {+        gindex = cmap->clazz->char_next( cmap, &code );+      } while ( gindex >= (FT_UInt)face->num_glyphs );++      result = ( gindex == 0 ) ? 0 : code;+    }++    if ( agindex )+      *agindex = gindex;++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt )+  FT_Face_GetCharVariantIndex( FT_Face   face,+                               FT_ULong  charcode,+                               FT_ULong  variantSelector )+  {+    FT_UInt  result = 0;+++    if ( face && face->charmap &&+        face->charmap->encoding == FT_ENCODING_UNICODE )+    {+      FT_CharMap  charmap = find_variant_selector_charmap( face );+      FT_CMap     ucmap = FT_CMAP( face->charmap );+++      if ( charmap != NULL )+      {+        FT_CMap  vcmap = FT_CMAP( charmap );+++        if ( charcode > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));+        }+        if ( variantSelector > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));+        }++        result = vcmap->clazz->char_var_index( vcmap, ucmap,+                                               (FT_UInt32)charcode,+                                               (FT_UInt32)variantSelector );+      }+    }++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Int )+  FT_Face_GetCharVariantIsDefault( FT_Face   face,+                                   FT_ULong  charcode,+                                   FT_ULong  variantSelector )+  {+    FT_Int  result = -1;+++    if ( face )+    {+      FT_CharMap  charmap = find_variant_selector_charmap( face );+++      if ( charmap != NULL )+      {+        FT_CMap  vcmap = FT_CMAP( charmap );+++        if ( charcode > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));+        }+        if ( variantSelector > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));+        }++        result = vcmap->clazz->char_var_default( vcmap,+                                                 (FT_UInt32)charcode,+                                                 (FT_UInt32)variantSelector );+      }+    }++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt32* )+  FT_Face_GetVariantSelectors( FT_Face  face )+  {+    FT_UInt32  *result = NULL;+++    if ( face )+    {+      FT_CharMap  charmap = find_variant_selector_charmap( face );+++      if ( charmap != NULL )+      {+        FT_CMap    vcmap  = FT_CMAP( charmap );+        FT_Memory  memory = FT_FACE_MEMORY( face );+++        result = vcmap->clazz->variant_list( vcmap, memory );+      }+    }++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt32* )+  FT_Face_GetVariantsOfChar( FT_Face   face,+                             FT_ULong  charcode )+  {+    FT_UInt32  *result = NULL;+++    if ( face )+    {+      FT_CharMap  charmap = find_variant_selector_charmap( face );+++      if ( charmap != NULL )+      {+        FT_CMap    vcmap  = FT_CMAP( charmap );+        FT_Memory  memory = FT_FACE_MEMORY( face );+++        if ( charcode > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));+        }++        result = vcmap->clazz->charvariant_list( vcmap, memory,+                                                 (FT_UInt32)charcode );+      }+    }+    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt32* )+  FT_Face_GetCharsOfVariant( FT_Face   face,+                             FT_ULong  variantSelector )+  {+    FT_UInt32  *result = NULL;+++    if ( face )+    {+      FT_CharMap  charmap = find_variant_selector_charmap( face );+++      if ( charmap != NULL )+      {+        FT_CMap    vcmap  = FT_CMAP( charmap );+        FT_Memory  memory = FT_FACE_MEMORY( face );+++        if ( variantSelector > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));+        }++        result = vcmap->clazz->variantchar_list( vcmap, memory,+                                                 (FT_UInt32)variantSelector );+      }+    }++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_UInt )+  FT_Get_Name_Index( FT_Face     face,+                     FT_String*  glyph_name )+  {+    FT_UInt  result = 0;+++    if ( face && FT_HAS_GLYPH_NAMES( face ) )+    {+      FT_Service_GlyphDict  service;+++      FT_FACE_LOOKUP_SERVICE( face,+                              service,+                              GLYPH_DICT );++      if ( service && service->name_index )+        result = service->name_index( face, glyph_name );+    }++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Glyph_Name( FT_Face     face,+                     FT_UInt     glyph_index,+                     FT_Pointer  buffer,+                     FT_UInt     buffer_max )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+++    /* clean up buffer */+    if ( buffer && buffer_max > 0 )+      ((FT_Byte*)buffer)[0] = 0;++    if ( face                                     &&+         (FT_Long)glyph_index <= face->num_glyphs &&+         FT_HAS_GLYPH_NAMES( face )               )+    {+      FT_Service_GlyphDict  service;+++      FT_FACE_LOOKUP_SERVICE( face,+                              service,+                              GLYPH_DICT );++      if ( service && service->get_name )+        error = service->get_name( face, glyph_index, buffer, buffer_max );+    }++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( const char* )+  FT_Get_Postscript_Name( FT_Face  face )+  {+    const char*  result = NULL;+++    if ( !face )+      goto Exit;++    if ( !result )+    {+      FT_Service_PsFontName  service;+++      FT_FACE_LOOKUP_SERVICE( face,+                              service,+                              POSTSCRIPT_FONT_NAME );++      if ( service && service->get_ps_font_name )+        result = service->get_ps_font_name( face );+    }++  Exit:+    return result;+  }+++  /* documentation is in tttables.h */++  FT_EXPORT_DEF( void* )+  FT_Get_Sfnt_Table( FT_Face      face,+                     FT_Sfnt_Tag  tag )+  {+    void*                  table = 0;+    FT_Service_SFNT_Table  service;+++    if ( face && FT_IS_SFNT( face ) )+    {+      FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );+      if ( service != NULL )+        table = service->get_table( face, tag );+    }++    return table;+  }+++  /* documentation is in tttables.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Load_Sfnt_Table( FT_Face    face,+                      FT_ULong   tag,+                      FT_Long    offset,+                      FT_Byte*   buffer,+                      FT_ULong*  length )+  {+    FT_Service_SFNT_Table  service;+++    if ( !face || !FT_IS_SFNT( face ) )+      return FT_Err_Invalid_Face_Handle;++    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );+    if ( service == NULL )+      return FT_Err_Unimplemented_Feature;++    return service->load_table( face, tag, offset, buffer, length );+  }+++  /* documentation is in tttables.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Sfnt_Table_Info( FT_Face    face,+                      FT_UInt    table_index,+                      FT_ULong  *tag,+                      FT_ULong  *length )+  {+    FT_Service_SFNT_Table  service;+    FT_ULong               offset;+++    if ( !face || !FT_IS_SFNT( face ) )+      return FT_Err_Invalid_Face_Handle;++    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );+    if ( service == NULL )+      return FT_Err_Unimplemented_Feature;++    return service->table_info( face, table_index, tag, &offset, length );+  }+++  /* documentation is in tttables.h */++  FT_EXPORT_DEF( FT_ULong )+  FT_Get_CMap_Language_ID( FT_CharMap  charmap )+  {+    FT_Service_TTCMaps  service;+    FT_Face             face;+    TT_CMapInfo         cmap_info;+++    if ( !charmap || !charmap->face )+      return 0;++    face = charmap->face;+    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );+    if ( service == NULL )+      return 0;+    if ( service->get_cmap_info( charmap, &cmap_info ))+      return 0;++    return cmap_info.language;+  }+++  /* documentation is in tttables.h */++  FT_EXPORT_DEF( FT_Long )+  FT_Get_CMap_Format( FT_CharMap  charmap )+  {+    FT_Service_TTCMaps  service;+    FT_Face             face;+    TT_CMapInfo         cmap_info;+++    if ( !charmap || !charmap->face )+      return -1;++    face = charmap->face;+    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );+    if ( service == NULL )+      return -1;+    if ( service->get_cmap_info( charmap, &cmap_info ))+      return -1;++    return cmap_info.format;+  }+++  /* documentation is in ftsizes.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Activate_Size( FT_Size  size )+  {+    FT_Face  face;+++    if ( size == NULL )+      return FT_Err_Invalid_Argument;++    face = size->face;+    if ( face == NULL || face->driver == NULL )+      return FT_Err_Invalid_Argument;++    /* we don't need anything more complex than that; all size objects */+    /* are already listed by the face                                  */+    face->size = size;++    return FT_Err_Ok;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                        R E N D E R E R S                        ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  /* lookup a renderer by glyph format in the library's list */+  FT_BASE_DEF( FT_Renderer )+  FT_Lookup_Renderer( FT_Library       library,+                      FT_Glyph_Format  format,+                      FT_ListNode*     node )+  {+    FT_ListNode  cur;+    FT_Renderer  result = 0;+++    if ( !library )+      goto Exit;++    cur = library->renderers.head;++    if ( node )+    {+      if ( *node )+        cur = (*node)->next;+      *node = 0;+    }++    while ( cur )+    {+      FT_Renderer  renderer = FT_RENDERER( cur->data );+++      if ( renderer->glyph_format == format )+      {+        if ( node )+          *node = cur;++        result = renderer;+        break;+      }+      cur = cur->next;+    }++  Exit:+    return result;+  }+++  static FT_Renderer+  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )+  {+    FT_Face      face    = slot->face;+    FT_Library   library = FT_FACE_LIBRARY( face );+    FT_Renderer  result  = library->cur_renderer;+++    if ( !result || result->glyph_format != slot->format )+      result = FT_Lookup_Renderer( library, slot->format, 0 );++    return result;+  }+++  static void+  ft_set_current_renderer( FT_Library  library )+  {+    FT_Renderer  renderer;+++    renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 );+    library->cur_renderer = renderer;+  }+++  static FT_Error+  ft_add_renderer( FT_Module  module )+  {+    FT_Library   library = module->library;+    FT_Memory    memory  = library->memory;+    FT_Error     error;+    FT_ListNode  node    = NULL;+++    if ( FT_NEW( node ) )+      goto Exit;++    {+      FT_Renderer         render = FT_RENDERER( module );+      FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;+++      render->clazz        = clazz;+      render->glyph_format = clazz->glyph_format;++      /* allocate raster object if needed */+      if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&+           clazz->raster_class->raster_new                )+      {+        error = clazz->raster_class->raster_new( memory, &render->raster );+        if ( error )+          goto Fail;++        render->raster_render = clazz->raster_class->raster_render;+        render->render        = clazz->render_glyph;+      }++      /* add to list */+      node->data = module;+      FT_List_Add( &library->renderers, node );++      ft_set_current_renderer( library );+    }++  Fail:+    if ( error )+      FT_FREE( node );++  Exit:+    return error;+  }+++  static void+  ft_remove_renderer( FT_Module  module )+  {+    FT_Library   library = module->library;+    FT_Memory    memory  = library->memory;+    FT_ListNode  node;+++    node = FT_List_Find( &library->renderers, module );+    if ( node )+    {+      FT_Renderer  render = FT_RENDERER( module );+++      /* release raster object, if any */+      if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&+           render->raster                                         )+        render->clazz->raster_class->raster_done( render->raster );++      /* remove from list */+      FT_List_Remove( &library->renderers, node );+      FT_FREE( node );++      ft_set_current_renderer( library );+    }+  }+++  /* documentation is in ftrender.h */++  FT_EXPORT_DEF( FT_Renderer )+  FT_Get_Renderer( FT_Library       library,+                   FT_Glyph_Format  format )+  {+    /* test for valid `library' delayed to FT_Lookup_Renderer() */++    return FT_Lookup_Renderer( library, format, 0 );+  }+++  /* documentation is in ftrender.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Set_Renderer( FT_Library     library,+                   FT_Renderer    renderer,+                   FT_UInt        num_params,+                   FT_Parameter*  parameters )+  {+    FT_ListNode  node;+    FT_Error     error = FT_Err_Ok;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !renderer )+      return FT_Err_Invalid_Argument;++    node = FT_List_Find( &library->renderers, renderer );+    if ( !node )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    FT_List_Up( &library->renderers, node );++    if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )+      library->cur_renderer = renderer;++    if ( num_params > 0 )+    {+      FT_Renderer_SetModeFunc  set_mode = renderer->clazz->set_mode;+++      for ( ; num_params > 0; num_params-- )+      {+        error = set_mode( renderer, parameters->tag, parameters->data );+        if ( error )+          break;+      }+    }++  Exit:+    return error;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Render_Glyph_Internal( FT_Library      library,+                            FT_GlyphSlot    slot,+                            FT_Render_Mode  render_mode )+  {+    FT_Error     error = FT_Err_Ok;+    FT_Renderer  renderer;+++    /* if it is already a bitmap, no need to do anything */+    switch ( slot->format )+    {+    case FT_GLYPH_FORMAT_BITMAP:   /* already a bitmap, don't do anything */+      break;++    default:+      {+        FT_ListNode  node   = 0;+        FT_Bool      update = 0;+++        /* small shortcut for the very common case */+        if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )+        {+          renderer = library->cur_renderer;+          node     = library->renderers.head;+        }+        else+          renderer = FT_Lookup_Renderer( library, slot->format, &node );++        error = FT_Err_Unimplemented_Feature;+        while ( renderer )+        {+          error = renderer->render( renderer, slot, render_mode, NULL );+          if ( !error                                               ||+               FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )+            break;++          /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */+          /* is unsupported by the current renderer for this glyph image */+          /* format.                                                     */++          /* now, look for another renderer that supports the same */+          /* format.                                               */+          renderer = FT_Lookup_Renderer( library, slot->format, &node );+          update   = 1;+        }++        /* if we changed the current renderer for the glyph image format */+        /* we need to select it as the next current one                  */+        if ( !error && update && renderer )+          FT_Set_Renderer( library, renderer, 0, 0 );+      }+    }++    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Render_Glyph( FT_GlyphSlot    slot,+                   FT_Render_Mode  render_mode )+  {+    FT_Library  library;+++    if ( !slot || !slot->face )+      return FT_Err_Invalid_Argument;++    library = FT_FACE_LIBRARY( slot->face );++    return FT_Render_Glyph_Internal( library, slot, render_mode );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                         M O D U L E S                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Destroy_Module                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroys a given module object.  For drivers, this also destroys   */+  /*    all child faces.                                                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*     module :: A handle to the target driver object.                   */+  /*                                                                       */+  /* <Note>                                                                */+  /*     The driver _must_ be LOCKED!                                      */+  /*                                                                       */+  static void+  Destroy_Module( FT_Module  module )+  {+    FT_Memory         memory  = module->memory;+    FT_Module_Class*  clazz   = module->clazz;+    FT_Library        library = module->library;+++    /* finalize client-data - before anything else */+    if ( module->generic.finalizer )+      module->generic.finalizer( module );++    if ( library && library->auto_hinter == module )+      library->auto_hinter = 0;++    /* if the module is a renderer */+    if ( FT_MODULE_IS_RENDERER( module ) )+      ft_remove_renderer( module );++    /* if the module is a font driver, add some steps */+    if ( FT_MODULE_IS_DRIVER( module ) )+      Destroy_Driver( FT_DRIVER( module ) );++    /* finalize the module object */+    if ( clazz->module_done )+      clazz->module_done( module );++    /* discard it */+    FT_FREE( module );+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Add_Module( FT_Library              library,+                 const FT_Module_Class*  clazz )+  {+    FT_Error   error;+    FT_Memory  memory;+    FT_Module  module;+    FT_UInt    nn;+++#define FREETYPE_VER_FIXED  ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \+                                FREETYPE_MINOR                  )++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !clazz )+      return FT_Err_Invalid_Argument;++    /* check freetype version */+    if ( clazz->module_requires > FREETYPE_VER_FIXED )+      return FT_Err_Invalid_Version;++    /* look for a module with the same name in the library's table */+    for ( nn = 0; nn < library->num_modules; nn++ )+    {+      module = library->modules[nn];+      if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )+      {+        /* this installed module has the same name, compare their versions */+        if ( clazz->module_version <= module->clazz->module_version )+          return FT_Err_Lower_Module_Version;++        /* remove the module from our list, then exit the loop to replace */+        /* it by our new version..                                        */+        FT_Remove_Module( library, module );+        break;+      }+    }++    memory = library->memory;+    error  = FT_Err_Ok;++    if ( library->num_modules >= FT_MAX_MODULES )+    {+      error = FT_Err_Too_Many_Drivers;+      goto Exit;+    }++    /* allocate module object */+    if ( FT_ALLOC( module, clazz->module_size ) )+      goto Exit;++    /* base initialization */+    module->library = library;+    module->memory  = memory;+    module->clazz   = (FT_Module_Class*)clazz;++    /* check whether the module is a renderer - this must be performed */+    /* before the normal module initialization                         */+    if ( FT_MODULE_IS_RENDERER( module ) )+    {+      /* add to the renderers list */+      error = ft_add_renderer( module );+      if ( error )+        goto Fail;+    }++    /* is the module a auto-hinter? */+    if ( FT_MODULE_IS_HINTER( module ) )+      library->auto_hinter = module;++    /* if the module is a font driver */+    if ( FT_MODULE_IS_DRIVER( module ) )+    {+      /* allocate glyph loader if needed */+      FT_Driver  driver = FT_DRIVER( module );+++      driver->clazz = (FT_Driver_Class)module->clazz;+      if ( FT_DRIVER_USES_OUTLINES( driver ) )+      {+        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );+        if ( error )+          goto Fail;+      }+    }++    if ( clazz->module_init )+    {+      error = clazz->module_init( module );+      if ( error )+        goto Fail;+    }++    /* add module to the library's table */+    library->modules[library->num_modules++] = module;++  Exit:+    return error;++  Fail:+    if ( FT_MODULE_IS_DRIVER( module ) )+    {+      FT_Driver  driver = FT_DRIVER( module );+++      if ( FT_DRIVER_USES_OUTLINES( driver ) )+        FT_GlyphLoader_Done( driver->glyph_loader );+    }++    if ( FT_MODULE_IS_RENDERER( module ) )+    {+      FT_Renderer  renderer = FT_RENDERER( module );+++      if ( renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && +           renderer->raster                                         )+        renderer->clazz->raster_class->raster_done( renderer->raster );+    }++    FT_FREE( module );+    goto Exit;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Module )+  FT_Get_Module( FT_Library   library,+                 const char*  module_name )+  {+    FT_Module   result = 0;+    FT_Module*  cur;+    FT_Module*  limit;+++    if ( !library || !module_name )+      return result;++    cur   = library->modules;+    limit = cur + library->num_modules;++    for ( ; cur < limit; cur++ )+      if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )+      {+        result = cur[0];+        break;+      }++    return result;+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( const void* )+  FT_Get_Module_Interface( FT_Library   library,+                           const char*  mod_name )+  {+    FT_Module  module;+++    /* test for valid `library' delayed to FT_Get_Module() */++    module = FT_Get_Module( library, mod_name );++    return module ? module->clazz->module_interface : 0;+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_module_get_service( FT_Module    module,+                         const char*  service_id )+  {+    FT_Pointer  result = NULL;++    if ( module )+    {+      FT_ASSERT( module->clazz && module->clazz->get_interface );++     /* first, look for the service in the module+      */+      if ( module->clazz->get_interface )+        result = module->clazz->get_interface( module, service_id );++      if ( result == NULL )+      {+       /* we didn't find it, look in all other modules then+        */+        FT_Library  library = module->library;+        FT_Module*  cur     = library->modules;+        FT_Module*  limit   = cur + library->num_modules;++        for ( ; cur < limit; cur++ )+        {+          if ( cur[0] != module )+          {+            FT_ASSERT( cur[0]->clazz );++            if ( cur[0]->clazz->get_interface )+            {+              result = cur[0]->clazz->get_interface( cur[0], service_id );+              if ( result != NULL )+                break;+            }+          }+        }+      }+    }++    return result;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Remove_Module( FT_Library  library,+                    FT_Module   module )+  {+    /* try to find the module from the table, then remove it from there */++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( module )+    {+      FT_Module*  cur   = library->modules;+      FT_Module*  limit = cur + library->num_modules;+++      for ( ; cur < limit; cur++ )+      {+        if ( cur[0] == module )+        {+          /* remove it from the table */+          library->num_modules--;+          limit--;+          while ( cur < limit )+          {+            cur[0] = cur[1];+            cur++;+          }+          limit[0] = 0;++          /* destroy the module */+          Destroy_Module( module );++          return FT_Err_Ok;+        }+      }+    }+    return FT_Err_Invalid_Driver_Handle;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                         L I B R A R Y                           ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Reference_Library( FT_Library  library )+  {+    library->refcount++;++    return FT_Err_Ok;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Error )+  FT_New_Library( FT_Memory    memory,+                  FT_Library  *alibrary )+  {+    FT_Library  library = NULL;+    FT_Error    error;+++    if ( !memory )+      return FT_Err_Invalid_Argument;++#ifdef FT_DEBUG_LEVEL_ERROR+    /* init debugging support */+    ft_debug_init();+#endif++    /* first of all, allocate the library object */+    if ( FT_NEW( library ) )+      return error;++    library->memory = memory;++#ifdef FT_CONFIG_OPTION_PIC+    /* initialize position independent code containers */+    error = ft_pic_container_init( library );+    if ( error )+      goto Fail;+#endif++    /* allocate the render pool */+    library->raster_pool_size = FT_RENDER_POOL_SIZE;+#if FT_RENDER_POOL_SIZE > 0+    if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )+      goto Fail;+#endif++    library->version_major = FREETYPE_MAJOR;+    library->version_minor = FREETYPE_MINOR;+    library->version_patch = FREETYPE_PATCH;++    library->refcount = 1;++    /* That's ok now */+    *alibrary = library;++    return FT_Err_Ok;++  Fail:+#ifdef FT_CONFIG_OPTION_PIC+    ft_pic_container_destroy( library );+#endif+    FT_FREE( library );+    return error;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( void )+  FT_Library_Version( FT_Library   library,+                      FT_Int      *amajor,+                      FT_Int      *aminor,+                      FT_Int      *apatch )+  {+    FT_Int  major = 0;+    FT_Int  minor = 0;+    FT_Int  patch = 0;+++    if ( library )+    {+      major = library->version_major;+      minor = library->version_minor;+      patch = library->version_patch;+    }++    if ( amajor )+      *amajor = major;++    if ( aminor )+      *aminor = minor;++    if ( apatch )+      *apatch = patch;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Done_Library( FT_Library  library )+  {+    FT_Memory  memory;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    library->refcount--;+    if ( library->refcount > 0 )+      goto Exit;++    memory = library->memory;++    /* Discard client-data */+    if ( library->generic.finalizer )+      library->generic.finalizer( library );++    /*+     * Close all faces in the library.  If we don't do this, we can have+     * some subtle memory leaks.+     *+     * Example:+     *+     *  - the cff font driver uses the pshinter module in cff_size_done+     *  - if the pshinter module is destroyed before the cff font driver,+     *    opened FT_Face objects managed by the driver are not properly+     *    destroyed, resulting in a memory leak+     *+     * Some faces are dependent on other faces, like Type42 faces that+     * depend on TrueType faces synthesized internally.+     *+     * The order of drivers should be specified in driver_name[].+     */+    {+      FT_UInt      m, n;+      const char*  driver_name[] = { "type42", NULL };+++      for ( m = 0;+            m < sizeof ( driver_name ) / sizeof ( driver_name[0] );+            m++ )+      {+        for ( n = 0; n < library->num_modules; n++ )+        {+          FT_Module    module      = library->modules[n];+          const char*  module_name = module->clazz->module_name;+          FT_List      faces;+++          if ( driver_name[m]                                &&+               ft_strcmp( module_name, driver_name[m] ) != 0 )+            continue;++          if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )+            continue;++          FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));++          faces = &FT_DRIVER( module )->faces_list;+          while ( faces->head )+          {+            FT_Done_Face( FT_FACE( faces->head->data ) );+            if ( faces->head )+              FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));+          }+        }+      }+    }++    /* Close all other modules in the library */+#if 1+    /* XXX Modules are removed in the reversed order so that  */+    /* type42 module is removed before truetype module.  This */+    /* avoids double free in some occasions.  It is a hack.   */+    while ( library->num_modules > 0 )+      FT_Remove_Module( library,+                        library->modules[library->num_modules - 1] );+#else+    {+      FT_UInt  n;+++      for ( n = 0; n < library->num_modules; n++ )+      {+        FT_Module  module = library->modules[n];+++        if ( module )+        {+          Destroy_Module( module );+          library->modules[n] = 0;+        }+      }+    }+#endif++    /* Destroy raster objects */+    FT_FREE( library->raster_pool );+    library->raster_pool_size = 0;++#ifdef FT_CONFIG_OPTION_PIC+    /* Destroy pic container contents */+    ft_pic_container_destroy( library );+#endif++    FT_FREE( library );++  Exit:+    return FT_Err_Ok;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( void )+  FT_Set_Debug_Hook( FT_Library         library,+                     FT_UInt            hook_index,+                     FT_DebugHook_Func  debug_hook )+  {+    if ( library && debug_hook &&+         hook_index <+           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )+      library->debug_hooks[hook_index] = debug_hook;+  }+++  /* documentation is in ftmodapi.h */++  FT_EXPORT_DEF( FT_TrueTypeEngineType )+  FT_Get_TrueType_Engine_Type( FT_Library  library )+  {+    FT_TrueTypeEngineType  result = FT_TRUETYPE_ENGINE_TYPE_NONE;+++    if ( library )+    {+      FT_Module  module = FT_Get_Module( library, "truetype" );+++      if ( module )+      {+        FT_Service_TrueTypeEngine  service;+++        service = (FT_Service_TrueTypeEngine)+                    ft_module_get_service( module,+                                           FT_SERVICE_ID_TRUETYPE_ENGINE );+        if ( service )+          result = service->engine_type;+      }+    }++    return result;+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_BASE_DEF( FT_Error )+  ft_stub_set_char_sizes( FT_Size     size,+                          FT_F26Dot6  width,+                          FT_F26Dot6  height,+                          FT_UInt     horz_res,+                          FT_UInt     vert_res )+  {+    FT_Size_RequestRec  req;+    FT_Driver           driver = size->face->driver;+++    if ( driver->clazz->request_size )+    {+      req.type   = FT_SIZE_REQUEST_TYPE_NOMINAL;+      req.width  = width;+      req.height = height;++      if ( horz_res == 0 )+        horz_res = vert_res;++      if ( vert_res == 0 )+        vert_res = horz_res;++      if ( horz_res == 0 )+        horz_res = vert_res = 72;++      req.horiResolution = horz_res;+      req.vertResolution = vert_res;++      return driver->clazz->request_size( size, &req );+    }++    return 0;+  }+++  FT_BASE_DEF( FT_Error )+  ft_stub_set_pixel_sizes( FT_Size  size,+                           FT_UInt  width,+                           FT_UInt  height )+  {+    FT_Size_RequestRec  req;+    FT_Driver           driver = size->face->driver;+++    if ( driver->clazz->request_size )+    {+      req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;+      req.width          = width  << 6;+      req.height         = height << 6;+      req.horiResolution = 0;+      req.vertResolution = 0;++      return driver->clazz->request_size( size, &req );+    }++    return 0;+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,+                        FT_UInt       sub_index,+                        FT_Int       *p_index,+                        FT_UInt      *p_flags,+                        FT_Int       *p_arg1,+                        FT_Int       *p_arg2,+                        FT_Matrix    *p_transform )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+++    if ( glyph                                      &&+         glyph->subglyphs                           &&+         glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&+         sub_index < glyph->num_subglyphs           )+    {+      FT_SubGlyph  subg = glyph->subglyphs + sub_index;+++      *p_index     = subg->index;+      *p_flags     = subg->flags;+      *p_arg1      = subg->arg1;+      *p_arg2      = subg->arg2;+      *p_transform = subg->transform;+    }++    return error;+  }+++/* END */
+ src/base/ftotval.c view
@@ -0,0 +1,89 @@+/***************************************************************************/+/*                                                                         */+/*  ftotval.c                                                              */+/*                                                                         */+/*    FreeType API for validating OpenType tables (body).                  */+/*                                                                         */+/*  Copyright 2004, 2006, 2008, 2010 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_OPENTYPE_VALIDATE_H+#include FT_OPENTYPE_VALIDATE_H+++  /* documentation is in ftotval.h */++  FT_EXPORT_DEF( FT_Error )+  FT_OpenType_Validate( FT_Face    face,+                        FT_UInt    validation_flags,+                        FT_Bytes  *BASE_table,+                        FT_Bytes  *GDEF_table,+                        FT_Bytes  *GPOS_table,+                        FT_Bytes  *GSUB_table,+                        FT_Bytes  *JSTF_table )+  {+    FT_Service_OTvalidate  service;+    FT_Error               error;+++    if ( !face )+    {+      error = FT_Err_Invalid_Face_Handle;+      goto Exit;+    }++    if ( !( BASE_table &&+            GDEF_table &&+            GPOS_table &&+            GSUB_table &&+            JSTF_table ) )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE );++    if ( service )+      error = service->validate( face,+                                 validation_flags,+                                 BASE_table,+                                 GDEF_table,+                                 GPOS_table,+                                 GSUB_table,+                                 JSTF_table );+    else+      error = FT_Err_Unimplemented_Feature;++  Exit:+    return error;+  }+++  FT_EXPORT_DEF( void )+  FT_OpenType_Free( FT_Face   face,+                    FT_Bytes  table )+  {+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );++    FT_FREE( table );+  }+++/* END */
+ src/base/ftoutln.c view
@@ -0,0 +1,1129 @@+/***************************************************************************/+/*                                                                         */+/*  ftoutln.c                                                              */+/*                                                                         */+/*    FreeType outline management (body).                                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* All functions are declared in freetype.h.                             */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_OUTLINE_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_TRIGONOMETRY_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_outline+++  static+  const FT_Outline  null_outline = { 0, 0, 0, 0, 0, 0 };+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Decompose( FT_Outline*              outline,+                        const FT_Outline_Funcs*  func_interface,+                        void*                    user )+  {+#undef SCALED+#define SCALED( x )  ( ( (x) << shift ) - delta )++    FT_Vector   v_last;+    FT_Vector   v_control;+    FT_Vector   v_start;++    FT_Vector*  point;+    FT_Vector*  limit;+    char*       tags;++    FT_Error    error;++    FT_Int   n;         /* index of contour in outline     */+    FT_UInt  first;     /* index of first point in contour */+    FT_Int   tag;       /* current point's state           */++    FT_Int   shift;+    FT_Pos   delta;+++    if ( !outline || !func_interface )+      return FT_Err_Invalid_Argument;++    shift = func_interface->shift;+    delta = func_interface->delta;+    first = 0;++    for ( n = 0; n < outline->n_contours; n++ )+    {+      FT_Int  last;  /* index of last point in contour */+++      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));++      last = outline->contours[n];+      if ( last < 0 )+        goto Invalid_Outline;+      limit = outline->points + last;++      v_start   = outline->points[first];+      v_start.x = SCALED( v_start.x );+      v_start.y = SCALED( v_start.y );++      v_last   = outline->points[last];+      v_last.x = SCALED( v_last.x );+      v_last.y = SCALED( v_last.y );++      v_control = v_start;++      point = outline->points + first;+      tags  = outline->tags   + first;+      tag   = FT_CURVE_TAG( tags[0] );++      /* A contour cannot start with a cubic control point! */+      if ( tag == FT_CURVE_TAG_CUBIC )+        goto Invalid_Outline;++      /* check first point to determine origin */+      if ( tag == FT_CURVE_TAG_CONIC )+      {+        /* first point is conic control.  Yes, this happens. */+        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )+        {+          /* start at last point if it is on the curve */+          v_start = v_last;+          limit--;+        }+        else+        {+          /* if both first and last points are conic,         */+          /* start at their middle and record its position    */+          /* for closure                                      */+          v_start.x = ( v_start.x + v_last.x ) / 2;+          v_start.y = ( v_start.y + v_last.y ) / 2;++          v_last = v_start;+        }+        point--;+        tags--;+      }++      FT_TRACE5(( "  move to (%.2f, %.2f)\n",+                  v_start.x / 64.0, v_start.y / 64.0 ));+      error = func_interface->move_to( &v_start, user );+      if ( error )+        goto Exit;++      while ( point < limit )+      {+        point++;+        tags++;++        tag = FT_CURVE_TAG( tags[0] );+        switch ( tag )+        {+        case FT_CURVE_TAG_ON:  /* emit a single line_to */+          {+            FT_Vector  vec;+++            vec.x = SCALED( point->x );+            vec.y = SCALED( point->y );++            FT_TRACE5(( "  line to (%.2f, %.2f)\n",+                        vec.x / 64.0, vec.y / 64.0 ));+            error = func_interface->line_to( &vec, user );+            if ( error )+              goto Exit;+            continue;+          }++        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */+          v_control.x = SCALED( point->x );+          v_control.y = SCALED( point->y );++        Do_Conic:+          if ( point < limit )+          {+            FT_Vector  vec;+            FT_Vector  v_middle;+++            point++;+            tags++;+            tag = FT_CURVE_TAG( tags[0] );++            vec.x = SCALED( point->x );+            vec.y = SCALED( point->y );++            if ( tag == FT_CURVE_TAG_ON )+            {+              FT_TRACE5(( "  conic to (%.2f, %.2f)"+                          " with control (%.2f, %.2f)\n",+                          vec.x / 64.0, vec.y / 64.0,+                          v_control.x / 64.0, v_control.y / 64.0 ));+              error = func_interface->conic_to( &v_control, &vec, user );+              if ( error )+                goto Exit;+              continue;+            }++            if ( tag != FT_CURVE_TAG_CONIC )+              goto Invalid_Outline;++            v_middle.x = ( v_control.x + vec.x ) / 2;+            v_middle.y = ( v_control.y + vec.y ) / 2;++            FT_TRACE5(( "  conic to (%.2f, %.2f)"+                        " with control (%.2f, %.2f)\n",+                        v_middle.x / 64.0, v_middle.y / 64.0,+                        v_control.x / 64.0, v_control.y / 64.0 ));+            error = func_interface->conic_to( &v_control, &v_middle, user );+            if ( error )+              goto Exit;++            v_control = vec;+            goto Do_Conic;+          }++          FT_TRACE5(( "  conic to (%.2f, %.2f)"+                      " with control (%.2f, %.2f)\n",+                      v_start.x / 64.0, v_start.y / 64.0,+                      v_control.x / 64.0, v_control.y / 64.0 ));+          error = func_interface->conic_to( &v_control, &v_start, user );+          goto Close;++        default:  /* FT_CURVE_TAG_CUBIC */+          {+            FT_Vector  vec1, vec2;+++            if ( point + 1 > limit                             ||+                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )+              goto Invalid_Outline;++            point += 2;+            tags  += 2;++            vec1.x = SCALED( point[-2].x );+            vec1.y = SCALED( point[-2].y );++            vec2.x = SCALED( point[-1].x );+            vec2.y = SCALED( point[-1].y );++            if ( point <= limit )+            {+              FT_Vector  vec;+++              vec.x = SCALED( point->x );+              vec.y = SCALED( point->y );++              FT_TRACE5(( "  cubic to (%.2f, %.2f)"+                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",+                          vec.x / 64.0, vec.y / 64.0,+                          vec1.x / 64.0, vec1.y / 64.0,+                          vec2.x / 64.0, vec2.y / 64.0 ));+              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );+              if ( error )+                goto Exit;+              continue;+            }++            FT_TRACE5(( "  cubic to (%.2f, %.2f)"+                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",+                        v_start.x / 64.0, v_start.y / 64.0,+                        vec1.x / 64.0, vec1.y / 64.0,+                        vec2.x / 64.0, vec2.y / 64.0 ));+            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );+            goto Close;+          }+        }+      }++      /* close the contour with a line segment */+      FT_TRACE5(( "  line to (%.2f, %.2f)\n",+                  v_start.x / 64.0, v_start.y / 64.0 ));+      error = func_interface->line_to( &v_start, user );++    Close:+      if ( error )+        goto Exit;++      first = last + 1;+    }++    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));+    return FT_Err_Ok;++  Exit:+    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));+    return error;++  Invalid_Outline:+    return FT_Err_Invalid_Outline;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_New_Internal( FT_Memory    memory,+                           FT_UInt      numPoints,+                           FT_Int       numContours,+                           FT_Outline  *anoutline )+  {+    FT_Error  error;+++    if ( !anoutline || !memory )+      return FT_Err_Invalid_Argument;++    *anoutline = null_outline;++    if ( FT_NEW_ARRAY( anoutline->points,   numPoints   ) ||+         FT_NEW_ARRAY( anoutline->tags,     numPoints   ) ||+         FT_NEW_ARRAY( anoutline->contours, numContours ) )+      goto Fail;++    anoutline->n_points    = (FT_UShort)numPoints;+    anoutline->n_contours  = (FT_Short)numContours;+    anoutline->flags      |= FT_OUTLINE_OWNER;++    return FT_Err_Ok;++  Fail:+    anoutline->flags |= FT_OUTLINE_OWNER;+    FT_Outline_Done_Internal( memory, anoutline );++    return error;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_New( FT_Library   library,+                  FT_UInt      numPoints,+                  FT_Int       numContours,+                  FT_Outline  *anoutline )+  {+    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    return FT_Outline_New_Internal( library->memory, numPoints,+                                    numContours, anoutline );+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Check( FT_Outline*  outline )+  {+    if ( outline )+    {+      FT_Int  n_points   = outline->n_points;+      FT_Int  n_contours = outline->n_contours;+      FT_Int  end0, end;+      FT_Int  n;+++      /* empty glyph? */+      if ( n_points == 0 && n_contours == 0 )+        return 0;++      /* check point and contour counts */+      if ( n_points <= 0 || n_contours <= 0 )+        goto Bad;++      end0 = end = -1;+      for ( n = 0; n < n_contours; n++ )+      {+        end = outline->contours[n];++        /* note that we don't accept empty contours */+        if ( end <= end0 || end >= n_points )+          goto Bad;++        end0 = end;+      }++      if ( end != n_points - 1 )+        goto Bad;++      /* XXX: check the tags array */+      return 0;+    }++  Bad:+    return FT_Err_Invalid_Argument;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Copy( const FT_Outline*  source,+                   FT_Outline        *target )+  {+    FT_Int  is_owner;+++    if ( !source            || !target            ||+         source->n_points   != target->n_points   ||+         source->n_contours != target->n_contours )+      return FT_Err_Invalid_Argument;++    if ( source == target )+      return FT_Err_Ok;++    FT_ARRAY_COPY( target->points, source->points, source->n_points );++    FT_ARRAY_COPY( target->tags, source->tags, source->n_points );++    FT_ARRAY_COPY( target->contours, source->contours, source->n_contours );++    /* copy all flags, except the `FT_OUTLINE_OWNER' one */+    is_owner      = target->flags & FT_OUTLINE_OWNER;+    target->flags = source->flags;++    target->flags &= ~FT_OUTLINE_OWNER;+    target->flags |= is_owner;++    return FT_Err_Ok;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Done_Internal( FT_Memory    memory,+                            FT_Outline*  outline )+  {+    if ( memory && outline )+    {+      if ( outline->flags & FT_OUTLINE_OWNER )+      {+        FT_FREE( outline->points   );+        FT_FREE( outline->tags     );+        FT_FREE( outline->contours );+      }+      *outline = null_outline;++      return FT_Err_Ok;+    }+    else+      return FT_Err_Invalid_Argument;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Done( FT_Library   library,+                   FT_Outline*  outline )+  {+    /* check for valid `outline' in FT_Outline_Done_Internal() */++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    return FT_Outline_Done_Internal( library->memory, outline );+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( void )+  FT_Outline_Get_CBox( const FT_Outline*  outline,+                       FT_BBox           *acbox )+  {+    FT_Pos  xMin, yMin, xMax, yMax;+++    if ( outline && acbox )+    {+      if ( outline->n_points == 0 )+      {+        xMin = 0;+        yMin = 0;+        xMax = 0;+        yMax = 0;+      }+      else+      {+        FT_Vector*  vec   = outline->points;+        FT_Vector*  limit = vec + outline->n_points;+++        xMin = xMax = vec->x;+        yMin = yMax = vec->y;+        vec++;++        for ( ; vec < limit; vec++ )+        {+          FT_Pos  x, y;+++          x = vec->x;+          if ( x < xMin ) xMin = x;+          if ( x > xMax ) xMax = x;++          y = vec->y;+          if ( y < yMin ) yMin = y;+          if ( y > yMax ) yMax = y;+        }+      }+      acbox->xMin = xMin;+      acbox->xMax = xMax;+      acbox->yMin = yMin;+      acbox->yMax = yMax;+    }+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( void )+  FT_Outline_Translate( const FT_Outline*  outline,+                        FT_Pos             xOffset,+                        FT_Pos             yOffset )+  {+    FT_UShort   n;+    FT_Vector*  vec;+++    if ( !outline )+      return;++    vec = outline->points;++    for ( n = 0; n < outline->n_points; n++ )+    {+      vec->x += xOffset;+      vec->y += yOffset;+      vec++;+    }+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( void )+  FT_Outline_Reverse( FT_Outline*  outline )+  {+    FT_UShort  n;+    FT_Int     first, last;+++    if ( !outline )+      return;++    first = 0;++    for ( n = 0; n < outline->n_contours; n++ )+    {+      last  = outline->contours[n];++      /* reverse point table */+      {+        FT_Vector*  p = outline->points + first;+        FT_Vector*  q = outline->points + last;+        FT_Vector   swap;+++        while ( p < q )+        {+          swap = *p;+          *p   = *q;+          *q   = swap;+          p++;+          q--;+        }+      }++      /* reverse tags table */+      {+        char*  p = outline->tags + first;+        char*  q = outline->tags + last;+        char   swap;+++        while ( p < q )+        {+          swap = *p;+          *p   = *q;+          *q   = swap;+          p++;+          q--;+        }+      }++      first = last + 1;+    }++    outline->flags ^= FT_OUTLINE_REVERSE_FILL;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Render( FT_Library         library,+                     FT_Outline*        outline,+                     FT_Raster_Params*  params )+  {+    FT_Error     error;+    FT_Bool      update = FALSE;+    FT_Renderer  renderer;+    FT_ListNode  node;+++    if ( !library )+      return FT_Err_Invalid_Library_Handle;++    if ( !outline || !params )+      return FT_Err_Invalid_Argument;++    renderer = library->cur_renderer;+    node     = library->renderers.head;++    params->source = (void*)outline;++    error = FT_Err_Cannot_Render_Glyph;+    while ( renderer )+    {+      error = renderer->raster_render( renderer->raster, params );+      if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )+        break;++      /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */+      /* is unsupported by the current renderer for this glyph image */+      /* format                                                      */++      /* now, look for another renderer that supports the same */+      /* format                                                */+      renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE,+                                     &node );+      update   = TRUE;+    }++    /* if we changed the current renderer for the glyph image format */+    /* we need to select it as the next current one                  */+    if ( !error && update && renderer )+      FT_Set_Renderer( library, renderer, 0, 0 );++    return error;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Get_Bitmap( FT_Library        library,+                         FT_Outline*       outline,+                         const FT_Bitmap  *abitmap )+  {+    FT_Raster_Params  params;+++    if ( !abitmap )+      return FT_Err_Invalid_Argument;++    /* other checks are delayed to FT_Outline_Render() */++    params.target = abitmap;+    params.flags  = 0;++    if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY  ||+         abitmap->pixel_mode == FT_PIXEL_MODE_LCD   ||+         abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )+      params.flags |= FT_RASTER_FLAG_AA;++    return FT_Outline_Render( library, outline, &params );+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( void )+  FT_Vector_Transform( FT_Vector*        vector,+                       const FT_Matrix*  matrix )+  {+    FT_Pos  xz, yz;+++    if ( !vector || !matrix )+      return;++    xz = FT_MulFix( vector->x, matrix->xx ) ++         FT_MulFix( vector->y, matrix->xy );++    yz = FT_MulFix( vector->x, matrix->yx ) ++         FT_MulFix( vector->y, matrix->yy );++    vector->x = xz;+    vector->y = yz;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( void )+  FT_Outline_Transform( const FT_Outline*  outline,+                        const FT_Matrix*   matrix )+  {+    FT_Vector*  vec;+    FT_Vector*  limit;+++    if ( !outline || !matrix )+      return;++    vec   = outline->points;+    limit = vec + outline->n_points;++    for ( ; vec < limit; vec++ )+      FT_Vector_Transform( vec, matrix );+  }+++#if 0++#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last )  \+  do {                                                     \+    (first) = ( c > 0 ) ? (outline)->points +              \+                            (outline)->contours[c - 1] + 1 \+                        : (outline)->points;               \+    (last) = (outline)->points + (outline)->contours[c];   \+  } while ( 0 )+++  /* Is a point in some contour?                     */+  /*                                                 */+  /* We treat every point of the contour as if it    */+  /* it were ON.  That is, we allow false positives, */+  /* but disallow false negatives.  (XXX really?)    */+  static FT_Bool+  ft_contour_has( FT_Outline*  outline,+                  FT_Short     c,+                  FT_Vector*   point )+  {+    FT_Vector*  first;+    FT_Vector*  last;+    FT_Vector*  a;+    FT_Vector*  b;+    FT_UInt     n = 0;+++    FT_OUTLINE_GET_CONTOUR( outline, c, first, last );++    for ( a = first; a <= last; a++ )+    {+      FT_Pos  x;+      FT_Int  intersect;+++      b = ( a == last ) ? first : a + 1;++      intersect = ( a->y - point->y ) ^ ( b->y - point->y );++      /* a and b are on the same side */+      if ( intersect >= 0 )+      {+        if ( intersect == 0 && a->y == point->y )+        {+          if ( ( a->x <= point->x && b->x >= point->x ) ||+               ( a->x >= point->x && b->x <= point->x ) )+            return 1;+        }++        continue;+      }++      x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y );++      if ( x < point->x )+        n++;+      else if ( x == point->x )+        return 1;+    }++    return ( n % 2 );+  }+++  static FT_Bool+  ft_contour_enclosed( FT_Outline*  outline,+                       FT_UShort    c )+  {+    FT_Vector*  first;+    FT_Vector*  last;+    FT_Short    i;+++    FT_OUTLINE_GET_CONTOUR( outline, c, first, last );++    for ( i = 0; i < outline->n_contours; i++ )+    {+      if ( i != c && ft_contour_has( outline, i, first ) )+      {+        FT_Vector*  pt;+++        for ( pt = first + 1; pt <= last; pt++ )+          if ( !ft_contour_has( outline, i, pt ) )+            return 0;++        return 1;+      }+    }++    return 0;+  }+++  /* This version differs from the public one in that each */+  /* part (contour not enclosed in another contour) of the */+  /* outline is checked for orientation.  This is          */+  /* necessary for some buggy CJK fonts.                   */+  static FT_Orientation+  ft_outline_get_orientation( FT_Outline*  outline )+  {+    FT_Short        i;+    FT_Vector*      first;+    FT_Vector*      last;+    FT_Orientation  orient = FT_ORIENTATION_NONE;+++    first = outline->points;+    for ( i = 0; i < outline->n_contours; i++, first = last + 1 )+    {+      FT_Vector*  point;+      FT_Vector*  xmin_point;+      FT_Pos      xmin;+++      last = outline->points + outline->contours[i];++      /* skip degenerate contours */+      if ( last < first + 2 )+        continue;++      if ( ft_contour_enclosed( outline, i ) )+        continue;++      xmin       = first->x;+      xmin_point = first;++      for ( point = first + 1; point <= last; point++ )+      {+        if ( point->x < xmin )+        {+          xmin       = point->x;+          xmin_point = point;+        }+      }++      /* check the orientation of the contour */+      {+        FT_Vector*      prev;+        FT_Vector*      next;+        FT_Orientation  o;+++        prev = ( xmin_point == first ) ? last : xmin_point - 1;+        next = ( xmin_point == last ) ? first : xmin_point + 1;++        if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >+             FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )+          o = FT_ORIENTATION_POSTSCRIPT;+        else+          o = FT_ORIENTATION_TRUETYPE;++        if ( orient == FT_ORIENTATION_NONE )+          orient = o;+        else if ( orient != o )+          return FT_ORIENTATION_NONE;+      }+    }++    return orient;+  }++#endif /* 0 */+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Outline_Embolden( FT_Outline*  outline,+                       FT_Pos       strength )+  {+    FT_Vector*  points;+    FT_Vector   v_prev, v_first, v_next, v_cur;+    FT_Angle    rotate, angle_in, angle_out;+    FT_Int      c, n, first;+    FT_Int      orientation;+++    if ( !outline )+      return FT_Err_Invalid_Argument;++    strength /= 2;+    if ( strength == 0 )+      return FT_Err_Ok;++    orientation = FT_Outline_Get_Orientation( outline );+    if ( orientation == FT_ORIENTATION_NONE )+    {+      if ( outline->n_contours )+        return FT_Err_Invalid_Argument;+      else+        return FT_Err_Ok;+    }++    if ( orientation == FT_ORIENTATION_TRUETYPE )+      rotate = -FT_ANGLE_PI2;+    else+      rotate = FT_ANGLE_PI2;++    points = outline->points;++    first = 0;+    for ( c = 0; c < outline->n_contours; c++ )+    {+      int  last = outline->contours[c];+++      v_first = points[first];+      v_prev  = points[last];+      v_cur   = v_first;++      for ( n = first; n <= last; n++ )+      {+        FT_Vector  in, out;+        FT_Angle   angle_diff;+        FT_Pos     d;+        FT_Fixed   scale;+++        if ( n < last )+          v_next = points[n + 1];+        else+          v_next = v_first;++        /* compute the in and out vectors */+        in.x = v_cur.x - v_prev.x;+        in.y = v_cur.y - v_prev.y;++        out.x = v_next.x - v_cur.x;+        out.y = v_next.y - v_cur.y;++        angle_in   = FT_Atan2( in.x, in.y );+        angle_out  = FT_Atan2( out.x, out.y );+        angle_diff = FT_Angle_Diff( angle_in, angle_out );+        scale      = FT_Cos( angle_diff / 2 );++        if ( scale < 0x4000L && scale > -0x4000L )+          in.x = in.y = 0;+        else+        {+          d = FT_DivFix( strength, scale );++          FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );+        }++        outline->points[n].x = v_cur.x + strength + in.x;+        outline->points[n].y = v_cur.y + strength + in.y;++        v_prev = v_cur;+        v_cur  = v_next;+      }++      first = last + 1;+    }++    return FT_Err_Ok;+  }+++  /* documentation is in ftoutln.h */++  FT_EXPORT_DEF( FT_Orientation )+  FT_Outline_Get_Orientation( FT_Outline*  outline )+  {+    FT_Pos      xmin       = 32768L;+    FT_Pos      xmin_ymin  = 32768L;+    FT_Pos      xmin_ymax  = -32768L;+    FT_Vector*  xmin_first = NULL;+    FT_Vector*  xmin_last  = NULL;++    short*      contour;++    FT_Vector*  first;+    FT_Vector*  last;+    FT_Vector*  prev;+    FT_Vector*  point;++    int             i;+    FT_Pos          ray_y[3];+    FT_Orientation  result[3] =+      { FT_ORIENTATION_NONE, FT_ORIENTATION_NONE, FT_ORIENTATION_NONE };+++    if ( !outline || outline->n_points <= 0 )+      return FT_ORIENTATION_TRUETYPE;++    /* We use the nonzero winding rule to find the orientation.       */+    /* Since glyph outlines behave much more `regular' than arbitrary */+    /* cubic or quadratic curves, this test deals with the polygon    */+    /* only which is spanned up by the control points.                */++    first = outline->points;+    for ( contour = outline->contours;+          contour < outline->contours + outline->n_contours;+          contour++, first = last + 1 )+    {+      FT_Pos  contour_xmin = 32768L;+      FT_Pos  contour_xmax = -32768L;+      FT_Pos  contour_ymin = 32768L;+      FT_Pos  contour_ymax = -32768L;+++      last = outline->points + *contour;++      /* skip degenerate contours */+      if ( last < first + 2 )+        continue;++      for ( point = first; point <= last; ++point )+      {+        if ( point->x < contour_xmin )+          contour_xmin = point->x;++        if ( point->x > contour_xmax )+          contour_xmax = point->x;++        if ( point->y < contour_ymin )+          contour_ymin = point->y;++        if ( point->y > contour_ymax )+          contour_ymax = point->y;+      }++      if ( contour_xmin < xmin          &&+           contour_xmin != contour_xmax &&+           contour_ymin != contour_ymax )+      {+        xmin       = contour_xmin;+        xmin_ymin  = contour_ymin;+        xmin_ymax  = contour_ymax;+        xmin_first = first;+        xmin_last  = last;+      }+    }++    if ( xmin == 32768L )+      return FT_ORIENTATION_TRUETYPE;++    ray_y[0] = ( xmin_ymin * 3 + xmin_ymax     ) >> 2;+    ray_y[1] = ( xmin_ymin     + xmin_ymax     ) >> 1;+    ray_y[2] = ( xmin_ymin     + xmin_ymax * 3 ) >> 2;++    for ( i = 0; i < 3; i++ )+    {+      FT_Pos      left_x;+      FT_Pos      right_x;+      FT_Vector*  left1;+      FT_Vector*  left2;+      FT_Vector*  right1;+      FT_Vector*  right2;+++    RedoRay:+      left_x  = 32768L;+      right_x = -32768L;++      left1 = left2 = right1 = right2 = NULL;++      prev = xmin_last;+      for ( point = xmin_first; point <= xmin_last; prev = point, ++point )+      {+        FT_Pos  tmp_x;+++        if ( point->y == ray_y[i] || prev->y == ray_y[i] )+        {+          ray_y[i]++;+          goto RedoRay;+        }++        if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) ||+             ( point->y > ray_y[i] && prev->y > ray_y[i] ) )+          continue;++        tmp_x = FT_MulDiv( point->x - prev->x,+                           ray_y[i] - prev->y,+                           point->y - prev->y ) + prev->x;++        if ( tmp_x < left_x )+        {+          left_x = tmp_x;+          left1  = prev;+          left2  = point;+        }++        if ( tmp_x > right_x )+        {+          right_x = tmp_x;+          right1  = prev;+          right2  = point;+        }+      }++      if ( left1 && right1 )+      {+        if ( left1->y < left2->y && right1->y > right2->y )+          result[i] = FT_ORIENTATION_TRUETYPE;+        else if ( left1->y > left2->y && right1->y < right2->y )+          result[i] = FT_ORIENTATION_POSTSCRIPT;+        else+          result[i] = FT_ORIENTATION_NONE;+      }+    }++    if ( result[0] != FT_ORIENTATION_NONE                     &&+         ( result[0] == result[1] || result[0] == result[2] ) )+      return result[0];++    if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] )+      return result[1];++    return FT_ORIENTATION_TRUETYPE;+  }+++/* END */
+ src/base/ftpatent.c view
@@ -0,0 +1,286 @@+/***************************************************************************/+/*                                                                         */+/*  ftpatent.c                                                             */+/*                                                                         */+/*    FreeType API for checking patented TrueType bytecode instructions    */+/*    (body).                                                              */+/*                                                                         */+/*  Copyright 2007, 2008, 2010 by David Turner.                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TRUETYPE_TAGS_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_STREAM_H+#include FT_SERVICE_SFNT_H+#include FT_SERVICE_TRUETYPE_GLYF_H+++  static FT_Bool+  _tt_check_patents_in_range( FT_Stream  stream,+                              FT_ULong   size )+  {+    FT_Bool   result = FALSE;+    FT_Error  error;+    FT_Bytes  p, end;+++    if ( FT_FRAME_ENTER( size ) )+      return 0;++    p   = stream->cursor;+    end = p + size;++    while ( p < end )+    {+      switch (p[0])+      {+      case 0x06:  /* SPvTL // */+      case 0x07:  /* SPvTL +  */+      case 0x08:  /* SFvTL // */+      case 0x09:  /* SFvTL +  */+      case 0x0A:  /* SPvFS    */+      case 0x0B:  /* SFvFS    */+        result = TRUE;+        goto Exit;++      case 0x40:+        if ( p + 1 >= end )+          goto Exit;++        p += p[1] + 2;+        break;++      case 0x41:+        if ( p + 1 >= end )+          goto Exit;++        p += p[1] * 2 + 2;+        break;++      case 0x71:  /* DELTAP2 */+      case 0x72:  /* DELTAP3 */+      case 0x73:  /* DELTAC0 */+      case 0x74:  /* DELTAC1 */+      case 0x75:  /* DELTAC2 */+        result = TRUE;+        goto Exit;++      case 0xB0:+      case 0xB1:+      case 0xB2:+      case 0xB3:+      case 0xB4:+      case 0xB5:+      case 0xB6:+      case 0xB7:+        p += ( p[0] - 0xB0 ) + 2;+        break;++      case 0xB8:+      case 0xB9:+      case 0xBA:+      case 0xBB:+      case 0xBC:+      case 0xBD:+      case 0xBE:+      case 0xBF:+        p += ( p[0] - 0xB8 ) * 2 + 3;+        break;++      default:+        p += 1;+        break;+      }+    }++  Exit:+    FT_UNUSED( error );+    FT_FRAME_EXIT();+    return result;+  }+++  static FT_Bool+  _tt_check_patents_in_table( FT_Face   face,+                              FT_ULong  tag )+  {+    FT_Stream              stream = face->stream;+    FT_Error               error  = FT_Err_Ok;+    FT_Service_SFNT_Table  service;+    FT_Bool                result = FALSE;+++    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );++    if ( service )+    {+      FT_UInt   i = 0;+      FT_ULong  tag_i = 0, offset_i = 0, length_i = 0;+++      for ( i = 0; !error && tag_i != tag ; i++ )+        error = service->table_info( face, i,+                                     &tag_i, &offset_i, &length_i );++      if ( error                      ||+           FT_STREAM_SEEK( offset_i ) )+        goto Exit;++      result = _tt_check_patents_in_range( stream, length_i );+    }++  Exit:+    return result;+  }+++  static FT_Bool+  _tt_face_check_patents( FT_Face  face )+  {+    FT_Stream  stream = face->stream;+    FT_UInt    gindex;+    FT_Error   error;+    FT_Bool    result;++    FT_Service_TTGlyf  service;+++    result = _tt_check_patents_in_table( face, TTAG_fpgm );+    if ( result )+      goto Exit;++    result = _tt_check_patents_in_table( face, TTAG_prep );+    if ( result )+      goto Exit;++    FT_FACE_FIND_SERVICE( face, service, TT_GLYF );+    if ( service == NULL )+      goto Exit;++    for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )+    {+      FT_ULong  offset, num_ins, size;+      FT_Int    num_contours;+++      offset = service->get_location( face, gindex, &size );+      if ( size == 0 )+        continue;++      if ( FT_STREAM_SEEK( offset )      ||+           FT_READ_SHORT( num_contours ) )+        continue;++      if ( num_contours >= 0 )  /* simple glyph */+      {+        if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )+          continue;+      }+      else  /* compound glyph */+      {+        FT_Bool  has_instr = 0;+++        if ( FT_STREAM_SKIP( 8 ) )+          continue;++        /* now read each component */+        for (;;)+        {+          FT_UInt  flags, toskip;+++          if( FT_READ_USHORT( flags ) )+            break;++          toskip = 2 + 1 + 1;++          if ( ( flags & ( 1 << 0 ) ) != 0 )       /* ARGS_ARE_WORDS */+            toskip += 2;++          if ( ( flags & ( 1 << 3 ) ) != 0 )       /* WE_HAVE_A_SCALE */+            toskip += 2;+          else if ( ( flags & ( 1 << 6 ) ) != 0 )  /* WE_HAVE_X_Y_SCALE */+            toskip += 4;+          else if ( ( flags & ( 1 << 7 ) ) != 0 )  /* WE_HAVE_A_2x2 */+            toskip += 8;++          if ( ( flags & ( 1 << 8 ) ) != 0 )       /* WE_HAVE_INSTRUCTIONS */+            has_instr = 1;++          if ( FT_STREAM_SKIP( toskip ) )+            goto NextGlyph;++          if ( ( flags & ( 1 << 5 ) ) == 0 )       /* MORE_COMPONENTS */+            break;+        }++        if ( !has_instr )+          goto NextGlyph;+      }++      if ( FT_READ_USHORT( num_ins ) )+        continue;++      result = _tt_check_patents_in_range( stream, num_ins );+      if ( result )+        goto Exit;++    NextGlyph:+      ;+    }++  Exit:+    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Bool )+  FT_Face_CheckTrueTypePatents( FT_Face  face )+  {+    FT_Bool  result = FALSE;+++    if ( face && FT_IS_SFNT( face ) )+      result = _tt_face_check_patents( face );++    return result;+  }+++  /* documentation is in freetype.h */++  FT_EXPORT_DEF( FT_Bool )+  FT_Face_SetUnpatentedHinting( FT_Face  face,+                                FT_Bool  value )+  {+    FT_Bool  result = FALSE;+++#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \+    !defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER )+    if ( face && FT_IS_SFNT( face ) )+    {+      result = !face->internal->ignore_unpatented_hinter;+      face->internal->ignore_unpatented_hinter = !value;+    }+#else+    FT_UNUSED( face );+    FT_UNUSED( value );+#endif++    return result;+  }++/* END */
+ src/base/ftpfr.c view
@@ -0,0 +1,144 @@+/***************************************************************************/+/*                                                                         */+/*  ftpfr.c                                                                */+/*                                                                         */+/*    FreeType API for accessing PFR-specific data (body).                 */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2008, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_PFR_H+++  /* check the format */+  static FT_Service_PfrMetrics+  ft_pfr_check( FT_Face  face )+  {+    FT_Service_PfrMetrics  service = NULL;+++    if ( face )+      FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );++    return service;+  }+++  /* documentation is in ftpfr.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_PFR_Metrics( FT_Face    face,+                      FT_UInt   *aoutline_resolution,+                      FT_UInt   *ametrics_resolution,+                      FT_Fixed  *ametrics_x_scale,+                      FT_Fixed  *ametrics_y_scale )+  {+    FT_Error               error = FT_Err_Ok;+    FT_Service_PfrMetrics  service;+++    if ( !face )+      return FT_Err_Invalid_Argument;++    service = ft_pfr_check( face );+    if ( service )+    {+      error = service->get_metrics( face,+                                    aoutline_resolution,+                                    ametrics_resolution,+                                    ametrics_x_scale,+                                    ametrics_y_scale );+    }+    else+    {+      FT_Fixed  x_scale, y_scale;+++      /* this is not a PFR font */+      if ( aoutline_resolution )+        *aoutline_resolution = face->units_per_EM;++      if ( ametrics_resolution )+        *ametrics_resolution = face->units_per_EM;++      x_scale = y_scale = 0x10000L;+      if ( face->size )+      {+        x_scale = face->size->metrics.x_scale;+        y_scale = face->size->metrics.y_scale;+      }++      if ( ametrics_x_scale )+        *ametrics_x_scale = x_scale;++      if ( ametrics_y_scale )+        *ametrics_y_scale = y_scale;++      error = FT_Err_Unknown_File_Format;+    }++    return error;+  }+++  /* documentation is in ftpfr.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_PFR_Kerning( FT_Face     face,+                      FT_UInt     left,+                      FT_UInt     right,+                      FT_Vector  *avector )+  {+    FT_Error               error;+    FT_Service_PfrMetrics  service;+++    if ( !face )+      return FT_Err_Invalid_Argument;++    service = ft_pfr_check( face );+    if ( service )+      error = service->get_kerning( face, left, right, avector );+    else+      error = FT_Get_Kerning( face, left, right,+                              FT_KERNING_UNSCALED, avector );++    return error;+  }+++  /* documentation is in ftpfr.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_PFR_Advance( FT_Face   face,+                      FT_UInt   gindex,+                      FT_Pos   *aadvance )+  {+    FT_Error               error;+    FT_Service_PfrMetrics  service;+++    service = ft_pfr_check( face );+    if ( service )+    {+      error = service->get_advance( face, gindex, aadvance );+    }+    else+      /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */+      error = FT_Err_Invalid_Argument;++    return error;+  }+++/* END */
+ src/base/ftpic.c view
@@ -0,0 +1,54 @@+/***************************************************************************/+/*                                                                         */+/*  ftpic.c                                                                */+/*                                                                         */+/*    The FreeType position independent code services (body).              */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "basepic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* documentation is in ftpic.h */++  FT_BASE_DEF( FT_Error )+  ft_pic_container_init( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Error error = FT_Err_Ok;++    FT_MEM_SET( pic_container, 0, sizeof(*pic_container) );++    error = ft_base_pic_init( library );+    if(error)+      return error;++    return FT_Err_Ok;+  }+++  /* Destroy the contents of the container. */+  FT_BASE_DEF( void )+  ft_pic_container_destroy( FT_Library library )+  {+    ft_base_pic_free( library );+  }++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/base/ftrfork.c view
@@ -0,0 +1,871 @@+/***************************************************************************/+/*                                                                         */+/*  ftrfork.c                                                              */+/*                                                                         */+/*    Embedded resource forks accessor (body).                             */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 by                  */+/*  Masatake YAMATO and Redhat K.K.                                        */+/*                                                                         */+/*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */+/*  derived from ftobjs.c.                                                 */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++/***************************************************************************/+/* Development of the code in this file is support of                      */+/* Information-technology Promotion Agency, Japan.                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_RFORK_H+++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_raccess+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****               Resource fork directory access                    ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  FT_BASE_DEF( FT_Error )+  FT_Raccess_Get_HeaderInfo( FT_Library  library,+                             FT_Stream   stream,+                             FT_Long     rfork_offset,+                             FT_Long    *map_offset,+                             FT_Long    *rdata_pos )+  {+    FT_Error       error;+    unsigned char  head[16], head2[16];+    FT_Long        map_pos, rdata_len;+    int            allzeros, allmatch, i;+    FT_Long        type_list;++    FT_UNUSED( library );+++    error = FT_Stream_Seek( stream, rfork_offset );+    if ( error )+      return error;++    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );+    if ( error )+      return error;++    *rdata_pos = rfork_offset + ( ( head[0] << 24 ) |+                                  ( head[1] << 16 ) |+                                  ( head[2] <<  8 ) |+                                    head[3]         );+    map_pos    = rfork_offset + ( ( head[4] << 24 ) |+                                  ( head[5] << 16 ) |+                                  ( head[6] <<  8 ) |+                                    head[7]         );+    rdata_len = ( head[ 8] << 24 ) |+                ( head[ 9] << 16 ) |+                ( head[10] <<  8 ) |+                  head[11];++    /* map_len = head[12] .. head[15] */++    if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )+      return FT_Err_Unknown_File_Format;++    error = FT_Stream_Seek( stream, map_pos );+    if ( error )+      return error;++    head2[15] = (FT_Byte)( head[15] + 1 );       /* make it be different */++    error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );+    if ( error )+      return error;++    allzeros = 1;+    allmatch = 1;+    for ( i = 0; i < 16; ++i )+    {+      if ( head2[i] != 0 )+        allzeros = 0;+      if ( head2[i] != head[i] )+        allmatch = 0;+    }+    if ( !allzeros && !allmatch )+      return FT_Err_Unknown_File_Format;++    /* If we have reached this point then it is probably a mac resource */+    /* file.  Now, does it contain any interesting resources?           */+    /* Skip handle to next resource map, the file resource number, and  */+    /* attributes.                                                      */+    (void)FT_STREAM_SKIP( 4        /* skip handle to next resource map */+                          + 2      /* skip file resource number */+                          + 2 );   /* skip attributes */++    if ( FT_READ_USHORT( type_list ) )+      return error;+    if ( type_list == -1 )+      return FT_Err_Unknown_File_Format;++    error = FT_Stream_Seek( stream, map_pos + type_list );+    if ( error )+      return error;++    *map_offset = map_pos + type_list;+    return FT_Err_Ok;+  }+++  static int+  ft_raccess_sort_ref_by_id( FT_RFork_Ref*  a,+                             FT_RFork_Ref*  b )+  {+    if ( a->res_id < b->res_id )+      return -1;+    else if ( a->res_id > b->res_id )+      return 1;+    else+      return 0;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Raccess_Get_DataOffsets( FT_Library  library,+                              FT_Stream   stream,+                              FT_Long     map_offset,+                              FT_Long     rdata_pos,+                              FT_Long     tag,+                              FT_Long   **offsets,+                              FT_Long    *count )+  {+    FT_Error      error;+    int           i, j, cnt, subcnt;+    FT_Long       tag_internal, rpos;+    FT_Memory     memory = library->memory;+    FT_Long       temp;+    FT_Long       *offsets_internal;+    FT_RFork_Ref  *ref;+++    error = FT_Stream_Seek( stream, map_offset );+    if ( error )+      return error;++    if ( FT_READ_USHORT( cnt ) )+      return error;+    cnt++;++    for ( i = 0; i < cnt; ++i )+    {+      if ( FT_READ_LONG( tag_internal ) ||+           FT_READ_USHORT( subcnt )     ||+           FT_READ_USHORT( rpos )       )+        return error;++      FT_TRACE2(( "Resource tags: %c%c%c%c\n",+                  (char)( 0xff & ( tag_internal >> 24 ) ),+                  (char)( 0xff & ( tag_internal >> 16 ) ),+                  (char)( 0xff & ( tag_internal >>  8 ) ),+                  (char)( 0xff & ( tag_internal >>  0 ) ) ));++      if ( tag_internal == tag )+      {+        *count = subcnt + 1;+        rpos  += map_offset;++        error = FT_Stream_Seek( stream, rpos );+        if ( error )+          return error;++        if ( FT_NEW_ARRAY( ref, *count ) )+          return error;++        for ( j = 0; j < *count; ++j )+        {+          if ( FT_READ_USHORT( ref[j].res_id ) )+            goto Exit;+          if ( FT_STREAM_SKIP( 2 ) ) /* resource name */+            goto Exit;+          if ( FT_READ_LONG( temp ) )+            goto Exit;+          if ( FT_STREAM_SKIP( 4 ) ) /* mbz */+            goto Exit;++          ref[j].offset = temp & 0xFFFFFFL;+        }++        ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),+                  ( int(*)(const void*, const void*) )+                  ft_raccess_sort_ref_by_id );++        if ( FT_NEW_ARRAY( offsets_internal, *count ) )+          goto Exit;++        /* XXX: duplicated reference ID,+         *      gap between reference IDs are acceptable?+         *      further investigation on Apple implementation is needed.+         */+        for ( j = 0; j < *count; ++j )+          offsets_internal[j] = rdata_pos + ref[j].offset;++        *offsets = offsets_internal;+        error    = FT_Err_Ok;++      Exit:+        FT_FREE( ref );+        return error;+      }+    }++    return FT_Err_Cannot_Open_Resource;+  }+++#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                     Guessing functions                          ****/+  /****                                                                 ****/+  /****            When you add a new guessing function,                ****/+  /****           update FT_RACCESS_N_RULES in ftrfork.h.               ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++  typedef FT_Error+  (*raccess_guess_func)( FT_Library  library,+                         FT_Stream   stream,+                         char       *base_file_name,+                         char      **result_file_name,+                         FT_Long    *result_offset );+++  static FT_Error+  raccess_guess_apple_double( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset );++  static FT_Error+  raccess_guess_apple_single( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset );++  static FT_Error+  raccess_guess_darwin_ufs_export( FT_Library  library,+                                   FT_Stream   stream,+                                   char       *base_file_name,+                                   char      **result_file_name,+                                   FT_Long    *result_offset );++  static FT_Error+  raccess_guess_darwin_newvfs( FT_Library  library,+                               FT_Stream   stream,+                               char       *base_file_name,+                               char      **result_file_name,+                               FT_Long    *result_offset );++  static FT_Error+  raccess_guess_darwin_hfsplus( FT_Library  library,+                                FT_Stream   stream,+                                char       *base_file_name,+                                char      **result_file_name,+                                FT_Long    *result_offset );++  static FT_Error+  raccess_guess_vfat( FT_Library  library,+                      FT_Stream   stream,+                      char       *base_file_name,+                      char      **result_file_name,+                      FT_Long    *result_offset );++  static FT_Error+  raccess_guess_linux_cap( FT_Library  library,+                           FT_Stream   stream,+                           char       *base_file_name,+                           char      **result_file_name,+                           FT_Long    *result_offset );++  static FT_Error+  raccess_guess_linux_double( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset );++  static FT_Error+  raccess_guess_linux_netatalk( FT_Library  library,+                                FT_Stream   stream,+                                char       *base_file_name,+                                char      **result_file_name,+                                FT_Long    *result_offset );+++  /*************************************************************************/+  /****                                                                 ****/+  /****                       Helper functions                          ****/+  /****                                                                 ****/+  /*************************************************************************/++  static FT_Error+  raccess_guess_apple_generic( FT_Library  library,+                               FT_Stream   stream,+                               char       *base_file_name,+                               FT_Int32    magic,+                               FT_Long    *result_offset );++  static FT_Error+  raccess_guess_linux_double_from_file_name( FT_Library  library,+                                             char *      file_name,+                                             FT_Long    *result_offset );++  static char *+  raccess_make_file_name( FT_Memory    memory,+                          const char  *original_name,+                          const char  *insertion );+++  typedef enum  FT_RFork_Rule_ {+    FT_RFork_Rule_invalid = -2,+    FT_RFork_Rule_uknown, /* -1 */+    FT_RFork_Rule_apple_double,+    FT_RFork_Rule_apple_single,+    FT_RFork_Rule_darwin_ufs_export,+    FT_RFork_Rule_darwin_newvfs,+    FT_RFork_Rule_darwin_hfsplus,+    FT_RFork_Rule_vfat,+    FT_RFork_Rule_linux_cap,+    FT_RFork_Rule_linux_double,+    FT_RFork_Rule_linux_netatalk+  } FT_RFork_Rule;++  /* For fast translation between rule index and rule type,+   * the macros FT_RFORK_xxx should be kept consistent with+   * the raccess_guess_funcs table+   */+  typedef struct raccess_guess_rec_ {+    raccess_guess_func  func;+    FT_RFork_Rule       type;+  } raccess_guess_rec;++  static raccess_guess_rec  raccess_guess_table[FT_RACCESS_N_RULES] =+  {+    { raccess_guess_apple_double,	FT_RFork_Rule_apple_double, },+    { raccess_guess_apple_single,	FT_RFork_Rule_apple_single, },+    { raccess_guess_darwin_ufs_export,	FT_RFork_Rule_darwin_ufs_export, },+    { raccess_guess_darwin_newvfs,	FT_RFork_Rule_darwin_newvfs, },+    { raccess_guess_darwin_hfsplus,	FT_RFork_Rule_darwin_hfsplus, },+    { raccess_guess_vfat,		FT_RFork_Rule_vfat, },+    { raccess_guess_linux_cap,		FT_RFork_Rule_linux_cap, },+    { raccess_guess_linux_double,	FT_RFork_Rule_linux_double, },+    { raccess_guess_linux_netatalk,	FT_RFork_Rule_linux_netatalk, },+  };++  FT_BASE_DEF( void )+  FT_Raccess_Guess( FT_Library  library,+                    FT_Stream   stream,+                    char*       base_name,+                    char      **new_names,+                    FT_Long    *offsets,+                    FT_Error   *errors )+  {+    FT_Long  i;+++    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )+    {+      new_names[i] = NULL;+      if ( NULL != stream )+        errors[i] = FT_Stream_Seek( stream, 0 );+      else+        errors[i] = FT_Err_Ok;++      if ( errors[i] )+        continue ;++      errors[i] = (raccess_guess_table[i].func)( library,+                                                 stream, base_name,+                                                 &(new_names[i]),+                                                 &(offsets[i]) );+    }++    return;+  }+++  static FT_RFork_Rule+  raccess_get_rule_type_from_rule_index( FT_UInt  rule_index )+  {+    if ( rule_index >= FT_RACCESS_N_RULES )+      return FT_RFork_Rule_invalid;++    return raccess_guess_table[rule_index].type;+  }+++  FT_LOCAL_DEF( FT_Bool )+  raccess_rule_by_darwin_vfs( FT_UInt  rule_index )+  {+    switch( raccess_get_rule_type_from_rule_index( rule_index ) )+    {+      case FT_RFork_Rule_darwin_newvfs:+      case FT_RFork_Rule_darwin_hfsplus:+        return TRUE;++      default:+        return FALSE;+    }+  }+++  static FT_Error+  raccess_guess_apple_double( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset )+  {+    FT_Int32  magic = ( 0x00 << 24 ) |+                      ( 0x05 << 16 ) |+                      ( 0x16 <<  8 ) |+                        0x07;+++    *result_file_name = NULL;+    if ( NULL == stream )+      return FT_Err_Cannot_Open_Stream;++    return raccess_guess_apple_generic( library, stream, base_file_name,+                                        magic, result_offset );+  }+++  static FT_Error+  raccess_guess_apple_single( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset )+  {+    FT_Int32  magic = ( 0x00 << 24 ) |+                      ( 0x05 << 16 ) |+                      ( 0x16 <<  8 ) |+                        0x00;+++    *result_file_name = NULL;+    if ( NULL == stream )+      return FT_Err_Cannot_Open_Stream;++    return raccess_guess_apple_generic( library, stream, base_file_name,+                                        magic, result_offset );+  }+++  static FT_Error+  raccess_guess_darwin_ufs_export( FT_Library  library,+                                   FT_Stream   stream,+                                   char       *base_file_name,+                                   char      **result_file_name,+                                   FT_Long    *result_offset )+  {+    char*      newpath;+    FT_Error   error;+    FT_Memory  memory;++    FT_UNUSED( stream );+++    memory  = library->memory;+    newpath = raccess_make_file_name( memory, base_file_name, "._" );+    if ( !newpath )+      return FT_Err_Out_Of_Memory;++    error = raccess_guess_linux_double_from_file_name( library, newpath,+                                                       result_offset );+    if ( !error )+      *result_file_name = newpath;+    else+      FT_FREE( newpath );++    return error;+  }+++  static FT_Error+  raccess_guess_darwin_hfsplus( FT_Library  library,+                                FT_Stream   stream,+                                char       *base_file_name,+                                char      **result_file_name,+                                FT_Long    *result_offset )+  {+    /*+      Only meaningful on systems with hfs+ drivers (or Macs).+     */+    FT_Error   error;+    char*      newpath;+    FT_Memory  memory;+    FT_Long    base_file_len = ft_strlen( base_file_name );++    FT_UNUSED( stream );+++    memory = library->memory;++    if ( base_file_len + 6 > FT_INT_MAX )+      return FT_Err_Array_Too_Large;++    if ( FT_ALLOC( newpath, base_file_len + 6 ) )+      return error;++    FT_MEM_COPY( newpath, base_file_name, base_file_len );+    FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );++    *result_file_name = newpath;+    *result_offset    = 0;++    return FT_Err_Ok;+  }+++  static FT_Error+  raccess_guess_darwin_newvfs( FT_Library  library,+                               FT_Stream   stream,+                               char       *base_file_name,+                               char      **result_file_name,+                               FT_Long    *result_offset )+  {+    /*+      Only meaningful on systems with Mac OS X (> 10.1).+     */+    FT_Error   error;+    char*      newpath;+    FT_Memory  memory;+    FT_Long    base_file_len = ft_strlen( base_file_name );++    FT_UNUSED( stream );+++    memory = library->memory;++    if ( base_file_len + 18 > FT_INT_MAX )+      return FT_Err_Array_Too_Large;++    if ( FT_ALLOC( newpath, base_file_len + 18 ) )+      return error;++    FT_MEM_COPY( newpath, base_file_name, base_file_len );+    FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );++    *result_file_name = newpath;+    *result_offset    = 0;++    return FT_Err_Ok;+  }+++  static FT_Error+  raccess_guess_vfat( FT_Library  library,+                      FT_Stream   stream,+                      char       *base_file_name,+                      char      **result_file_name,+                      FT_Long    *result_offset )+  {+    char*      newpath;+    FT_Memory  memory;++    FT_UNUSED( stream );+++    memory = library->memory;++    newpath = raccess_make_file_name( memory, base_file_name,+                                      "resource.frk/" );+    if ( !newpath )+      return FT_Err_Out_Of_Memory;++    *result_file_name = newpath;+    *result_offset    = 0;++    return FT_Err_Ok;+  }+++  static FT_Error+  raccess_guess_linux_cap( FT_Library  library,+                           FT_Stream   stream,+                           char       *base_file_name,+                           char      **result_file_name,+                           FT_Long    *result_offset )+  {+    char*      newpath;+    FT_Memory  memory;++    FT_UNUSED( stream );+++    memory = library->memory;++    newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );+    if ( !newpath )+      return FT_Err_Out_Of_Memory;++    *result_file_name = newpath;+    *result_offset    = 0;++    return FT_Err_Ok;+  }+++  static FT_Error+  raccess_guess_linux_double( FT_Library  library,+                              FT_Stream   stream,+                              char       *base_file_name,+                              char      **result_file_name,+                              FT_Long    *result_offset )+  {+    char*      newpath;+    FT_Error   error;+    FT_Memory  memory;++    FT_UNUSED( stream );+++    memory = library->memory;++    newpath = raccess_make_file_name( memory, base_file_name, "%" );+    if ( !newpath )+      return FT_Err_Out_Of_Memory;++    error = raccess_guess_linux_double_from_file_name( library, newpath,+                                                       result_offset );+    if ( !error )+      *result_file_name = newpath;+    else+      FT_FREE( newpath );++    return error;+  }+++  static FT_Error+  raccess_guess_linux_netatalk( FT_Library  library,+                                FT_Stream   stream,+                                char       *base_file_name,+                                char      **result_file_name,+                                FT_Long    *result_offset )+  {+    char*      newpath;+    FT_Error   error;+    FT_Memory  memory;++    FT_UNUSED( stream );+++    memory = library->memory;++    newpath = raccess_make_file_name( memory, base_file_name,+                                      ".AppleDouble/" );+    if ( !newpath )+      return FT_Err_Out_Of_Memory;++    error = raccess_guess_linux_double_from_file_name( library, newpath,+                                                       result_offset );+    if ( !error )+      *result_file_name = newpath;+    else+      FT_FREE( newpath );++    return error;+  }+++  static FT_Error+  raccess_guess_apple_generic( FT_Library  library,+                               FT_Stream   stream,+                               char       *base_file_name,+                               FT_Int32    magic,+                               FT_Long    *result_offset )+  {+    FT_Int32   magic_from_stream;+    FT_Error   error;+    FT_Int32   version_number = 0;+    FT_UShort  n_of_entries;++    int        i;+    FT_UInt32  entry_id, entry_offset, entry_length = 0;++    const FT_UInt32  resource_fork_entry_id = 0x2;++    FT_UNUSED( library );+    FT_UNUSED( base_file_name );+    FT_UNUSED( version_number );+    FT_UNUSED( entry_length   );+++    if ( FT_READ_LONG( magic_from_stream ) )+      return error;+    if ( magic_from_stream != magic )+      return FT_Err_Unknown_File_Format;++    if ( FT_READ_LONG( version_number ) )+      return error;++    /* filler */+    error = FT_Stream_Skip( stream, 16 );+    if ( error )+      return error;++    if ( FT_READ_USHORT( n_of_entries ) )+      return error;+    if ( n_of_entries == 0 )+      return FT_Err_Unknown_File_Format;++    for ( i = 0; i < n_of_entries; i++ )+    {+      if ( FT_READ_LONG( entry_id ) )+        return error;+      if ( entry_id == resource_fork_entry_id )+      {+        if ( FT_READ_LONG( entry_offset ) ||+             FT_READ_LONG( entry_length ) )+          continue;+        *result_offset = entry_offset;++        return FT_Err_Ok;+      }+      else+      {+        error = FT_Stream_Skip( stream, 4 + 4 );    /* offset + length */+        if ( error )+          return error;+      }+    }++    return FT_Err_Unknown_File_Format;+  }+++  static FT_Error+  raccess_guess_linux_double_from_file_name( FT_Library  library,+                                             char       *file_name,+                                             FT_Long    *result_offset )+  {+    FT_Open_Args  args2;+    FT_Stream     stream2;+    char *        nouse = NULL;+    FT_Error      error;+++    args2.flags    = FT_OPEN_PATHNAME;+    args2.pathname = file_name;+    error = FT_Stream_New( library, &args2, &stream2 );+    if ( error )+      return error;++    error = raccess_guess_apple_double( library, stream2, file_name,+                                        &nouse, result_offset );++    FT_Stream_Free( stream2, 0 );++    return error;+  }+++  static char*+  raccess_make_file_name( FT_Memory    memory,+                          const char  *original_name,+                          const char  *insertion )+  {+    char*        new_name = NULL;+    const char*  tmp;+    const char*  slash;+    size_t       new_length;+    FT_Error     error = FT_Err_Ok;++    FT_UNUSED( error );+++    new_length = ft_strlen( original_name ) + ft_strlen( insertion );+    if ( FT_ALLOC( new_name, new_length + 1 ) )+      return NULL;++    tmp = ft_strrchr( original_name, '/' );+    if ( tmp )+    {+      ft_strncpy( new_name, original_name, tmp - original_name + 1 );+      new_name[tmp - original_name + 1] = '\0';+      slash = tmp + 1;+    }+    else+    {+      slash       = original_name;+      new_name[0] = '\0';+    }++    ft_strcat( new_name, insertion );+    ft_strcat( new_name, slash );++    return new_name;+  }+++#else   /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */+++  /*************************************************************************/+  /*                  Dummy function; just sets errors                     */+  /*************************************************************************/++  FT_BASE_DEF( void )+  FT_Raccess_Guess( FT_Library  library,+                    FT_Stream   stream,+                    char       *base_name,+                    char      **new_names,+                    FT_Long    *offsets,+                    FT_Error   *errors )+  {+    int  i;++    FT_UNUSED( library );+    FT_UNUSED( stream );+    FT_UNUSED( base_name );+++    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )+    {+      new_names[i] = NULL;+      offsets[i]   = 0;+      errors[i]    = FT_Err_Unimplemented_Feature;+    }+  }+++#endif  /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */+++/* END */
+ src/base/ftsnames.c view
@@ -0,0 +1,94 @@+/***************************************************************************/+/*                                                                         */+/*  ftsnames.c                                                             */+/*                                                                         */+/*    Simple interface to access SFNT name tables (which are used          */+/*    to hold font names, copyright info, notices, etc.) (body).           */+/*                                                                         */+/*    This is _not_ used to retrieve glyph names!                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2009 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_SFNT_NAMES_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+#include FT_INTERNAL_STREAM_H+++#ifdef TT_CONFIG_OPTION_SFNT_NAMES+++  /* documentation is in ftsnames.h */++  FT_EXPORT_DEF( FT_UInt )+  FT_Get_Sfnt_Name_Count( FT_Face  face )+  {+    return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0;+  }+++  /* documentation is in ftsnames.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_Sfnt_Name( FT_Face       face,+                    FT_UInt       idx,+                    FT_SfntName  *aname )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+++    if ( aname && face && FT_IS_SFNT( face ) )+    {+      TT_Face  ttface = (TT_Face)face;+++      if ( idx < (FT_UInt)ttface->num_names )+      {+        TT_NameEntryRec*  entry = ttface->name_table.names + idx;+++        /* load name on demand */+        if ( entry->stringLength > 0 && entry->string == NULL )+        {+          FT_Memory  memory = face->memory;+          FT_Stream  stream = face->stream;+++          if ( FT_NEW_ARRAY  ( entry->string, entry->stringLength ) ||+               FT_STREAM_SEEK( entry->stringOffset )                ||+               FT_STREAM_READ( entry->string, entry->stringLength ) )+          {+            FT_FREE( entry->string );+            entry->stringLength = 0;+          }+        }++        aname->platform_id = entry->platformID;+        aname->encoding_id = entry->encodingID;+        aname->language_id = entry->languageID;+        aname->name_id     = entry->nameID;+        aname->string      = (FT_Byte*)entry->string;+        aname->string_len  = entry->stringLength;++        error = FT_Err_Ok;+      }+    }++    return error;+  }+++#endif /* TT_CONFIG_OPTION_SFNT_NAMES */+++/* END */
+ src/base/ftstream.c view
@@ -0,0 +1,864 @@+/***************************************************************************/+/*                                                                         */+/*  ftstream.c                                                             */+/*                                                                         */+/*    I/O stream support (body).                                           */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_DEBUG_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_stream+++  FT_BASE_DEF( void )+  FT_Stream_OpenMemory( FT_Stream       stream,+                        const FT_Byte*  base,+                        FT_ULong        size )+  {+    stream->base   = (FT_Byte*) base;+    stream->size   = size;+    stream->pos    = 0;+    stream->cursor = 0;+    stream->read   = 0;+    stream->close  = 0;+  }+++  FT_BASE_DEF( void )+  FT_Stream_Close( FT_Stream  stream )+  {+    if ( stream && stream->close )+      stream->close( stream );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_Seek( FT_Stream  stream,+                  FT_ULong   pos )+  {+    FT_Error  error = FT_Err_Ok;+++    if ( stream->read )+    {+      if ( stream->read( stream, pos, 0, 0 ) )+      {+        FT_ERROR(( "FT_Stream_Seek:"+                   " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+                   pos, stream->size ));++        error = FT_Err_Invalid_Stream_Operation;+      }+    }+    /* note that seeking to the first position after the file is valid */+    else if ( pos > stream->size )+    {+      FT_ERROR(( "FT_Stream_Seek:"+                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+                 pos, stream->size ));++      error = FT_Err_Invalid_Stream_Operation;+    }++    if ( !error )+      stream->pos = pos;++    return error;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_Skip( FT_Stream  stream,+                  FT_Long    distance )+  {+    if ( distance < 0 )+      return FT_Err_Invalid_Stream_Operation;++    return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_Pos( FT_Stream  stream )+  {+    return stream->pos;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_Read( FT_Stream  stream,+                  FT_Byte*   buffer,+                  FT_ULong   count )+  {+    return FT_Stream_ReadAt( stream, stream->pos, buffer, count );+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_ReadAt( FT_Stream  stream,+                    FT_ULong   pos,+                    FT_Byte*   buffer,+                    FT_ULong   count )+  {+    FT_Error  error = FT_Err_Ok;+    FT_ULong  read_bytes;+++    if ( pos >= stream->size )+    {+      FT_ERROR(( "FT_Stream_ReadAt:"+                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+                 pos, stream->size ));++      return FT_Err_Invalid_Stream_Operation;+    }++    if ( stream->read )+      read_bytes = stream->read( stream, pos, buffer, count );+    else+    {+      read_bytes = stream->size - pos;+      if ( read_bytes > count )+        read_bytes = count;++      FT_MEM_COPY( buffer, stream->base + pos, read_bytes );+    }++    stream->pos = pos + read_bytes;++    if ( read_bytes < count )+    {+      FT_ERROR(( "FT_Stream_ReadAt:"+                 " invalid read; expected %lu bytes, got %lu\n",+                 count, read_bytes ));++      error = FT_Err_Invalid_Stream_Operation;+    }++    return error;+  }+++  FT_BASE_DEF( FT_ULong )+  FT_Stream_TryRead( FT_Stream  stream,+                     FT_Byte*   buffer,+                     FT_ULong   count )+  {+    FT_ULong  read_bytes = 0;+++    if ( stream->pos >= stream->size )+      goto Exit;++    if ( stream->read )+      read_bytes = stream->read( stream, stream->pos, buffer, count );+    else+    {+      read_bytes = stream->size - stream->pos;+      if ( read_bytes > count )+        read_bytes = count;++      FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );+    }++    stream->pos += read_bytes;++  Exit:+    return read_bytes;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_ExtractFrame( FT_Stream  stream,+                          FT_ULong   count,+                          FT_Byte**  pbytes )+  {+    FT_Error  error;+++    error = FT_Stream_EnterFrame( stream, count );+    if ( !error )+    {+      *pbytes = (FT_Byte*)stream->cursor;++      /* equivalent to FT_Stream_ExitFrame(), with no memory block release */+      stream->cursor = 0;+      stream->limit  = 0;+    }++    return error;+  }+++  FT_BASE_DEF( void )+  FT_Stream_ReleaseFrame( FT_Stream  stream,+                          FT_Byte**  pbytes )+  {+    if ( stream && stream->read )+    {+      FT_Memory  memory = stream->memory;++#ifdef FT_DEBUG_MEMORY+      ft_mem_free( memory, *pbytes );+      *pbytes = NULL;+#else+      FT_FREE( *pbytes );+#endif+    }+    *pbytes = 0;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_EnterFrame( FT_Stream  stream,+                        FT_ULong   count )+  {+    FT_Error  error = FT_Err_Ok;+    FT_ULong  read_bytes;+++    /* check for nested frame access */+    FT_ASSERT( stream && stream->cursor == 0 );++    if ( stream->read )+    {+      /* allocate the frame in memory */+      FT_Memory  memory = stream->memory;+++      /* simple sanity check */+      if ( count > stream->size )+      {+        FT_ERROR(( "FT_Stream_EnterFrame:"+                   " frame size (%lu) larger than stream size (%lu)\n",+                   count, stream->size ));++        error = FT_Err_Invalid_Stream_Operation;+        goto Exit;+      }++#ifdef FT_DEBUG_MEMORY+      /* assume _ft_debug_file and _ft_debug_lineno are already set */+      stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );+      if ( error )+        goto Exit;+#else+      if ( FT_QALLOC( stream->base, count ) )+        goto Exit;+#endif+      /* read it */+      read_bytes = stream->read( stream, stream->pos,+                                 stream->base, count );+      if ( read_bytes < count )+      {+        FT_ERROR(( "FT_Stream_EnterFrame:"+                   " invalid read; expected %lu bytes, got %lu\n",+                   count, read_bytes ));++        FT_FREE( stream->base );+        error = FT_Err_Invalid_Stream_Operation;+      }+      stream->cursor = stream->base;+      stream->limit  = stream->cursor + count;+      stream->pos   += read_bytes;+    }+    else+    {+      /* check current and new position */+      if ( stream->pos >= stream->size        ||+           stream->size - stream->pos < count )+      {+        FT_ERROR(( "FT_Stream_EnterFrame:"+                   " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",+                   stream->pos, count, stream->size ));++        error = FT_Err_Invalid_Stream_Operation;+        goto Exit;+      }++      /* set cursor */+      stream->cursor = stream->base + stream->pos;+      stream->limit  = stream->cursor + count;+      stream->pos   += count;+    }++  Exit:+    return error;+  }+++  FT_BASE_DEF( void )+  FT_Stream_ExitFrame( FT_Stream  stream )+  {+    /* IMPORTANT: The assertion stream->cursor != 0 was removed, given    */+    /*            that it is possible to access a frame of length 0 in    */+    /*            some weird fonts (usually, when accessing an array of   */+    /*            0 records, like in some strange kern tables).           */+    /*                                                                    */+    /*  In this case, the loader code handles the 0-length table          */+    /*  gracefully; however, stream.cursor is really set to 0 by the      */+    /*  FT_Stream_EnterFrame() call, and this is not an error.            */+    /*                                                                    */+    FT_ASSERT( stream );++    if ( stream->read )+    {+      FT_Memory  memory = stream->memory;++#ifdef FT_DEBUG_MEMORY+      ft_mem_free( memory, stream->base );+      stream->base = NULL;+#else+      FT_FREE( stream->base );+#endif+    }+    stream->cursor = 0;+    stream->limit  = 0;+  }+++  FT_BASE_DEF( FT_Char )+  FT_Stream_GetChar( FT_Stream  stream )+  {+    FT_Char  result;+++    FT_ASSERT( stream && stream->cursor );++    result = 0;+    if ( stream->cursor < stream->limit )+      result = *stream->cursor++;++    return result;+  }+++  FT_BASE_DEF( FT_Short )+  FT_Stream_GetShort( FT_Stream  stream )+  {+    FT_Byte*  p;+    FT_Short  result;+++    FT_ASSERT( stream && stream->cursor );++    result         = 0;+    p              = stream->cursor;+    if ( p + 1 < stream->limit )+      result       = FT_NEXT_SHORT( p );+    stream->cursor = p;++    return result;+  }+++  FT_BASE_DEF( FT_Short )+  FT_Stream_GetShortLE( FT_Stream  stream )+  {+    FT_Byte*  p;+    FT_Short  result;+++    FT_ASSERT( stream && stream->cursor );++    result         = 0;+    p              = stream->cursor;+    if ( p + 1 < stream->limit )+      result       = FT_NEXT_SHORT_LE( p );+    stream->cursor = p;++    return result;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_GetOffset( FT_Stream  stream )+  {+    FT_Byte*  p;+    FT_Long   result;+++    FT_ASSERT( stream && stream->cursor );++    result         = 0;+    p              = stream->cursor;+    if ( p + 2 < stream->limit )+      result       = FT_NEXT_OFF3( p );+    stream->cursor = p;+    return result;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_GetLong( FT_Stream  stream )+  {+    FT_Byte*  p;+    FT_Long   result;+++    FT_ASSERT( stream && stream->cursor );++    result         = 0;+    p              = stream->cursor;+    if ( p + 3 < stream->limit )+      result       = FT_NEXT_LONG( p );+    stream->cursor = p;+    return result;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_GetLongLE( FT_Stream  stream )+  {+    FT_Byte*  p;+    FT_Long   result;+++    FT_ASSERT( stream && stream->cursor );++    result         = 0;+    p              = stream->cursor;+    if ( p + 3 < stream->limit )+      result       = FT_NEXT_LONG_LE( p );+    stream->cursor = p;+    return result;+  }+++  FT_BASE_DEF( FT_Char )+  FT_Stream_ReadChar( FT_Stream  stream,+                      FT_Error*  error )+  {+    FT_Byte  result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->read )+    {+      if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )+        goto Fail;+    }+    else+    {+      if ( stream->pos < stream->size )+        result = stream->base[stream->pos];+      else+        goto Fail;+    }+    stream->pos++;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadChar:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Short )+  FT_Stream_ReadShort( FT_Stream  stream,+                       FT_Error*  error )+  {+    FT_Byte   reads[2];+    FT_Byte*  p = 0;+    FT_Short  result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->pos + 1 < stream->size )+    {+      if ( stream->read )+      {+        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )+          goto Fail;++        p = reads;+      }+      else+      {+        p = stream->base + stream->pos;+      }++      if ( p )+        result = FT_NEXT_SHORT( p );+    }+    else+      goto Fail;++    stream->pos += 2;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadShort:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Short )+  FT_Stream_ReadShortLE( FT_Stream  stream,+                         FT_Error*  error )+  {+    FT_Byte   reads[2];+    FT_Byte*  p = 0;+    FT_Short  result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->pos + 1 < stream->size )+    {+      if ( stream->read )+      {+        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )+          goto Fail;++        p = reads;+      }+      else+      {+        p = stream->base + stream->pos;+      }++      if ( p )+        result = FT_NEXT_SHORT_LE( p );+    }+    else+      goto Fail;++    stream->pos += 2;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadShortLE:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_ReadOffset( FT_Stream  stream,+                        FT_Error*  error )+  {+    FT_Byte   reads[3];+    FT_Byte*  p = 0;+    FT_Long   result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->pos + 2 < stream->size )+    {+      if ( stream->read )+      {+        if (stream->read( stream, stream->pos, reads, 3L ) != 3L )+          goto Fail;++        p = reads;+      }+      else+      {+        p = stream->base + stream->pos;+      }++      if ( p )+        result = FT_NEXT_OFF3( p );+    }+    else+      goto Fail;++    stream->pos += 3;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadOffset:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_ReadLong( FT_Stream  stream,+                      FT_Error*  error )+  {+    FT_Byte   reads[4];+    FT_Byte*  p = 0;+    FT_Long   result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->pos + 3 < stream->size )+    {+      if ( stream->read )+      {+        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )+          goto Fail;++        p = reads;+      }+      else+      {+        p = stream->base + stream->pos;+      }++      if ( p )+        result = FT_NEXT_LONG( p );+    }+    else+      goto Fail;++    stream->pos += 4;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadLong:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Long )+  FT_Stream_ReadLongLE( FT_Stream  stream,+                        FT_Error*  error )+  {+    FT_Byte   reads[4];+    FT_Byte*  p = 0;+    FT_Long   result = 0;+++    FT_ASSERT( stream );++    *error = FT_Err_Ok;++    if ( stream->pos + 3 < stream->size )+    {+      if ( stream->read )+      {+        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )+          goto Fail;++        p = reads;+      }+      else+      {+        p = stream->base + stream->pos;+      }++      if ( p )+        result = FT_NEXT_LONG_LE( p );+    }+    else+      goto Fail;++    stream->pos += 4;++    return result;++  Fail:+    *error = FT_Err_Invalid_Stream_Operation;+    FT_ERROR(( "FT_Stream_ReadLongLE:"+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",+               stream->pos, stream->size ));++    return 0;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Stream_ReadFields( FT_Stream              stream,+                        const FT_Frame_Field*  fields,+                        void*                  structure )+  {+    FT_Error  error;+    FT_Bool   frame_accessed = 0;+    FT_Byte*  cursor;++    if ( !fields || !stream )+      return FT_Err_Invalid_Argument;++    cursor = stream->cursor;++    error = FT_Err_Ok;+    do+    {+      FT_ULong  value;+      FT_Int    sign_shift;+      FT_Byte*  p;+++      switch ( fields->value )+      {+      case ft_frame_start:  /* access a new frame */+        error = FT_Stream_EnterFrame( stream, fields->offset );+        if ( error )+          goto Exit;++        frame_accessed = 1;+        cursor         = stream->cursor;+        fields++;+        continue;  /* loop! */++      case ft_frame_bytes:  /* read a byte sequence */+      case ft_frame_skip:   /* skip some bytes      */+        {+          FT_UInt  len = fields->size;+++          if ( cursor + len > stream->limit )+          {+            error = FT_Err_Invalid_Stream_Operation;+            goto Exit;+          }++          if ( fields->value == ft_frame_bytes )+          {+            p = (FT_Byte*)structure + fields->offset;+            FT_MEM_COPY( p, cursor, len );+          }+          cursor += len;+          fields++;+          continue;+        }++      case ft_frame_byte:+      case ft_frame_schar:  /* read a single byte */+        value = FT_NEXT_BYTE(cursor);+        sign_shift = 24;+        break;++      case ft_frame_short_be:+      case ft_frame_ushort_be:  /* read a 2-byte big-endian short */+        value = FT_NEXT_USHORT(cursor);+        sign_shift = 16;+        break;++      case ft_frame_short_le:+      case ft_frame_ushort_le:  /* read a 2-byte little-endian short */+        value = FT_NEXT_USHORT_LE(cursor);+        sign_shift = 16;+        break;++      case ft_frame_long_be:+      case ft_frame_ulong_be:  /* read a 4-byte big-endian long */+        value = FT_NEXT_ULONG(cursor);+        sign_shift = 0;+        break;++      case ft_frame_long_le:+      case ft_frame_ulong_le:  /* read a 4-byte little-endian long */+        value = FT_NEXT_ULONG_LE(cursor);+        sign_shift = 0;+        break;++      case ft_frame_off3_be:+      case ft_frame_uoff3_be:  /* read a 3-byte big-endian long */+        value = FT_NEXT_UOFF3(cursor);+        sign_shift = 8;+        break;++      case ft_frame_off3_le:+      case ft_frame_uoff3_le:  /* read a 3-byte little-endian long */+        value = FT_NEXT_UOFF3_LE(cursor);+        sign_shift = 8;+        break;++      default:+        /* otherwise, exit the loop */+        stream->cursor = cursor;+        goto Exit;+      }++      /* now, compute the signed value is necessary */+      if ( fields->value & FT_FRAME_OP_SIGNED )+        value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift );++      /* finally, store the value in the object */++      p = (FT_Byte*)structure + fields->offset;+      switch ( fields->size )+      {+      case (8 / FT_CHAR_BIT):+        *(FT_Byte*)p = (FT_Byte)value;+        break;++      case (16 / FT_CHAR_BIT):+        *(FT_UShort*)p = (FT_UShort)value;+        break;++      case (32 / FT_CHAR_BIT):+        *(FT_UInt32*)p = (FT_UInt32)value;+        break;++      default:  /* for 64-bit systems */+        *(FT_ULong*)p = (FT_ULong)value;+      }++      /* go to next field */+      fields++;+    }+    while ( 1 );++  Exit:+    /* close the frame if it was opened by this read */+    if ( frame_accessed )+      FT_Stream_ExitFrame( stream );++    return error;+  }+++/* END */
+ src/base/ftstroke.c view
@@ -0,0 +1,2039 @@+/***************************************************************************/+/*                                                                         */+/*  ftstroke.c                                                             */+/*                                                                         */+/*    FreeType path stroker (body).                                        */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by            */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_STROKER_H+#include FT_TRIGONOMETRY_H+#include FT_OUTLINE_H+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_StrokerBorder )+  FT_Outline_GetInsideBorder( FT_Outline*  outline )+  {+    FT_Orientation  o = FT_Outline_Get_Orientation( outline );+++    return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT+                                        : FT_STROKER_BORDER_LEFT ;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_StrokerBorder )+  FT_Outline_GetOutsideBorder( FT_Outline*  outline )+  {+    FT_Orientation  o = FT_Outline_Get_Orientation( outline );+++    return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT+                                        : FT_STROKER_BORDER_RIGHT ;+  }+++ /***************************************************************************/+ /***************************************************************************/+ /*****                                                                 *****/+ /*****                       BEZIER COMPUTATIONS                       *****/+ /*****                                                                 *****/+ /***************************************************************************/+ /***************************************************************************/++#define FT_SMALL_CONIC_THRESHOLD  ( FT_ANGLE_PI / 6 )+#define FT_SMALL_CUBIC_THRESHOLD  ( FT_ANGLE_PI / 6 )+#define FT_EPSILON  2++#define FT_IS_SMALL( x )  ( (x) > -FT_EPSILON && (x) < FT_EPSILON )+++  static FT_Pos+  ft_pos_abs( FT_Pos  x )+  {+    return x >= 0 ? x : -x ;+  }+++  static void+  ft_conic_split( FT_Vector*  base )+  {+    FT_Pos  a, b;+++    base[4].x = base[2].x;+    b = base[1].x;+    a = base[3].x = ( base[2].x + b ) / 2;+    b = base[1].x = ( base[0].x + b ) / 2;+    base[2].x = ( a + b ) / 2;++    base[4].y = base[2].y;+    b = base[1].y;+    a = base[3].y = ( base[2].y + b ) / 2;+    b = base[1].y = ( base[0].y + b ) / 2;+    base[2].y = ( a + b ) / 2;+  }+++  static FT_Bool+  ft_conic_is_small_enough( FT_Vector*  base,+                            FT_Angle   *angle_in,+                            FT_Angle   *angle_out )+  {+    FT_Vector  d1, d2;+    FT_Angle   theta;+    FT_Int     close1, close2;+++    d1.x = base[1].x - base[2].x;+    d1.y = base[1].y - base[2].y;+    d2.x = base[0].x - base[1].x;+    d2.y = base[0].y - base[1].y;++    close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y );+    close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y );++    if ( close1 )+    {+      if ( close2 )+        *angle_in = *angle_out = 0;+      else+        *angle_in = *angle_out = FT_Atan2( d2.x, d2.y );+    }+    else if ( close2 )+    {+      *angle_in = *angle_out = FT_Atan2( d1.x, d1.y );+    }+    else+    {+      *angle_in  = FT_Atan2( d1.x, d1.y );+      *angle_out = FT_Atan2( d2.x, d2.y );+    }++    theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) );++    return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD );+  }+++  static void+  ft_cubic_split( FT_Vector*  base )+  {+    FT_Pos  a, b, c, d;+++    base[6].x = base[3].x;+    c = base[1].x;+    d = base[2].x;+    base[1].x = a = ( base[0].x + c ) / 2;+    base[5].x = b = ( base[3].x + d ) / 2;+    c = ( c + d ) / 2;+    base[2].x = a = ( a + c ) / 2;+    base[4].x = b = ( b + c ) / 2;+    base[3].x = ( a + b ) / 2;++    base[6].y = base[3].y;+    c = base[1].y;+    d = base[2].y;+    base[1].y = a = ( base[0].y + c ) / 2;+    base[5].y = b = ( base[3].y + d ) / 2;+    c = ( c + d ) / 2;+    base[2].y = a = ( a + c ) / 2;+    base[4].y = b = ( b + c ) / 2;+    base[3].y = ( a + b ) / 2;+  }+++  static FT_Bool+  ft_cubic_is_small_enough( FT_Vector*  base,+                            FT_Angle   *angle_in,+                            FT_Angle   *angle_mid,+                            FT_Angle   *angle_out )+  {+    FT_Vector  d1, d2, d3;+    FT_Angle   theta1, theta2;+    FT_Int     close1, close2, close3;+++    d1.x = base[2].x - base[3].x;+    d1.y = base[2].y - base[3].y;+    d2.x = base[1].x - base[2].x;+    d2.y = base[1].y - base[2].y;+    d3.x = base[0].x - base[1].x;+    d3.y = base[0].y - base[1].y;++    close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y );+    close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y );+    close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y );++    if ( close1 || close3 )+    {+      if ( close2 )+      {+        /* basically a point */+        *angle_in = *angle_out = *angle_mid = 0;+      }+      else if ( close1 )+      {+        *angle_in  = *angle_mid = FT_Atan2( d2.x, d2.y );+        *angle_out = FT_Atan2( d3.x, d3.y );+      }+      else  /* close2 */+      {+        *angle_in  = FT_Atan2( d1.x, d1.y );+        *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y );+      }+    }+    else if ( close2 )+    {+      *angle_in  = *angle_mid = FT_Atan2( d1.x, d1.y );+      *angle_out = FT_Atan2( d3.x, d3.y );+    }+    else+    {+      *angle_in  = FT_Atan2( d1.x, d1.y );+      *angle_mid = FT_Atan2( d2.x, d2.y );+      *angle_out = FT_Atan2( d3.x, d3.y );+    }++    theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in,  *angle_mid ) );+    theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) );++    return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD &&+                    theta2 < FT_SMALL_CUBIC_THRESHOLD );+  }+++ /***************************************************************************/+ /***************************************************************************/+ /*****                                                                 *****/+ /*****                       STROKE BORDERS                            *****/+ /*****                                                                 *****/+ /***************************************************************************/+ /***************************************************************************/++  typedef enum  FT_StrokeTags_+  {+    FT_STROKE_TAG_ON    = 1,   /* on-curve point  */+    FT_STROKE_TAG_CUBIC = 2,   /* cubic off-point */+    FT_STROKE_TAG_BEGIN = 4,   /* sub-path start  */+    FT_STROKE_TAG_END   = 8    /* sub-path end    */++  } FT_StrokeTags;++#define  FT_STROKE_TAG_BEGIN_END  (FT_STROKE_TAG_BEGIN|FT_STROKE_TAG_END)++  typedef struct  FT_StrokeBorderRec_+  {+    FT_UInt     num_points;+    FT_UInt     max_points;+    FT_Vector*  points;+    FT_Byte*    tags;+    FT_Bool     movable;+    FT_Int      start;    /* index of current sub-path start point */+    FT_Memory   memory;+    FT_Bool     valid;++  } FT_StrokeBorderRec, *FT_StrokeBorder;+++  static FT_Error+  ft_stroke_border_grow( FT_StrokeBorder  border,+                         FT_UInt          new_points )+  {+    FT_UInt   old_max = border->max_points;+    FT_UInt   new_max = border->num_points + new_points;+    FT_Error  error   = FT_Err_Ok;+++    if ( new_max > old_max )+    {+      FT_UInt    cur_max = old_max;+      FT_Memory  memory  = border->memory;+++      while ( cur_max < new_max )+        cur_max += ( cur_max >> 1 ) + 16;++      if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) ||+           FT_RENEW_ARRAY( border->tags,   old_max, cur_max ) )+        goto Exit;++      border->max_points = cur_max;+    }++  Exit:+    return error;+  }+++  static void+  ft_stroke_border_close( FT_StrokeBorder  border,+                          FT_Bool          reverse )+  {+    FT_UInt  start = border->start;+    FT_UInt  count = border->num_points;+++    FT_ASSERT( border->start >= 0 );++    /* don't record empty paths! */+    if ( count <= start + 1U )+      border->num_points = start;+    else+    {+      /* copy the last point to the start of this sub-path, since */+      /* it contains the `adjusted' starting coordinates          */+      border->num_points    = --count;+      border->points[start] = border->points[count];++      if ( reverse )+      {+        /* reverse the points */+        {+          FT_Vector*  vec1 = border->points + start + 1;+          FT_Vector*  vec2 = border->points + count - 1;+++          for ( ; vec1 < vec2; vec1++, vec2-- )+          {+            FT_Vector  tmp;+++            tmp   = *vec1;+            *vec1 = *vec2;+            *vec2 = tmp;+          }+        }++        /* then the tags */+        {+          FT_Byte*  tag1 = border->tags + start + 1;+          FT_Byte*  tag2 = border->tags + count - 1;+++          for ( ; tag1 < tag2; tag1++, tag2-- )+          {+            FT_Byte  tmp;+++            tmp   = *tag1;+            *tag1 = *tag2;+            *tag2 = tmp;+          }+        }+      }++      border->tags[start    ] |= FT_STROKE_TAG_BEGIN;+      border->tags[count - 1] |= FT_STROKE_TAG_END;+    }++    border->start   = -1;+    border->movable = FALSE;+  }+++  static FT_Error+  ft_stroke_border_lineto( FT_StrokeBorder  border,+                           FT_Vector*       to,+                           FT_Bool          movable )+  {+    FT_Error  error = FT_Err_Ok;+++    FT_ASSERT( border->start >= 0 );++    if ( border->movable )+    {+      /* move last point */+      border->points[border->num_points - 1] = *to;+    }+    else+    {+      /* add one point */+      error = ft_stroke_border_grow( border, 1 );+      if ( !error )+      {+        FT_Vector*  vec = border->points + border->num_points;+        FT_Byte*    tag = border->tags   + border->num_points;+++        vec[0] = *to;+        tag[0] = FT_STROKE_TAG_ON;++        border->num_points += 1;+      }+    }+    border->movable = movable;+    return error;+  }+++  static FT_Error+  ft_stroke_border_conicto( FT_StrokeBorder  border,+                            FT_Vector*       control,+                            FT_Vector*       to )+  {+    FT_Error  error;+++    FT_ASSERT( border->start >= 0 );++    error = ft_stroke_border_grow( border, 2 );+    if ( !error )+    {+      FT_Vector*  vec = border->points + border->num_points;+      FT_Byte*    tag = border->tags   + border->num_points;++      vec[0] = *control;+      vec[1] = *to;++      tag[0] = 0;+      tag[1] = FT_STROKE_TAG_ON;++      border->num_points += 2;+    }+    border->movable = FALSE;+    return error;+  }+++  static FT_Error+  ft_stroke_border_cubicto( FT_StrokeBorder  border,+                            FT_Vector*       control1,+                            FT_Vector*       control2,+                            FT_Vector*       to )+  {+    FT_Error  error;+++    FT_ASSERT( border->start >= 0 );++    error = ft_stroke_border_grow( border, 3 );+    if ( !error )+    {+      FT_Vector*  vec = border->points + border->num_points;+      FT_Byte*    tag = border->tags   + border->num_points;+++      vec[0] = *control1;+      vec[1] = *control2;+      vec[2] = *to;++      tag[0] = FT_STROKE_TAG_CUBIC;+      tag[1] = FT_STROKE_TAG_CUBIC;+      tag[2] = FT_STROKE_TAG_ON;++      border->num_points += 3;+    }+    border->movable = FALSE;+    return error;+  }+++#define FT_ARC_CUBIC_ANGLE  ( FT_ANGLE_PI / 2 )+++  static FT_Error+  ft_stroke_border_arcto( FT_StrokeBorder  border,+                          FT_Vector*       center,+                          FT_Fixed         radius,+                          FT_Angle         angle_start,+                          FT_Angle         angle_diff )+  {+    FT_Angle   total, angle, step, rotate, next, theta;+    FT_Vector  a, b, a2, b2;+    FT_Fixed   length;+    FT_Error   error = FT_Err_Ok;+++    /* compute start point */+    FT_Vector_From_Polar( &a, radius, angle_start );+    a.x += center->x;+    a.y += center->y;++    total  = angle_diff;+    angle  = angle_start;+    rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2;++    while ( total != 0 )+    {+      step = total;+      if ( step > FT_ARC_CUBIC_ANGLE )+        step = FT_ARC_CUBIC_ANGLE;++      else if ( step < -FT_ARC_CUBIC_ANGLE )+        step = -FT_ARC_CUBIC_ANGLE;++      next  = angle + step;+      theta = step;+      if ( theta < 0 )+        theta = -theta;++      theta >>= 1;++      /* compute end point */+      FT_Vector_From_Polar( &b, radius, next );+      b.x += center->x;+      b.y += center->y;++      /* compute first and second control points */+      length = FT_MulDiv( radius, FT_Sin( theta ) * 4,+                          ( 0x10000L + FT_Cos( theta ) ) * 3 );++      FT_Vector_From_Polar( &a2, length, angle + rotate );+      a2.x += a.x;+      a2.y += a.y;++      FT_Vector_From_Polar( &b2, length, next - rotate );+      b2.x += b.x;+      b2.y += b.y;++      /* add cubic arc */+      error = ft_stroke_border_cubicto( border, &a2, &b2, &b );+      if ( error )+        break;++      /* process the rest of the arc ?? */+      a      = b;+      total -= step;+      angle  = next;+    }++    return error;+  }+++  static FT_Error+  ft_stroke_border_moveto( FT_StrokeBorder  border,+                           FT_Vector*       to )+  {+    /* close current open path if any ? */+    if ( border->start >= 0 )+      ft_stroke_border_close( border, FALSE );++    border->start   = border->num_points;+    border->movable = FALSE;++    return ft_stroke_border_lineto( border, to, FALSE );+  }+++  static void+  ft_stroke_border_init( FT_StrokeBorder  border,+                         FT_Memory        memory )+  {+    border->memory = memory;+    border->points = NULL;+    border->tags   = NULL;++    border->num_points = 0;+    border->max_points = 0;+    border->start      = -1;+    border->valid      = FALSE;+  }+++  static void+  ft_stroke_border_reset( FT_StrokeBorder  border )+  {+    border->num_points = 0;+    border->start      = -1;+    border->valid      = FALSE;+  }+++  static void+  ft_stroke_border_done( FT_StrokeBorder  border )+  {+    FT_Memory  memory = border->memory;+++    FT_FREE( border->points );+    FT_FREE( border->tags );++    border->num_points = 0;+    border->max_points = 0;+    border->start      = -1;+    border->valid      = FALSE;+  }+++  static FT_Error+  ft_stroke_border_get_counts( FT_StrokeBorder  border,+                               FT_UInt         *anum_points,+                               FT_UInt         *anum_contours )+  {+    FT_Error  error        = FT_Err_Ok;+    FT_UInt   num_points   = 0;+    FT_UInt   num_contours = 0;++    FT_UInt     count      = border->num_points;+    FT_Vector*  point      = border->points;+    FT_Byte*    tags       = border->tags;+    FT_Int      in_contour = 0;+++    for ( ; count > 0; count--, num_points++, point++, tags++ )+    {+      if ( tags[0] & FT_STROKE_TAG_BEGIN )+      {+        if ( in_contour != 0 )+          goto Fail;++        in_contour = 1;+      }+      else if ( in_contour == 0 )+        goto Fail;++      if ( tags[0] & FT_STROKE_TAG_END )+      {+        in_contour = 0;+        num_contours++;+      }+    }++    if ( in_contour != 0 )+      goto Fail;++    border->valid = TRUE;++  Exit:+    *anum_points   = num_points;+    *anum_contours = num_contours;+    return error;++  Fail:+    num_points   = 0;+    num_contours = 0;+    goto Exit;+  }+++  static void+  ft_stroke_border_export( FT_StrokeBorder  border,+                           FT_Outline*      outline )+  {+    /* copy point locations */+    FT_ARRAY_COPY( outline->points + outline->n_points,+                   border->points,+                   border->num_points );++    /* copy tags */+    {+      FT_UInt   count = border->num_points;+      FT_Byte*  read  = border->tags;+      FT_Byte*  write = (FT_Byte*)outline->tags + outline->n_points;+++      for ( ; count > 0; count--, read++, write++ )+      {+        if ( *read & FT_STROKE_TAG_ON )+          *write = FT_CURVE_TAG_ON;+        else if ( *read & FT_STROKE_TAG_CUBIC )+          *write = FT_CURVE_TAG_CUBIC;+        else+          *write = FT_CURVE_TAG_CONIC;+      }+    }++    /* copy contours */+    {+      FT_UInt    count = border->num_points;+      FT_Byte*   tags  = border->tags;+      FT_Short*  write = outline->contours + outline->n_contours;+      FT_Short   idx   = (FT_Short)outline->n_points;+++      for ( ; count > 0; count--, tags++, idx++ )+      {+        if ( *tags & FT_STROKE_TAG_END )+        {+          *write++ = idx;+          outline->n_contours++;+        }+      }+    }++    outline->n_points  = (short)( outline->n_points + border->num_points );++    FT_ASSERT( FT_Outline_Check( outline ) == 0 );+  }+++ /***************************************************************************/+ /***************************************************************************/+ /*****                                                                 *****/+ /*****                           STROKER                               *****/+ /*****                                                                 *****/+ /***************************************************************************/+ /***************************************************************************/++#define FT_SIDE_TO_ROTATE( s )   ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI )++  typedef struct  FT_StrokerRec_+  {+    FT_Angle             angle_in;+    FT_Angle             angle_out;+    FT_Vector            center;+    FT_Bool              first_point;+    FT_Bool              subpath_open;+    FT_Angle             subpath_angle;+    FT_Vector            subpath_start;++    FT_Stroker_LineCap   line_cap;+    FT_Stroker_LineJoin  line_join;+    FT_Fixed             miter_limit;+    FT_Fixed             radius;++    FT_Bool              valid;+    FT_StrokeBorderRec   borders[2];+    FT_Library           library;++  } FT_StrokerRec;+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_New( FT_Library   library,+                  FT_Stroker  *astroker )+  {+    FT_Error    error;+    FT_Memory   memory;+    FT_Stroker  stroker;+++    if ( !library )+      return FT_Err_Invalid_Argument;++    memory = library->memory;++    if ( !FT_NEW( stroker ) )+    {+      stroker->library = library;++      ft_stroke_border_init( &stroker->borders[0], memory );+      ft_stroke_border_init( &stroker->borders[1], memory );+    }+    *astroker = stroker;+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( void )+  FT_Stroker_Set( FT_Stroker           stroker,+                  FT_Fixed             radius,+                  FT_Stroker_LineCap   line_cap,+                  FT_Stroker_LineJoin  line_join,+                  FT_Fixed             miter_limit )+  {+    stroker->radius      = radius;+    stroker->line_cap    = line_cap;+    stroker->line_join   = line_join;+    stroker->miter_limit = miter_limit;++    FT_Stroker_Rewind( stroker );+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( void )+  FT_Stroker_Rewind( FT_Stroker  stroker )+  {+    if ( stroker )+    {+      ft_stroke_border_reset( &stroker->borders[0] );+      ft_stroke_border_reset( &stroker->borders[1] );+    }+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( void )+  FT_Stroker_Done( FT_Stroker  stroker )+  {+    if ( stroker )+    {+      FT_Memory  memory = stroker->library->memory;+++      ft_stroke_border_done( &stroker->borders[0] );+      ft_stroke_border_done( &stroker->borders[1] );++      stroker->library = NULL;+      FT_FREE( stroker );+    }+  }+++  /* creates a circular arc at a corner or cap */+  static FT_Error+  ft_stroker_arcto( FT_Stroker  stroker,+                    FT_Int      side )+  {+    FT_Angle         total, rotate;+    FT_Fixed         radius = stroker->radius;+    FT_Error         error  = FT_Err_Ok;+    FT_StrokeBorder  border = stroker->borders + side;+++    rotate = FT_SIDE_TO_ROTATE( side );++    total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );+    if ( total == FT_ANGLE_PI )+      total = -rotate * 2;++    error = ft_stroke_border_arcto( border,+                                    &stroker->center,+                                    radius,+                                    stroker->angle_in + rotate,+                                    total );+    border->movable = FALSE;+    return error;+  }+++  /* adds a cap at the end of an opened path */+  static FT_Error+  ft_stroker_cap( FT_Stroker  stroker,+                  FT_Angle    angle,+                  FT_Int      side )+  {+    FT_Error  error = FT_Err_Ok;+++    if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND )+    {+      /* add a round cap */+      stroker->angle_in  = angle;+      stroker->angle_out = angle + FT_ANGLE_PI;+      error = ft_stroker_arcto( stroker, side );+    }+    else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )+    {+      /* add a square cap */+      FT_Vector        delta, delta2;+      FT_Angle         rotate = FT_SIDE_TO_ROTATE( side );+      FT_Fixed         radius = stroker->radius;+      FT_StrokeBorder  border = stroker->borders + side;+++      FT_Vector_From_Polar( &delta2, radius, angle + rotate );+      FT_Vector_From_Polar( &delta,  radius, angle );++      delta.x += stroker->center.x + delta2.x;+      delta.y += stroker->center.y + delta2.y;++      error = ft_stroke_border_lineto( border, &delta, FALSE );+      if ( error )+        goto Exit;++      FT_Vector_From_Polar( &delta2, radius, angle - rotate );+      FT_Vector_From_Polar( &delta,  radius, angle );++      delta.x += delta2.x + stroker->center.x;+      delta.y += delta2.y + stroker->center.y;++      error = ft_stroke_border_lineto( border, &delta, FALSE );+    }+    else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT )+    {+      /* add a butt ending */+      FT_Vector        delta;+      FT_Angle         rotate = FT_SIDE_TO_ROTATE( side );+      FT_Fixed         radius = stroker->radius;+      FT_StrokeBorder  border = stroker->borders + side;+++      FT_Vector_From_Polar( &delta, radius, angle + rotate );++      delta.x += stroker->center.x;+      delta.y += stroker->center.y;++      error = ft_stroke_border_lineto( border, &delta, FALSE );+      if ( error )+        goto Exit;++      FT_Vector_From_Polar( &delta, radius, angle - rotate );++      delta.x += stroker->center.x;+      delta.y += stroker->center.y;++      error = ft_stroke_border_lineto( border, &delta, FALSE );   +    }++  Exit:+    return error;+  }+++  /* process an inside corner, i.e. compute intersection */+  static FT_Error+  ft_stroker_inside( FT_Stroker  stroker,+                     FT_Int      side)+  {+    FT_StrokeBorder  border = stroker->borders + side;+    FT_Angle         phi, theta, rotate;+    FT_Fixed         length, thcos, sigma;+    FT_Vector        delta;+    FT_Error         error = FT_Err_Ok;+++    rotate = FT_SIDE_TO_ROTATE( side );++    /* compute median angle */+    theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );+    if ( theta == FT_ANGLE_PI )+      theta = rotate;+    else+      theta = theta / 2;++    phi = stroker->angle_in + theta;++    thcos = FT_Cos( theta );+    sigma = FT_MulFix( stroker->miter_limit, thcos );++    /* TODO: find better criterion to switch off the optimization */+    if ( sigma < 0x10000L )+    {+      FT_Vector_From_Polar( &delta, stroker->radius,+                            stroker->angle_out + rotate );+      delta.x += stroker->center.x;+      delta.y += stroker->center.y;+      border->movable = FALSE;+    }+    else+    {+      length = FT_DivFix( stroker->radius, thcos );++      FT_Vector_From_Polar( &delta, length, phi + rotate );+      delta.x += stroker->center.x;+      delta.y += stroker->center.y;+    }++    error = ft_stroke_border_lineto( border, &delta, FALSE );++    return error;+  }+++  /* process an outside corner, i.e. compute bevel/miter/round */+  static FT_Error+  ft_stroker_outside( FT_Stroker  stroker,+                      FT_Int      side )+  {+    FT_StrokeBorder  border = stroker->borders + side;+    FT_Error         error;+    FT_Angle         rotate;+++    if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND )+      error = ft_stroker_arcto( stroker, side );+    else+    {+      /* this is a mitered or beveled corner */+      FT_Fixed  sigma, radius = stroker->radius;+      FT_Angle  theta, phi;+      FT_Fixed  thcos;+      FT_Bool   miter;+++      rotate = FT_SIDE_TO_ROTATE( side );+      miter  = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER );++      theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );+      if ( theta == FT_ANGLE_PI )+      {+        theta = rotate;+        phi   = stroker->angle_in;+      }+      else+      {+        theta = theta / 2;+        phi   = stroker->angle_in + theta + rotate;+      }++      thcos = FT_Cos( theta );+      sigma = FT_MulFix( stroker->miter_limit, thcos );++      /* FT_Sin(x) = 0 for x <= 57 */+      if ( sigma >= 0x10000L || ft_pos_abs( theta ) <= 57 )+        miter = FALSE;++      if ( miter )  /* this is a miter (broken angle) */+      {+        FT_Vector  middle, delta;+        FT_Fixed   length;+++        /* compute middle point */+        FT_Vector_From_Polar( &middle,+                              FT_MulFix( radius, stroker->miter_limit ),+                              phi );+        middle.x += stroker->center.x;+        middle.y += stroker->center.y;++        /* compute first angle point */+        length = FT_MulFix( radius,+                            FT_DivFix( 0x10000L - sigma,+                                       ft_pos_abs( FT_Sin( theta ) ) ) );++        FT_Vector_From_Polar( &delta, length, phi + rotate );+        delta.x += middle.x;+        delta.y += middle.y;++        error = ft_stroke_border_lineto( border, &delta, FALSE );+        if ( error )+          goto Exit;++        /* compute second angle point */+        FT_Vector_From_Polar( &delta, length, phi - rotate );+        delta.x += middle.x;+        delta.y += middle.y;++        error = ft_stroke_border_lineto( border, &delta, FALSE );+        if ( error )+          goto Exit;++        /* finally, add a movable end point */+        FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate );+        delta.x += stroker->center.x;+        delta.y += stroker->center.y;++        error = ft_stroke_border_lineto( border, &delta, TRUE );+      }++      else /* this is a bevel (intersection) */+      {+        FT_Fixed   length;+        FT_Vector  delta;+++        length = FT_DivFix( stroker->radius, thcos );++        FT_Vector_From_Polar( &delta, length, phi );+        delta.x += stroker->center.x;+        delta.y += stroker->center.y;++        error = ft_stroke_border_lineto( border, &delta, FALSE );+        if ( error )+          goto Exit;++        /* now add end point */+        FT_Vector_From_Polar( &delta, stroker->radius,+                              stroker->angle_out + rotate );+        delta.x += stroker->center.x;+        delta.y += stroker->center.y;++        error = ft_stroke_border_lineto( border, &delta, TRUE );+      }+    }++  Exit:+    return error;+  }+++  static FT_Error+  ft_stroker_process_corner( FT_Stroker  stroker )+  {+    FT_Error  error = FT_Err_Ok;+    FT_Angle  turn;+    FT_Int    inside_side;+++    turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );++    /* no specific corner processing is required if the turn is 0 */+    if ( turn == 0 )+      goto Exit;++    /* when we turn to the right, the inside side is 0 */+    inside_side = 0;++    /* otherwise, the inside side is 1 */+    if ( turn < 0 )+      inside_side = 1;++    /* process the inside side */+    error = ft_stroker_inside( stroker, inside_side );+    if ( error )+      goto Exit;++    /* process the outside side */+    error = ft_stroker_outside( stroker, 1 - inside_side );++  Exit:+    return error;+  }+++  /* add two points to the left and right borders corresponding to the */+  /* start of the subpath                                              */+  static FT_Error+  ft_stroker_subpath_start( FT_Stroker  stroker,+                            FT_Angle    start_angle )+  {+    FT_Vector        delta;+    FT_Vector        point;+    FT_Error         error;+    FT_StrokeBorder  border;+++    FT_Vector_From_Polar( &delta, stroker->radius,+                          start_angle + FT_ANGLE_PI2 );++    point.x = stroker->center.x + delta.x;+    point.y = stroker->center.y + delta.y;++    border = stroker->borders;+    error = ft_stroke_border_moveto( border, &point );+    if ( error )+      goto Exit;++    point.x = stroker->center.x - delta.x;+    point.y = stroker->center.y - delta.y;++    border++;+    error = ft_stroke_border_moveto( border, &point );++    /* save angle for last cap */+    stroker->subpath_angle = start_angle;+    stroker->first_point   = FALSE;++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_LineTo( FT_Stroker  stroker,+                     FT_Vector*  to )+  {+    FT_Error         error = FT_Err_Ok;+    FT_StrokeBorder  border;+    FT_Vector        delta;+    FT_Angle         angle;+    FT_Int           side;++    delta.x = to->x - stroker->center.x;+    delta.y = to->y - stroker->center.y;++    angle = FT_Atan2( delta.x, delta.y );+    FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 );++    /* process corner if necessary */+    if ( stroker->first_point )+    {+      /* This is the first segment of a subpath.  We need to     */+      /* add a point to each border at their respective starting */+      /* point locations.                                        */+      error = ft_stroker_subpath_start( stroker, angle );+      if ( error )+        goto Exit;+    }+    else+    {+      /* process the current corner */+      stroker->angle_out = angle;+      error = ft_stroker_process_corner( stroker );+      if ( error )+        goto Exit;+    }++    /* now add a line segment to both the `inside' and `outside' paths */++    for ( border = stroker->borders, side = 1; side >= 0; side--, border++ )+    {+      FT_Vector  point;+++      point.x = to->x + delta.x;+      point.y = to->y + delta.y;++      error = ft_stroke_border_lineto( border, &point, TRUE );+      if ( error )+        goto Exit;++      delta.x = -delta.x;+      delta.y = -delta.y;+    }++    stroker->angle_in = angle;+    stroker->center   = *to;++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_ConicTo( FT_Stroker  stroker,+                      FT_Vector*  control,+                      FT_Vector*  to )+  {+    FT_Error    error = FT_Err_Ok;+    FT_Vector   bez_stack[34];+    FT_Vector*  arc;+    FT_Vector*  limit = bez_stack + 30;+    FT_Angle    start_angle;+    FT_Bool     first_arc = TRUE;+++    arc    = bez_stack;+    arc[0] = *to;+    arc[1] = *control;+    arc[2] = stroker->center;++    while ( arc >= bez_stack )+    {+      FT_Angle  angle_in, angle_out;+++      angle_in = angle_out = 0;  /* remove compiler warnings */++      if ( arc < limit                                             &&+           !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) )+      {+        ft_conic_split( arc );+        arc += 2;+        continue;+      }++      if ( first_arc )+      {+        first_arc = FALSE;++        start_angle = angle_in;++        /* process corner if necessary */+        if ( stroker->first_point )+          error = ft_stroker_subpath_start( stroker, start_angle );+        else+        {+          stroker->angle_out = start_angle;+          error = ft_stroker_process_corner( stroker );+        }+      }++      /* the arc's angle is small enough; we can add it directly to each */+      /* border                                                          */+      {+        FT_Vector  ctrl, end;+        FT_Angle   theta, phi, rotate;+        FT_Fixed   length;+        FT_Int     side;+++        theta  = FT_Angle_Diff( angle_in, angle_out ) / 2;+        phi    = angle_in + theta;+        length = FT_DivFix( stroker->radius, FT_Cos( theta ) );++        for ( side = 0; side <= 1; side++ )+        {+          rotate = FT_SIDE_TO_ROTATE( side );++          /* compute control point */+          FT_Vector_From_Polar( &ctrl, length, phi + rotate );+          ctrl.x += arc[1].x;+          ctrl.y += arc[1].y;++          /* compute end point */+          FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate );+          end.x += arc[0].x;+          end.y += arc[0].y;++          error = ft_stroke_border_conicto( stroker->borders + side,+                                            &ctrl, &end );+          if ( error )+            goto Exit;+        }+      }++      arc -= 2;++      if ( arc < bez_stack )+        stroker->angle_in = angle_out;+    }++    stroker->center = *to;++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_CubicTo( FT_Stroker  stroker,+                      FT_Vector*  control1,+                      FT_Vector*  control2,+                      FT_Vector*  to )+  {+    FT_Error    error = FT_Err_Ok;+    FT_Vector   bez_stack[37];+    FT_Vector*  arc;+    FT_Vector*  limit = bez_stack + 32;+    FT_Angle    start_angle;+    FT_Bool     first_arc = TRUE;+++    arc    = bez_stack;+    arc[0] = *to;+    arc[1] = *control2;+    arc[2] = *control1;+    arc[3] = stroker->center;++    while ( arc >= bez_stack )+    {+      FT_Angle  angle_in, angle_mid, angle_out;+++      /* remove compiler warnings */+      angle_in = angle_out = angle_mid = 0;++      if ( arc < limit                                         &&+           !ft_cubic_is_small_enough( arc, &angle_in,+                                      &angle_mid, &angle_out ) )+      {+        ft_cubic_split( arc );+        arc += 3;+        continue;+      }++      if ( first_arc )+      {+        first_arc = FALSE;++        /* process corner if necessary */+        start_angle = angle_in;++        if ( stroker->first_point )+          error = ft_stroker_subpath_start( stroker, start_angle );+        else+        {+          stroker->angle_out = start_angle;+          error = ft_stroker_process_corner( stroker );+        }+        if ( error )+          goto Exit;+      }++      /* the arc's angle is small enough; we can add it directly to each */+      /* border                                                          */+      {+        FT_Vector  ctrl1, ctrl2, end;+        FT_Angle   theta1, phi1, theta2, phi2, rotate;+        FT_Fixed   length1, length2;+        FT_Int     side;+++        theta1  = ft_pos_abs( angle_mid - angle_in ) / 2;+        theta2  = ft_pos_abs( angle_out - angle_mid ) / 2;+        phi1    = (angle_mid + angle_in ) / 2;+        phi2    = (angle_mid + angle_out ) / 2;+        length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) );+        length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) );++        for ( side = 0; side <= 1; side++ )+        {+          rotate = FT_SIDE_TO_ROTATE( side );++          /* compute control points */+          FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate );+          ctrl1.x += arc[2].x;+          ctrl1.y += arc[2].y;++          FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate );+          ctrl2.x += arc[1].x;+          ctrl2.y += arc[1].y;++          /* compute end point */+          FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate );+          end.x += arc[0].x;+          end.y += arc[0].y;++          error = ft_stroke_border_cubicto( stroker->borders + side,+                                            &ctrl1, &ctrl2, &end );+          if ( error )+            goto Exit;+        }+      }++      arc -= 3;+      if ( arc < bez_stack )+        stroker->angle_in = angle_out;+    }++    stroker->center = *to;++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_BeginSubPath( FT_Stroker  stroker,+                           FT_Vector*  to,+                           FT_Bool     open )+  {+    /* We cannot process the first point, because there is not enough      */+    /* information regarding its corner/cap.  The latter will be processed */+    /* in the `FT_Stroker_EndSubPath' routine.                             */+    /*                                                                     */+    stroker->first_point  = TRUE;+    stroker->center       = *to;+    stroker->subpath_open = open;++    /* record the subpath start point for each border */+    stroker->subpath_start = *to;++    return FT_Err_Ok;+  }+++  static FT_Error+  ft_stroker_add_reverse_left( FT_Stroker  stroker,+                               FT_Bool     open )+  {+    FT_StrokeBorder  right = stroker->borders + 0;+    FT_StrokeBorder  left  = stroker->borders + 1;+    FT_Int           new_points;+    FT_Error         error = FT_Err_Ok;+++    FT_ASSERT( left->start >= 0 );++    new_points = left->num_points - left->start;+    if ( new_points > 0 )+    {+      error = ft_stroke_border_grow( right, (FT_UInt)new_points );+      if ( error )+        goto Exit;++      {+        FT_Vector*  dst_point = right->points + right->num_points;+        FT_Byte*    dst_tag   = right->tags   + right->num_points;+        FT_Vector*  src_point = left->points  + left->num_points - 1;+        FT_Byte*    src_tag   = left->tags    + left->num_points - 1;++        while ( src_point >= left->points + left->start )+        {+          *dst_point = *src_point;+          *dst_tag   = *src_tag;++          if ( open )+            dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END;+          else+          {+            FT_Byte  ttag = (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END );+++            /* switch begin/end tags if necessary */+            if ( ttag == FT_STROKE_TAG_BEGIN ||+                 ttag == FT_STROKE_TAG_END   )+              dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END;++          }++          src_point--;+          src_tag--;+          dst_point++;+          dst_tag++;+        }+      }++      left->num_points   = left->start;+      right->num_points += new_points;++      right->movable = FALSE;+      left->movable  = FALSE;+    }++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  /* there's a lot of magic in this function! */+  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_EndSubPath( FT_Stroker  stroker )+  {+    FT_Error  error = FT_Err_Ok;+++    if ( stroker->subpath_open )+    {+      FT_StrokeBorder  right = stroker->borders;++      /* All right, this is an opened path, we need to add a cap between */+      /* right & left, add the reverse of left, then add a final cap     */+      /* between left & right.                                           */+      error = ft_stroker_cap( stroker, stroker->angle_in, 0 );+      if ( error )+        goto Exit;++      /* add reversed points from `left' to `right' */+      error = ft_stroker_add_reverse_left( stroker, TRUE );+      if ( error )+        goto Exit;++      /* now add the final cap */+      stroker->center = stroker->subpath_start;+      error = ft_stroker_cap( stroker,+                              stroker->subpath_angle + FT_ANGLE_PI, 0 );+      if ( error )+        goto Exit;++      /* Now end the right subpath accordingly.  The left one is */+      /* rewind and doesn't need further processing.             */+      ft_stroke_border_close( right, FALSE );+    }+    else+    {+      FT_Angle  turn;+      FT_Int    inside_side;++      /* close the path if needed */+      if ( stroker->center.x != stroker->subpath_start.x ||+           stroker->center.y != stroker->subpath_start.y )+      {+        error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );+        if ( error )+          goto Exit;+      }++      /* process the corner */+      stroker->angle_out = stroker->subpath_angle;+      turn               = FT_Angle_Diff( stroker->angle_in,+                                          stroker->angle_out );++      /* no specific corner processing is required if the turn is 0 */+      if ( turn != 0 )+      {+        /* when we turn to the right, the inside side is 0 */+        inside_side = 0;++        /* otherwise, the inside side is 1 */+        if ( turn < 0 )+          inside_side = 1;++        error = ft_stroker_inside( stroker, inside_side );+        if ( error )+          goto Exit;++        /* process the outside side */+        error = ft_stroker_outside( stroker, 1 - inside_side );+        if ( error )+          goto Exit;+      }++      /* then end our two subpaths */+      ft_stroke_border_close( stroker->borders + 0, TRUE );+      ft_stroke_border_close( stroker->borders + 1, FALSE );+    }++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_GetBorderCounts( FT_Stroker        stroker,+                              FT_StrokerBorder  border,+                              FT_UInt          *anum_points,+                              FT_UInt          *anum_contours )+  {+    FT_UInt   num_points = 0, num_contours = 0;+    FT_Error  error;+++    if ( !stroker || border > 1 )+    {+      error = FT_Err_Invalid_Argument;+      goto Exit;+    }++    error = ft_stroke_border_get_counts( stroker->borders + border,+                                         &num_points, &num_contours );+  Exit:+    if ( anum_points )+      *anum_points = num_points;++    if ( anum_contours )+      *anum_contours = num_contours;++    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_GetCounts( FT_Stroker  stroker,+                        FT_UInt    *anum_points,+                        FT_UInt    *anum_contours )+  {+    FT_UInt   count1, count2, num_points   = 0;+    FT_UInt   count3, count4, num_contours = 0;+    FT_Error  error;+++    error = ft_stroke_border_get_counts( stroker->borders + 0,+                                         &count1, &count2 );+    if ( error )+      goto Exit;++    error = ft_stroke_border_get_counts( stroker->borders + 1,+                                         &count3, &count4 );+    if ( error )+      goto Exit;++    num_points   = count1 + count3;+    num_contours = count2 + count4;++  Exit:+    *anum_points   = num_points;+    *anum_contours = num_contours;+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( void )+  FT_Stroker_ExportBorder( FT_Stroker        stroker,+                           FT_StrokerBorder  border,+                           FT_Outline*       outline )+  {+    if ( border == FT_STROKER_BORDER_LEFT  ||+         border == FT_STROKER_BORDER_RIGHT )+    {+      FT_StrokeBorder  sborder = & stroker->borders[border];+++      if ( sborder->valid )+        ft_stroke_border_export( sborder, outline );+    }+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( void )+  FT_Stroker_Export( FT_Stroker   stroker,+                     FT_Outline*  outline )+  {+    FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline );+    FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline );+  }+++  /* documentation is in ftstroke.h */++  /*+   *  The following is very similar to FT_Outline_Decompose, except+   *  that we do support opened paths, and do not scale the outline.+   */+  FT_EXPORT_DEF( FT_Error )+  FT_Stroker_ParseOutline( FT_Stroker   stroker,+                           FT_Outline*  outline,+                           FT_Bool      opened )+  {+    FT_Vector   v_last;+    FT_Vector   v_control;+    FT_Vector   v_start;++    FT_Vector*  point;+    FT_Vector*  limit;+    char*       tags;++    FT_Error    error;++    FT_Int   n;         /* index of contour in outline     */+    FT_UInt  first;     /* index of first point in contour */+    FT_Int   tag;       /* current point's state           */+++    if ( !outline || !stroker )+      return FT_Err_Invalid_Argument;++    FT_Stroker_Rewind( stroker );++    first = 0;++    for ( n = 0; n < outline->n_contours; n++ )+    {+      FT_UInt  last;  /* index of last point in contour */+++      last  = outline->contours[n];+      limit = outline->points + last;++      /* skip empty points; we don't stroke these */+      if ( last <= first )+      {+        first = last + 1;+        continue;+      }++      v_start = outline->points[first];+      v_last  = outline->points[last];++      v_control = v_start;++      point = outline->points + first;+      tags  = outline->tags   + first;+      tag   = FT_CURVE_TAG( tags[0] );++      /* A contour cannot start with a cubic control point! */+      if ( tag == FT_CURVE_TAG_CUBIC )+        goto Invalid_Outline;++      /* check first point to determine origin */+      if ( tag == FT_CURVE_TAG_CONIC )+      {+        /* First point is conic control.  Yes, this happens. */+        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )+        {+          /* start at last point if it is on the curve */+          v_start = v_last;+          limit--;+        }+        else+        {+          /* if both first and last points are conic, */+          /* start at their middle                    */+          v_start.x = ( v_start.x + v_last.x ) / 2;+          v_start.y = ( v_start.y + v_last.y ) / 2;+        }+        point--;+        tags--;+      }++      error = FT_Stroker_BeginSubPath( stroker, &v_start, opened );+      if ( error )+        goto Exit;++      while ( point < limit )+      {+        point++;+        tags++;++        tag = FT_CURVE_TAG( tags[0] );+        switch ( tag )+        {+        case FT_CURVE_TAG_ON:  /* emit a single line_to */+          {+            FT_Vector  vec;+++            vec.x = point->x;+            vec.y = point->y;++            error = FT_Stroker_LineTo( stroker, &vec );+            if ( error )+              goto Exit;+            continue;+          }++        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */+          v_control.x = point->x;+          v_control.y = point->y;++        Do_Conic:+          if ( point < limit )+          {+            FT_Vector  vec;+            FT_Vector  v_middle;+++            point++;+            tags++;+            tag = FT_CURVE_TAG( tags[0] );++            vec = point[0];++            if ( tag == FT_CURVE_TAG_ON )+            {+              error = FT_Stroker_ConicTo( stroker, &v_control, &vec );+              if ( error )+                goto Exit;+              continue;+            }++            if ( tag != FT_CURVE_TAG_CONIC )+              goto Invalid_Outline;++            v_middle.x = ( v_control.x + vec.x ) / 2;+            v_middle.y = ( v_control.y + vec.y ) / 2;++            error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle );+            if ( error )+              goto Exit;++            v_control = vec;+            goto Do_Conic;+          }++          error = FT_Stroker_ConicTo( stroker, &v_control, &v_start );+          goto Close;++        default:  /* FT_CURVE_TAG_CUBIC */+          {+            FT_Vector  vec1, vec2;+++            if ( point + 1 > limit                             ||+                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )+              goto Invalid_Outline;++            point += 2;+            tags  += 2;++            vec1 = point[-2];+            vec2 = point[-1];++            if ( point <= limit )+            {+              FT_Vector  vec;+++              vec = point[0];++              error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec );+              if ( error )+                goto Exit;+              continue;+            }++            error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start );+            goto Close;+          }+        }+      }++    Close:+      if ( error )+        goto Exit;++      error = FT_Stroker_EndSubPath( stroker );+      if ( error )+        goto Exit;++      first = last + 1;+    }++    return FT_Err_Ok;++  Exit:+    return error;++  Invalid_Outline:+    return FT_Err_Invalid_Outline;+  }++/* declare an extern to access ft_outline_glyph_class global allocated +   in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access +   it when FT_CONFIG_OPTION_PIC is defined */+#ifndef FT_CONFIG_OPTION_PIC+  extern const FT_Glyph_Class  ft_outline_glyph_class;+#endif+#include "basepic.h"+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Glyph_Stroke( FT_Glyph    *pglyph,+                   FT_Stroker   stroker,+                   FT_Bool      destroy )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+    FT_Glyph  glyph = NULL;+    FT_Library library = stroker->library;+    FT_UNUSED(library);++    if ( pglyph == NULL )+      goto Exit;++    glyph = *pglyph;+    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )+      goto Exit;++    {+      FT_Glyph  copy;+++      error = FT_Glyph_Copy( glyph, &copy );+      if ( error )+        goto Exit;++      glyph = copy;+    }++    {+      FT_OutlineGlyph  oglyph  = (FT_OutlineGlyph) glyph;+      FT_Outline*      outline = &oglyph->outline;+      FT_UInt          num_points, num_contours;+++      error = FT_Stroker_ParseOutline( stroker, outline, FALSE );+      if ( error )+        goto Fail;++      (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours );++      FT_Outline_Done( glyph->library, outline );++      error = FT_Outline_New( glyph->library,+                              num_points, num_contours, outline );+      if ( error )+        goto Fail;++      outline->n_points   = 0;+      outline->n_contours = 0;++      FT_Stroker_Export( stroker, outline );+    }++    if ( destroy )+      FT_Done_Glyph( *pglyph );++    *pglyph = glyph;+    goto Exit;++  Fail:+    FT_Done_Glyph( glyph );+    glyph = NULL;++    if ( !destroy )+      *pglyph = NULL;++  Exit:+    return error;+  }+++  /* documentation is in ftstroke.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Glyph_StrokeBorder( FT_Glyph    *pglyph,+                         FT_Stroker   stroker,+                         FT_Bool      inside,+                         FT_Bool      destroy )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+    FT_Glyph  glyph = NULL;+    FT_Library library = stroker->library;+    FT_UNUSED(library);++    if ( pglyph == NULL )+      goto Exit;++    glyph = *pglyph;+    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )+      goto Exit;++    {+      FT_Glyph  copy;+++      error = FT_Glyph_Copy( glyph, &copy );+      if ( error )+        goto Exit;++      glyph = copy;+    }++    {+      FT_OutlineGlyph   oglyph  = (FT_OutlineGlyph) glyph;+      FT_StrokerBorder  border;+      FT_Outline*       outline = &oglyph->outline;+      FT_UInt           num_points, num_contours;+++      border = FT_Outline_GetOutsideBorder( outline );+      if ( inside )+      {+        if ( border == FT_STROKER_BORDER_LEFT )+          border = FT_STROKER_BORDER_RIGHT;+        else+          border = FT_STROKER_BORDER_LEFT;+      }++      error = FT_Stroker_ParseOutline( stroker, outline, FALSE );+      if ( error )+        goto Fail;++      (void)FT_Stroker_GetBorderCounts( stroker, border,+                                        &num_points, &num_contours );++      FT_Outline_Done( glyph->library, outline );++      error = FT_Outline_New( glyph->library,+                              num_points,+                              num_contours,+                              outline );+      if ( error )+        goto Fail;++      outline->n_points   = 0;+      outline->n_contours = 0;++      FT_Stroker_ExportBorder( stroker, border, outline );+    }++    if ( destroy )+      FT_Done_Glyph( *pglyph );++    *pglyph = glyph;+    goto Exit;++  Fail:+    FT_Done_Glyph( glyph );+    glyph = NULL;++    if ( !destroy )+      *pglyph = NULL;++  Exit:+    return error;+  }+++/* END */
+ src/base/ftsynth.c view
@@ -0,0 +1,160 @@+/***************************************************************************/+/*                                                                         */+/*  ftsynth.c                                                              */+/*                                                                         */+/*    FreeType synthesizing code for emboldening and slanting (body).      */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_SYNTHESIS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_OUTLINE_H+#include FT_BITMAP_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_synth++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****   EXPERIMENTAL OBLIQUING SUPPORT                                ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/++  /* documentation is in ftsynth.h */++  FT_EXPORT_DEF( void )+  FT_GlyphSlot_Oblique( FT_GlyphSlot  slot )+  {+    FT_Matrix    transform;+    FT_Outline*  outline = &slot->outline;+++    /* only oblique outline glyphs */+    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )+      return;++    /* we don't touch the advance width */++    /* For italic, simply apply a shear transform, with an angle */+    /* of about 12 degrees.                                      */++    transform.xx = 0x10000L;+    transform.yx = 0x00000L;++    transform.xy = 0x06000L;+    transform.yy = 0x10000L;++    FT_Outline_Transform( outline, &transform );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****   EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT                    ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+++  /* documentation is in ftsynth.h */++  FT_EXPORT_DEF( void )+  FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )+  {+    FT_Library  library = slot->library;+    FT_Face     face    = slot->face;+    FT_Error    error;+    FT_Pos      xstr, ystr;+++    if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&+         slot->format != FT_GLYPH_FORMAT_BITMAP  )+      return;++    /* some reasonable strength */+    xstr = FT_MulFix( face->units_per_EM,+                      face->size->metrics.y_scale ) / 24;+    ystr = xstr;++    if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )+    {+      /* ignore error */+      (void)FT_Outline_Embolden( &slot->outline, xstr );++      /* this is more than enough for most glyphs; if you need accurate */+      /* values, you have to call FT_Outline_Get_CBox                   */+      xstr = xstr * 2;+      ystr = xstr;+    }+    else /* slot->format == FT_GLYPH_FORMAT_BITMAP */+    {+      /* round to full pixels */+      xstr &= ~63;+      if ( xstr == 0 )+        xstr = 1 << 6;+      ystr &= ~63;++      /*+       * XXX: overflow check for 16-bit system, for compatibility+       *      with FT_GlyphSlot_Embolden() since freetype-2.1.10.+       *      unfortunately, this function return no informations+       *      about the cause of error.+       */+      if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )+      {+        FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));+        FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr ));+        return;+      }+      error = FT_GlyphSlot_Own_Bitmap( slot );+      if ( error )+        return;++      error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr );+      if ( error )+        return;+    }++    if ( slot->advance.x )+      slot->advance.x += xstr;++    if ( slot->advance.y )+      slot->advance.y += ystr;++    slot->metrics.width        += xstr;+    slot->metrics.height       += ystr;+    slot->metrics.horiBearingY += ystr;+    slot->metrics.horiAdvance  += xstr;+    slot->metrics.vertBearingX -= xstr / 2;+    slot->metrics.vertBearingY += ystr;+    slot->metrics.vertAdvance  += ystr;++    /* XXX: 16-bit overflow case must be excluded before here */+    if ( slot->format == FT_GLYPH_FORMAT_BITMAP )+      slot->bitmap_top += (FT_Int)( ystr >> 6 );+  }+++/* END */
+ src/base/ftsystem.c view
@@ -0,0 +1,318 @@+/***************************************************************************/+/*                                                                         */+/*  ftsystem.c                                                             */+/*                                                                         */+/*    ANSI-specific FreeType low-level system interface (body).            */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2006, 2008, 2009, 2010 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* This file contains the default interface used by FreeType to access   */+  /* low-level, i.e. memory management, i/o access as well as thread       */+  /* synchronisation.  It can be replaced by user-specific routines if     */+  /* necessary.                                                            */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_SYSTEM_H+#include FT_ERRORS_H+#include FT_TYPES_H+++  /*************************************************************************/+  /*                                                                       */+  /*                       MEMORY MANAGEMENT INTERFACE                     */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* It is not necessary to do any error checking for the                  */+  /* allocation-related functions.  This will be done by the higher level  */+  /* routines like ft_mem_alloc() or ft_mem_realloc().                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_alloc                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The memory allocation function.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory :: A pointer to the memory object.                          */+  /*                                                                       */+  /*    size   :: The requested size in bytes.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The address of newly allocated block.                              */+  /*                                                                       */+  FT_CALLBACK_DEF( void* )+  ft_alloc( FT_Memory  memory,+            long       size )+  {+    FT_UNUSED( memory );++    return ft_smalloc( size );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_realloc                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The memory reallocation function.                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory   :: A pointer to the memory object.                        */+  /*                                                                       */+  /*    cur_size :: The current size of the allocated memory block.        */+  /*                                                                       */+  /*    new_size :: The newly requested size in bytes.                     */+  /*                                                                       */+  /*    block    :: The current address of the block in memory.            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The address of the reallocated memory block.                       */+  /*                                                                       */+  FT_CALLBACK_DEF( void* )+  ft_realloc( FT_Memory  memory,+              long       cur_size,+              long       new_size,+              void*      block )+  {+    FT_UNUSED( memory );+    FT_UNUSED( cur_size );++    return ft_srealloc( block, new_size );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_free                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The memory release function.                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory  :: A pointer to the memory object.                         */+  /*                                                                       */+  /*    block   :: The address of block in memory to be freed.             */+  /*                                                                       */+  FT_CALLBACK_DEF( void )+  ft_free( FT_Memory  memory,+           void*      block )+  {+    FT_UNUSED( memory );++    ft_sfree( block );+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                     RESOURCE MANAGEMENT INTERFACE                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_io++  /* We use the macro STREAM_FILE for convenience to extract the       */+  /* system-specific stream handle from a given FreeType stream object */+#define STREAM_FILE( stream )  ( (FT_FILE*)stream->descriptor.pointer )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_ansi_stream_close                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The function to close a stream.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A pointer to the stream object.                          */+  /*                                                                       */+  FT_CALLBACK_DEF( void )+  ft_ansi_stream_close( FT_Stream  stream )+  {+    ft_fclose( STREAM_FILE( stream ) );++    stream->descriptor.pointer = NULL;+    stream->size               = 0;+    stream->base               = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_ansi_stream_io                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The function to open a stream.                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A pointer to the stream object.                          */+  /*                                                                       */+  /*    offset :: The position in the data stream to start reading.        */+  /*                                                                       */+  /*    buffer :: The address of buffer to store the read data.            */+  /*                                                                       */+  /*    count  :: The number of bytes to read from the stream.             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The number of bytes actually read.  If `count' is zero (this is,   */+  /*    the function is used for seeking), a non-zero return value         */+  /*    indicates an error.                                                */+  /*                                                                       */+  FT_CALLBACK_DEF( unsigned long )+  ft_ansi_stream_io( FT_Stream       stream,+                     unsigned long   offset,+                     unsigned char*  buffer,+                     unsigned long   count )+  {+    FT_FILE*  file;+++    if ( !count && offset > stream->size )+      return 1;++    file = STREAM_FILE( stream );++    if ( stream->pos != offset )+      ft_fseek( file, offset, SEEK_SET );++    return (unsigned long)ft_fread( buffer, 1, count, file );+  }+++  /* documentation is in ftstream.h */++  FT_BASE_DEF( FT_Error )+  FT_Stream_Open( FT_Stream    stream,+                  const char*  filepathname )+  {+    FT_FILE*  file;+++    if ( !stream )+      return FT_Err_Invalid_Stream_Handle;++    stream->descriptor.pointer = NULL;+    stream->pathname.pointer   = (char*)filepathname;+    stream->base               = 0;+    stream->pos                = 0;+    stream->read               = NULL;+    stream->close              = NULL;++    file = ft_fopen( filepathname, "rb" );+    if ( !file )+    {+      FT_ERROR(( "FT_Stream_Open:"+                 " could not open `%s'\n", filepathname ));++      return FT_Err_Cannot_Open_Resource;+    }++    ft_fseek( file, 0, SEEK_END );+    stream->size = ft_ftell( file );+    if ( !stream->size )+    {+      FT_ERROR(( "FT_Stream_Open:" ));+      FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));+      ft_fclose( file );+      return FT_Err_Cannot_Open_Stream;+    }+    ft_fseek( file, 0, SEEK_SET );++    stream->descriptor.pointer = file;+    stream->read  = ft_ansi_stream_io;+    stream->close = ft_ansi_stream_close;++    FT_TRACE1(( "FT_Stream_Open:" ));+    FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",+                filepathname, stream->size ));++    return FT_Err_Ok;+  }+++#ifdef FT_DEBUG_MEMORY++  extern FT_Int+  ft_mem_debug_init( FT_Memory  memory );++  extern void+  ft_mem_debug_done( FT_Memory  memory );++#endif+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( FT_Memory )+  FT_New_Memory( void )+  {+    FT_Memory  memory;+++    memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) );+    if ( memory )+    {+      memory->user    = 0;+      memory->alloc   = ft_alloc;+      memory->realloc = ft_realloc;+      memory->free    = ft_free;+#ifdef FT_DEBUG_MEMORY+      ft_mem_debug_init( memory );+#endif+    }++    return memory;+  }+++  /* documentation is in ftobjs.h */++  FT_BASE_DEF( void )+  FT_Done_Memory( FT_Memory  memory )+  {+#ifdef FT_DEBUG_MEMORY+    ft_mem_debug_done( memory );+#endif+    ft_sfree( memory );+  }+++/* END */
+ src/base/fttrigon.c view
@@ -0,0 +1,546 @@+/***************************************************************************/+/*                                                                         */+/*  fttrigon.c                                                             */+/*                                                                         */+/*    FreeType trigonometric functions (body).                             */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_TRIGONOMETRY_H+++  /* the following is 0.2715717684432231 * 2^30 */+#define FT_TRIG_COSCALE  0x11616E8EUL++  /* this table was generated for FT_PI = 180L << 16, i.e. degrees */+#define FT_TRIG_MAX_ITERS  23++  static const FT_Fixed+  ft_trig_arctan_table[24] =+  {+    4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,+    58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,+    57L, 29L, 14L, 7L, 4L, 2L, 1L+  };++  /* the Cordic shrink factor, multiplied by 2^32 */+#define FT_TRIG_SCALE    1166391785UL  /* 0x4585BA38UL */+++#ifdef FT_CONFIG_HAS_INT64++  /* multiply a given value by the CORDIC shrink factor */+  static FT_Fixed+  ft_trig_downscale( FT_Fixed  val )+  {+    FT_Fixed  s;+    FT_Int64  v;+++    s   = val;+    val = ( val >= 0 ) ? val : -val;++    v   = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;+    val = (FT_Fixed)( v >> 32 );++    return ( s >= 0 ) ? val : -val;+  }++#else /* !FT_CONFIG_HAS_INT64 */++  /* multiply a given value by the CORDIC shrink factor */+  static FT_Fixed+  ft_trig_downscale( FT_Fixed  val )+  {+    FT_Fixed   s;+    FT_UInt32  v1, v2, k1, k2, hi, lo1, lo2, lo3;+++    s   = val;+    val = ( val >= 0 ) ? val : -val;++    v1 = (FT_UInt32)val >> 16;+    v2 = (FT_UInt32)(val & 0xFFFFL);++    k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;       /* constant */+    k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL);   /* constant */++    hi   = k1 * v1;+    lo1  = k1 * v2 + k2 * v1;       /* can't overflow */++    lo2  = ( k2 * v2 ) >> 16;+    lo3  = ( lo1 >= lo2 ) ? lo1 : lo2;+    lo1 += lo2;++    hi  += lo1 >> 16;+    if ( lo1 < lo3 )+      hi += (FT_UInt32)0x10000UL;++    val  = (FT_Fixed)hi;++    return ( s >= 0 ) ? val : -val;+  }++#endif /* !FT_CONFIG_HAS_INT64 */+++  static FT_Int+  ft_trig_prenorm( FT_Vector*  vec )+  {+    FT_Fixed  x, y, z;+    FT_Int    shift;+++    x = vec->x;+    y = vec->y;++    z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );+    shift = 0;++#if 1+    /* determine msb bit index in `shift' */+    if ( z >= ( 1L << 16 ) )+    {+      z     >>= 16;+      shift  += 16;+    }+    if ( z >= ( 1L << 8 ) )+    {+      z     >>= 8;+      shift  += 8;+    }+    if ( z >= ( 1L << 4 ) )+    {+      z     >>= 4;+      shift  += 4;+    }+    if ( z >= ( 1L << 2 ) )+    {+      z     >>= 2;+      shift  += 2;+    }+    if ( z >= ( 1L << 1 ) )+    {+      z    >>= 1;+      shift += 1;+    }++    if ( shift <= 27 )+    {+      shift  = 27 - shift;+      vec->x = x << shift;+      vec->y = y << shift;+    }+    else+    {+      shift -= 27;+      vec->x = x >> shift;+      vec->y = y >> shift;+      shift  = -shift;+    }++#else /* 0 */++    if ( z < ( 1L << 27 ) )+    {+      do+      {+        shift++;+        z <<= 1;+      } while ( z < ( 1L << 27 ) );+      vec->x = x << shift;+      vec->y = y << shift;+    }+    else if ( z > ( 1L << 28 ) )+    {+      do+      {+        shift++;+        z >>= 1;+      } while ( z > ( 1L << 28 ) );++      vec->x = x >> shift;+      vec->y = y >> shift;+      shift  = -shift;+    }++#endif /* 0 */++    return shift;+  }+++  static void+  ft_trig_pseudo_rotate( FT_Vector*  vec,+                         FT_Angle    theta )+  {+    FT_Int           i;+    FT_Fixed         x, y, xtemp;+    const FT_Fixed  *arctanptr;+++    x = vec->x;+    y = vec->y;++    /* Get angle between -90 and 90 degrees */+    while ( theta <= -FT_ANGLE_PI2 )+    {+      x = -x;+      y = -y;+      theta += FT_ANGLE_PI;+    }++    while ( theta > FT_ANGLE_PI2 )+    {+      x = -x;+      y = -y;+      theta -= FT_ANGLE_PI;+    }++    /* Initial pseudorotation, with left shift */+    arctanptr = ft_trig_arctan_table;++    if ( theta < 0 )+    {+      xtemp  = x + ( y << 1 );+      y      = y - ( x << 1 );+      x      = xtemp;+      theta += *arctanptr++;+    }+    else+    {+      xtemp  = x - ( y << 1 );+      y      = y + ( x << 1 );+      x      = xtemp;+      theta -= *arctanptr++;+    }++    /* Subsequent pseudorotations, with right shifts */+    i = 0;+    do+    {+      if ( theta < 0 )+      {+        xtemp  = x + ( y >> i );+        y      = y - ( x >> i );+        x      = xtemp;+        theta += *arctanptr++;+      }+      else+      {+        xtemp  = x - ( y >> i );+        y      = y + ( x >> i );+        x      = xtemp;+        theta -= *arctanptr++;+      }+    } while ( ++i < FT_TRIG_MAX_ITERS );++    vec->x = x;+    vec->y = y;+  }+++  static void+  ft_trig_pseudo_polarize( FT_Vector*  vec )+  {+    FT_Fixed         theta;+    FT_Fixed         yi, i;+    FT_Fixed         x, y;+    const FT_Fixed  *arctanptr;+++    x = vec->x;+    y = vec->y;++    /* Get the vector into the right half plane */+    theta = 0;+    if ( x < 0 )+    {+      x = -x;+      y = -y;+      theta = 2 * FT_ANGLE_PI2;+    }++    if ( y > 0 )+      theta = - theta;++    arctanptr = ft_trig_arctan_table;++    if ( y < 0 )+    {+      /* Rotate positive */+      yi     = y + ( x << 1 );+      x      = x - ( y << 1 );+      y      = yi;+      theta -= *arctanptr++;  /* Subtract angle */+    }+    else+    {+      /* Rotate negative */+      yi     = y - ( x << 1 );+      x      = x + ( y << 1 );+      y      = yi;+      theta += *arctanptr++;  /* Add angle */+    }++    i = 0;+    do+    {+      if ( y < 0 )+      {+        /* Rotate positive */+        yi     = y + ( x >> i );+        x      = x - ( y >> i );+        y      = yi;+        theta -= *arctanptr++;+      }+      else+      {+        /* Rotate negative */+        yi     = y - ( x >> i );+        x      = x + ( y >> i );+        y      = yi;+        theta += *arctanptr++;+      }+    } while ( ++i < FT_TRIG_MAX_ITERS );++    /* round theta */+    if ( theta >= 0 )+      theta = FT_PAD_ROUND( theta, 32 );+    else+      theta = -FT_PAD_ROUND( -theta, 32 );++    vec->x = x;+    vec->y = theta;+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_Cos( FT_Angle  angle )+  {+    FT_Vector  v;+++    v.x = FT_TRIG_COSCALE >> 2;+    v.y = 0;+    ft_trig_pseudo_rotate( &v, angle );++    return v.x / ( 1 << 12 );+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_Sin( FT_Angle  angle )+  {+    return FT_Cos( FT_ANGLE_PI2 - angle );+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_Tan( FT_Angle  angle )+  {+    FT_Vector  v;+++    v.x = FT_TRIG_COSCALE >> 2;+    v.y = 0;+    ft_trig_pseudo_rotate( &v, angle );++    return FT_DivFix( v.y, v.x );+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Angle )+  FT_Atan2( FT_Fixed  dx,+            FT_Fixed  dy )+  {+    FT_Vector  v;+++    if ( dx == 0 && dy == 0 )+      return 0;++    v.x = dx;+    v.y = dy;+    ft_trig_prenorm( &v );+    ft_trig_pseudo_polarize( &v );++    return v.y;+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( void )+  FT_Vector_Unit( FT_Vector*  vec,+                  FT_Angle    angle )+  {+    vec->x = FT_TRIG_COSCALE >> 2;+    vec->y = 0;+    ft_trig_pseudo_rotate( vec, angle );+    vec->x >>= 12;+    vec->y >>= 12;+  }+++  /* these macros return 0 for positive numbers,+     and -1 for negative ones */+#define FT_SIGN_LONG( x )   ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )+#define FT_SIGN_INT( x )    ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )+#define FT_SIGN_INT32( x )  ( (x) >> 31 )+#define FT_SIGN_INT16( x )  ( (x) >> 15 )+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( void )+  FT_Vector_Rotate( FT_Vector*  vec,+                    FT_Angle    angle )+  {+    FT_Int     shift;+    FT_Vector  v;+++    v.x   = vec->x;+    v.y   = vec->y;++    if ( angle && ( v.x != 0 || v.y != 0 ) )+    {+      shift = ft_trig_prenorm( &v );+      ft_trig_pseudo_rotate( &v, angle );+      v.x = ft_trig_downscale( v.x );+      v.y = ft_trig_downscale( v.y );++      if ( shift > 0 )+      {+        FT_Int32  half = (FT_Int32)1L << ( shift - 1 );+++        vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;+        vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;+      }+      else+      {+        shift  = -shift;+        vec->x = v.x << shift;+        vec->y = v.y << shift;+      }+    }+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Fixed )+  FT_Vector_Length( FT_Vector*  vec )+  {+    FT_Int     shift;+    FT_Vector  v;+++    v = *vec;++    /* handle trivial cases */+    if ( v.x == 0 )+    {+      return ( v.y >= 0 ) ? v.y : -v.y;+    }+    else if ( v.y == 0 )+    {+      return ( v.x >= 0 ) ? v.x : -v.x;+    }++    /* general case */+    shift = ft_trig_prenorm( &v );+    ft_trig_pseudo_polarize( &v );++    v.x = ft_trig_downscale( v.x );++    if ( shift > 0 )+      return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;++    return v.x << -shift;+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( void )+  FT_Vector_Polarize( FT_Vector*  vec,+                      FT_Fixed   *length,+                      FT_Angle   *angle )+  {+    FT_Int     shift;+    FT_Vector  v;+++    v = *vec;++    if ( v.x == 0 && v.y == 0 )+      return;++    shift = ft_trig_prenorm( &v );+    ft_trig_pseudo_polarize( &v );++    v.x = ft_trig_downscale( v.x );++    *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );+    *angle  = v.y;+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( void )+  FT_Vector_From_Polar( FT_Vector*  vec,+                        FT_Fixed    length,+                        FT_Angle    angle )+  {+    vec->x = length;+    vec->y = 0;++    FT_Vector_Rotate( vec, angle );+  }+++  /* documentation is in fttrigon.h */++  FT_EXPORT_DEF( FT_Angle )+  FT_Angle_Diff( FT_Angle  angle1,+                 FT_Angle  angle2 )+  {+    FT_Angle  delta = angle2 - angle1;+++    delta %= FT_ANGLE_2PI;+    if ( delta < 0 )+      delta += FT_ANGLE_2PI;++    if ( delta > FT_ANGLE_PI )+      delta -= FT_ANGLE_2PI;++    return delta;+  }+++/* END */
+ src/base/fttype1.c view
@@ -0,0 +1,94 @@+/***************************************************************************/+/*                                                                         */+/*  fttype1.c                                                              */+/*                                                                         */+/*    FreeType utility file for PS names support (body).                   */+/*                                                                         */+/*  Copyright 2002, 2003, 2004 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_SERVICE_H+#include FT_SERVICE_POSTSCRIPT_INFO_H+++  /* documentation is in t1tables.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_PS_Font_Info( FT_Face          face,+                       PS_FontInfoRec*  afont_info )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+++    if ( face )+    {+      FT_Service_PsInfo  service = NULL;+++      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );++      if ( service && service->ps_get_font_info )+        error = service->ps_get_font_info( face, afont_info );+    }++    return error;+  }+++  /* documentation is in t1tables.h */++  FT_EXPORT_DEF( FT_Int )+  FT_Has_PS_Glyph_Names( FT_Face  face )+  {+    FT_Int             result  = 0;+    FT_Service_PsInfo  service = NULL;+++    if ( face )+    {+      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );++      if ( service && service->ps_has_glyph_names )+        result = service->ps_has_glyph_names( face );+    }++    return result;+  }+++  /* documentation is in t1tables.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_PS_Font_Private( FT_Face         face,+                          PS_PrivateRec*  afont_private )+  {+    FT_Error  error = FT_Err_Invalid_Argument;+++    if ( face )+    {+      FT_Service_PsInfo  service = NULL;+++      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );++      if ( service && service->ps_get_font_private )+        error = service->ps_get_font_private( face, afont_private );+    }++    return error;+  }+++/* END */
+ src/base/ftutil.c view
@@ -0,0 +1,501 @@+/***************************************************************************/+/*                                                                         */+/*  ftutil.c                                                               */+/*                                                                         */+/*    FreeType utility file for memory and list management (body).         */+/*                                                                         */+/*  Copyright 2002, 2004, 2005, 2006, 2007 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_OBJECTS_H+#include FT_LIST_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_memory+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                                                               *****/+  /*****               M E M O R Y   M A N A G E M E N T               *****/+  /*****                                                               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_alloc( FT_Memory  memory,+                FT_Long    size,+                FT_Error  *p_error )+  {+    FT_Error    error;+    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );++    if ( !error && size > 0 )+      FT_MEM_ZERO( block, size );++    *p_error = error;+    return block;+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_qalloc( FT_Memory  memory,+                 FT_Long    size,+                 FT_Error  *p_error )+  {+    FT_Error    error = FT_Err_Ok;+    FT_Pointer  block = NULL;+++    if ( size > 0 )+    {+      block = memory->alloc( memory, size );+      if ( block == NULL )+        error = FT_Err_Out_Of_Memory;+    }+    else if ( size < 0 )+    {+      /* may help catch/prevent security issues */+      error = FT_Err_Invalid_Argument;+    }++    *p_error = error;+    return block;+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_realloc( FT_Memory  memory,+                  FT_Long    item_size,+                  FT_Long    cur_count,+                  FT_Long    new_count,+                  void*      block,+                  FT_Error  *p_error )+  {+    FT_Error  error = FT_Err_Ok;++    block = ft_mem_qrealloc( memory, item_size,+                             cur_count, new_count, block, &error );+    if ( !error && new_count > cur_count )+      FT_MEM_ZERO( (char*)block + cur_count * item_size,+                   ( new_count - cur_count ) * item_size );++    *p_error = error;+    return block;+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_qrealloc( FT_Memory  memory,+                   FT_Long    item_size,+                   FT_Long    cur_count,+                   FT_Long    new_count,+                   void*      block,+                   FT_Error  *p_error )+  {+    FT_Error  error = FT_Err_Ok;+++    /* Note that we now accept `item_size == 0' as a valid parameter, in+     * order to cover very weird cases where an ALLOC_MULT macro would be+     * called.+     */+    if ( cur_count < 0 || new_count < 0 || item_size < 0 )+    {+      /* may help catch/prevent nasty security issues */+      error = FT_Err_Invalid_Argument;+    }+    else if ( new_count == 0 || item_size == 0 )+    {+      ft_mem_free( memory, block );+      block = NULL;+    }+    else if ( new_count > FT_INT_MAX/item_size )+    {+      error = FT_Err_Array_Too_Large;+    }+    else if ( cur_count == 0 )+    {+      FT_ASSERT( block == NULL );++      block = ft_mem_alloc( memory, new_count*item_size, &error );+    }+    else+    {+      FT_Pointer  block2;+      FT_Long     cur_size = cur_count*item_size;+      FT_Long     new_size = new_count*item_size;+++      block2 = memory->realloc( memory, cur_size, new_size, block );+      if ( block2 == NULL )+        error = FT_Err_Out_Of_Memory;+      else+        block = block2;+    }++    *p_error = error;+    return block;+  }+++  FT_BASE_DEF( void )+  ft_mem_free( FT_Memory   memory,+               const void *P )+  {+    if ( P )+      memory->free( memory, (void*)P );+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_dup( FT_Memory    memory,+              const void*  address,+              FT_ULong     size,+              FT_Error    *p_error )+  {+    FT_Error    error;+    FT_Pointer  p = ft_mem_qalloc( memory, size, &error );+++    if ( !error && address )+      ft_memcpy( p, address, size );++    *p_error = error;+    return p;+  }+++  FT_BASE_DEF( FT_Pointer )+  ft_mem_strdup( FT_Memory    memory,+                 const char*  str,+                 FT_Error    *p_error )+  {+    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1+                        : 0;+++    return ft_mem_dup( memory, str, len, p_error );+  }+++  FT_BASE_DEF( FT_Int )+  ft_mem_strcpyn( char*        dst,+                  const char*  src,+                  FT_ULong     size )+  {+    while ( size > 1 && *src != 0 )+    {+      *dst++ = *src++;+      size--;+    }++    *dst = 0;  /* always zero-terminate */++    return *src != 0;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                                                               *****/+  /*****            D O U B L Y   L I N K E D   L I S T S              *****/+  /*****                                                               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_list++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( FT_ListNode )+  FT_List_Find( FT_List  list,+                void*    data )+  {+    FT_ListNode  cur;+++    cur = list->head;+    while ( cur )+    {+      if ( cur->data == data )+        return cur;++      cur = cur->next;+    }++    return (FT_ListNode)0;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( void )+  FT_List_Add( FT_List      list,+               FT_ListNode  node )+  {+    FT_ListNode  before = list->tail;+++    node->next = 0;+    node->prev = before;++    if ( before )+      before->next = node;+    else+      list->head = node;++    list->tail = node;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( void )+  FT_List_Insert( FT_List      list,+                  FT_ListNode  node )+  {+    FT_ListNode  after = list->head;+++    node->next = after;+    node->prev = 0;++    if ( !after )+      list->tail = node;+    else+      after->prev = node;++    list->head = node;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( void )+  FT_List_Remove( FT_List      list,+                  FT_ListNode  node )+  {+    FT_ListNode  before, after;+++    before = node->prev;+    after  = node->next;++    if ( before )+      before->next = after;+    else+      list->head = after;++    if ( after )+      after->prev = before;+    else+      list->tail = before;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( void )+  FT_List_Up( FT_List      list,+              FT_ListNode  node )+  {+    FT_ListNode  before, after;+++    before = node->prev;+    after  = node->next;++    /* check whether we are already on top of the list */+    if ( !before )+      return;++    before->next = after;++    if ( after )+      after->prev = before;+    else+      list->tail = before;++    node->prev       = 0;+    node->next       = list->head;+    list->head->prev = node;+    list->head       = node;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( FT_Error )+  FT_List_Iterate( FT_List            list,+                   FT_List_Iterator   iterator,+                   void*              user )+  {+    FT_ListNode  cur   = list->head;+    FT_Error     error = FT_Err_Ok;+++    while ( cur )+    {+      FT_ListNode  next = cur->next;+++      error = iterator( cur, user );+      if ( error )+        break;++      cur = next;+    }++    return error;+  }+++  /* documentation is in ftlist.h */++  FT_EXPORT_DEF( void )+  FT_List_Finalize( FT_List             list,+                    FT_List_Destructor  destroy,+                    FT_Memory           memory,+                    void*               user )+  {+    FT_ListNode  cur;+++    cur = list->head;+    while ( cur )+    {+      FT_ListNode  next = cur->next;+      void*        data = cur->data;+++      if ( destroy )+        destroy( memory, data, user );++      FT_FREE( cur );+      cur = next;+    }++    list->head = 0;+    list->tail = 0;+  }+++  FT_BASE_DEF( FT_UInt32 )+  ft_highpow2( FT_UInt32  value )+  {+    FT_UInt32  value2;+++    /*+     *  We simply clear the lowest bit in each iteration.  When+     *  we reach 0, we know that the previous value was our result.+     */+    for ( ;; )+    {+      value2 = value & (value - 1);  /* clear lowest bit */+      if ( value2 == 0 )+        break;++      value = value2;+    }+    return value;+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_BASE_DEF( FT_Error )+  FT_Alloc( FT_Memory  memory,+            FT_Long    size,+            void*     *P )+  {+    FT_Error  error;+++    (void)FT_ALLOC( *P, size );+    return error;+  }+++  FT_BASE_DEF( FT_Error )+  FT_QAlloc( FT_Memory  memory,+             FT_Long    size,+             void*     *p )+  {+    FT_Error  error;+++    (void)FT_QALLOC( *p, size );+    return error;+  }+++  FT_BASE_DEF( FT_Error )+  FT_Realloc( FT_Memory  memory,+              FT_Long    current,+              FT_Long    size,+              void*     *P )+  {+    FT_Error  error;+++    (void)FT_REALLOC( *P, current, size );+    return error;+  }+++  FT_BASE_DEF( FT_Error )+  FT_QRealloc( FT_Memory  memory,+               FT_Long    current,+               FT_Long    size,+               void*     *p )+  {+    FT_Error  error;+++    (void)FT_QREALLOC( *p, current, size );+    return error;+  }+++  FT_BASE_DEF( void )+  FT_Free( FT_Memory  memory,+           void*     *P )+  {+    if ( *P )+      FT_MEM_FREE( *P );+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++/* END */
+ src/base/ftwinfnt.c view
@@ -0,0 +1,51 @@+/***************************************************************************/+/*                                                                         */+/*  ftwinfnt.c                                                             */+/*                                                                         */+/*    FreeType API for accessing Windows FNT specific info (body).         */+/*                                                                         */+/*  Copyright 2003, 2004 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_WINFONTS_H+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_WINFNT_H+++  /* documentation is in ftwinfnt.h */++  FT_EXPORT_DEF( FT_Error )+  FT_Get_WinFNT_Header( FT_Face               face,+                        FT_WinFNT_HeaderRec  *header )+  {+    FT_Service_WinFnt  service;+    FT_Error           error;+++    error = FT_Err_Invalid_Argument;++    if ( face != NULL )+    {+      FT_FACE_LOOKUP_SERVICE( face, service, WINFNT );++      if ( service != NULL )+      {+        error = service->get_header( face, header );+      }+    }++    return error;+  }+++/* END */
+ src/base/ftxf86.c view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  ftxf86.c                                                               */+/*                                                                         */+/*    FreeType utility file for X11 support (body).                        */+/*                                                                         */+/*  Copyright 2002, 2003, 2004 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_XFREE86_H+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_XFREE86_NAME_H+++  /* documentation is in ftxf86.h */++  FT_EXPORT_DEF( const char* )+  FT_Get_X11_Font_Format( FT_Face  face )+  {+    const char*  result = NULL;+++    if ( face )+      FT_FACE_FIND_SERVICE( face, result, XF86_NAME );++    return result;+  }+++/* END */
+ src/bdf/bdf.c view
@@ -0,0 +1,34 @@+/*  bdf.c++    FreeType font driver for bdf files++    Copyright (C) 2001, 2002 by+    Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "bdflib.c"+#include "bdfdrivr.c"+++/* END */
+ src/bdf/bdf.h view
@@ -0,0 +1,295 @@+/*+ * Copyright 2000 Computing Research Labs, New Mexico State University+ * Copyright 2001, 2002, 2003, 2004 Francesco Zappa Nardelli+ *+ * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the "Software"),+ * to deal in the Software without restriction, including without limitation+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,+ * and/or sell copies of the Software, and to permit persons to whom the+ * Software is furnished to do so, subject to the following conditions:+ *+ * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ *+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */+++#ifndef __BDF_H__+#define __BDF_H__+++/*+ * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher+ */++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_STREAM_H+++FT_BEGIN_HEADER+++/* Imported from bdfP.h */++#define _bdf_glyph_modified( map, e )                 \+          ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) )+#define _bdf_set_glyph_modified( map, e )              \+          ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) )+#define _bdf_clear_glyph_modified( map, e )             \+          ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) )++/* end of bdfP.h */+++  /*************************************************************************/+  /*                                                                       */+  /* BDF font options macros and types.                                    */+  /*                                                                       */+  /*************************************************************************/+++#define BDF_CORRECT_METRICS  0x01 /* Correct invalid metrics when loading. */+#define BDF_KEEP_COMMENTS    0x02 /* Preserve the font comments.           */+#define BDF_KEEP_UNENCODED   0x04 /* Keep the unencoded glyphs.            */+#define BDF_PROPORTIONAL     0x08 /* Font has proportional spacing.        */+#define BDF_MONOWIDTH        0x10 /* Font has mono width.                  */+#define BDF_CHARCELL         0x20 /* Font has charcell spacing.            */++#define BDF_ALL_SPACING  ( BDF_PROPORTIONAL | \+                           BDF_MONOWIDTH    | \+                           BDF_CHARCELL     )++#define BDF_DEFAULT_LOAD_OPTIONS  ( BDF_CORRECT_METRICS | \+                                    BDF_KEEP_COMMENTS   | \+                                    BDF_KEEP_UNENCODED  | \+                                    BDF_PROPORTIONAL    )+++  typedef struct  bdf_options_t_+  {+    int            correct_metrics;+    int            keep_unencoded;+    int            keep_comments;+    int            font_spacing;++  } bdf_options_t;+++  /* Callback function type for unknown configuration options. */+  typedef int+  (*bdf_options_callback_t)( bdf_options_t*  opts,+                             char**          params,+                             unsigned long   nparams,+                             void*           client_data );+++  /*************************************************************************/+  /*                                                                       */+  /* BDF font property macros and types.                                   */+  /*                                                                       */+  /*************************************************************************/+++#define BDF_ATOM      1+#define BDF_INTEGER   2+#define BDF_CARDINAL  3+++  /* This structure represents a particular property of a font. */+  /* There are a set of defaults and each font has their own.   */+  typedef struct  bdf_property_t_+  {+    char*  name;         /* Name of the property.   */+    int    format;       /* Format of the property. */+    int    builtin;      /* A builtin property.     */+    union+    {+      char*          atom;+      long           l;+      unsigned long  ul;++    } value;             /* Value of the property.  */++  } bdf_property_t;+++  /*************************************************************************/+  /*                                                                       */+  /* BDF font metric and glyph types.                                      */+  /*                                                                       */+  /*************************************************************************/+++  typedef struct  bdf_bbx_t_+  {+    unsigned short  width;+    unsigned short  height;++    short           x_offset;+    short           y_offset;++    short           ascent;+    short           descent;++  } bdf_bbx_t;+++  typedef struct  bdf_glyph_t_+  {+    char*           name;        /* Glyph name.                          */+    long            encoding;    /* Glyph encoding.                      */+    unsigned short  swidth;      /* Scalable width.                      */+    unsigned short  dwidth;      /* Device width.                        */+    bdf_bbx_t       bbx;         /* Glyph bounding box.                  */+    unsigned char*  bitmap;      /* Glyph bitmap.                        */+    unsigned long   bpr;         /* Number of bytes used per row.        */+    unsigned short  bytes;       /* Number of bytes used for the bitmap. */++  } bdf_glyph_t;+++  typedef struct  _hashnode_+  {+    const char*  key;+    size_t       data;++  } _hashnode, *hashnode;+++  typedef struct  hashtable_+  {+    int        limit;+    int        size;+    int        used;+    hashnode*  table;++  } hashtable;+++  typedef struct  bdf_glyphlist_t_+  {+    unsigned short  pad;          /* Pad to 4-byte boundary.              */+    unsigned short  bpp;          /* Bits per pixel.                      */+    long            start;        /* Beginning encoding value of glyphs.  */+    long            end;          /* Ending encoding value of glyphs.     */+    bdf_glyph_t*    glyphs;       /* Glyphs themselves.                   */+    unsigned long   glyphs_size;  /* Glyph structures allocated.          */+    unsigned long   glyphs_used;  /* Glyph structures used.               */+    bdf_bbx_t       bbx;          /* Overall bounding box of glyphs.      */++  } bdf_glyphlist_t;+++  typedef struct  bdf_font_t_+  {+    char*            name;           /* Name of the font.                   */+    bdf_bbx_t        bbx;            /* Font bounding box.                  */++    long             point_size;     /* Point size of the font.             */+    unsigned long    resolution_x;   /* Font horizontal resolution.         */+    unsigned long    resolution_y;   /* Font vertical resolution.           */++    int              spacing;        /* Font spacing value.                 */++    unsigned short   monowidth;      /* Logical width for monowidth font.   */++    long             default_char;   /* Encoding of the default glyph.      */++    long             font_ascent;    /* Font ascent.                        */+    long             font_descent;   /* Font descent.                       */++    unsigned long    glyphs_size;    /* Glyph structures allocated.         */+    unsigned long    glyphs_used;    /* Glyph structures used.              */+    bdf_glyph_t*     glyphs;         /* Glyphs themselves.                  */++    unsigned long    unencoded_size; /* Unencoded glyph struct. allocated.  */+    unsigned long    unencoded_used; /* Unencoded glyph struct. used.       */+    bdf_glyph_t*     unencoded;      /* Unencoded glyphs themselves.        */++    unsigned long    props_size;     /* Font properties allocated.          */+    unsigned long    props_used;     /* Font properties used.               */+    bdf_property_t*  props;          /* Font properties themselves.         */++    char*            comments;       /* Font comments.                      */+    unsigned long    comments_len;   /* Length of comment string.           */++    bdf_glyphlist_t  overflow;       /* Storage used for glyph insertion.   */++    void*            internal;       /* Internal data for the font.         */++    unsigned long    nmod[2048];     /* Bitmap indicating modified glyphs.  */+    unsigned long    umod[2048];     /* Bitmap indicating modified          */+                                     /* unencoded glyphs.                   */+    unsigned short   modified;       /* Boolean indicating font modified.   */+    unsigned short   bpp;            /* Bits per pixel.                     */++    FT_Memory        memory;++    bdf_property_t*  user_props;+    unsigned long    nuser_props;+    hashtable        proptbl;++  } bdf_font_t;+++  /*************************************************************************/+  /*                                                                       */+  /* Types for load/save callbacks.                                        */+  /*                                                                       */+  /*************************************************************************/+++  /* Error codes. */+#define BDF_MISSING_START       -1+#define BDF_MISSING_FONTNAME    -2+#define BDF_MISSING_SIZE        -3+#define BDF_MISSING_CHARS       -4+#define BDF_MISSING_STARTCHAR   -5+#define BDF_MISSING_ENCODING    -6+#define BDF_MISSING_BBX         -7++#define BDF_OUT_OF_MEMORY      -20++#define BDF_INVALID_LINE      -100+++  /*************************************************************************/+  /*                                                                       */+  /* BDF font API.                                                         */+  /*                                                                       */+  /*************************************************************************/++  FT_LOCAL( FT_Error )+  bdf_load_font( FT_Stream       stream,+                 FT_Memory       memory,+                 bdf_options_t*  opts,+                 bdf_font_t*    *font );++  FT_LOCAL( void )+  bdf_free_font( bdf_font_t*  font );++  FT_LOCAL( bdf_property_t * )+  bdf_get_property( char*        name,+                    bdf_font_t*  font );++  FT_LOCAL( bdf_property_t * )+  bdf_get_font_property( bdf_font_t*  font,+                         const char*  name );+++FT_END_HEADER+++#endif /* __BDF_H__ */+++/* END */
+ src/bdf/bdfdrivr.c view
@@ -0,0 +1,881 @@+/*  bdfdrivr.c++    FreeType font driver for bdf files++    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by+    Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/++#include <ft2build.h>++#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_OBJECTS_H+#include FT_BDF_H+#include FT_TRUETYPE_IDS_H ++#include FT_SERVICE_BDF_H+#include FT_SERVICE_XFREE86_NAME_H++#include "bdf.h"+#include "bdfdrivr.h"++#include "bdferror.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_bdfdriver+++  typedef struct  BDF_CMapRec_+  {+    FT_CMapRec        cmap;+    FT_ULong          num_encodings; /* ftobjs.h: FT_CMap->clazz->size */+    BDF_encoding_el*  encodings;++  } BDF_CMapRec, *BDF_CMap;+++  FT_CALLBACK_DEF( FT_Error )+  bdf_cmap_init( FT_CMap     bdfcmap,+                 FT_Pointer  init_data )+  {+    BDF_CMap  cmap = (BDF_CMap)bdfcmap;+    BDF_Face  face = (BDF_Face)FT_CMAP_FACE( cmap );+    FT_UNUSED( init_data );+++    cmap->num_encodings = face->bdffont->glyphs_used;+    cmap->encodings     = face->en_table;++    return BDF_Err_Ok;+  }+++  FT_CALLBACK_DEF( void )+  bdf_cmap_done( FT_CMap  bdfcmap )+  {+    BDF_CMap  cmap = (BDF_CMap)bdfcmap;+++    cmap->encodings     = NULL;+    cmap->num_encodings = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  bdf_cmap_char_index( FT_CMap    bdfcmap,+                       FT_UInt32  charcode )+  {+    BDF_CMap          cmap      = (BDF_CMap)bdfcmap;+    BDF_encoding_el*  encodings = cmap->encodings;+    FT_ULong          min, max, mid; /* num_encodings */+    FT_UShort         result    = 0; /* encodings->glyph */+++    min = 0;+    max = cmap->num_encodings;++    while ( min < max )+    {+      FT_ULong  code;+++      mid  = ( min + max ) >> 1;+      code = encodings[mid].enc;++      if ( charcode == code )+      {+        /* increase glyph index by 1 --              */+        /* we reserve slot 0 for the undefined glyph */+        result = encodings[mid].glyph + 1;+        break;+      }++      if ( charcode < code )+        max = mid;+      else+        min = mid + 1;+    }++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  bdf_cmap_char_next( FT_CMap     bdfcmap,+                      FT_UInt32  *acharcode )+  {+    BDF_CMap          cmap      = (BDF_CMap)bdfcmap;+    BDF_encoding_el*  encodings = cmap->encodings;+    FT_ULong          min, max, mid; /* num_encodings */+    FT_UShort         result   = 0;  /* encodings->glyph */+    FT_ULong          charcode = *acharcode + 1;+++    min = 0;+    max = cmap->num_encodings;++    while ( min < max )+    {+      FT_ULong  code; /* same as BDF_encoding_el.enc */+++      mid  = ( min + max ) >> 1;+      code = encodings[mid].enc;++      if ( charcode == code )+      {+        /* increase glyph index by 1 --              */+        /* we reserve slot 0 for the undefined glyph */+        result = encodings[mid].glyph + 1;+        goto Exit;+      }++      if ( charcode < code )+        max = mid;+      else+        min = mid + 1;+    }++    charcode = 0;+    if ( min < cmap->num_encodings )+    {+      charcode = encodings[min].enc;+      result   = encodings[min].glyph + 1;+    }++  Exit:+    if ( charcode > 0xFFFFFFFFUL )+    {+      FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" ));+      *acharcode = 0;+      /* XXX: result should be changed to indicate an overflow error */+    }+    else+      *acharcode = (FT_UInt32)charcode;+    return result;+  }+++  FT_CALLBACK_TABLE_DEF+  const FT_CMap_ClassRec  bdf_cmap_class =+  {+    sizeof ( BDF_CMapRec ),+    bdf_cmap_init,+    bdf_cmap_done,+    bdf_cmap_char_index,+    bdf_cmap_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++  static FT_Error+  bdf_interpret_style( BDF_Face  bdf )+  {+    FT_Error         error  = BDF_Err_Ok;+    FT_Face          face   = FT_FACE( bdf );+    FT_Memory        memory = face->memory;+    bdf_font_t*      font   = bdf->bdffont;+    bdf_property_t*  prop;++    char*   strings[4] = { NULL, NULL, NULL, NULL };+    size_t  nn, len, lengths[4];+++    face->style_flags = 0;++    prop = bdf_get_font_property( font, (char *)"SLANT" );+    if ( prop && prop->format == BDF_ATOM                             &&+         prop->value.atom                                             &&+         ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||+           *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )+    {+      face->style_flags |= FT_STYLE_FLAG_ITALIC;+      strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )+                   ? (char *)"Oblique"+                   : (char *)"Italic";+    }++    prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );+    if ( prop && prop->format == BDF_ATOM                             &&+         prop->value.atom                                             &&+         ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )+    {+      face->style_flags |= FT_STYLE_FLAG_BOLD;+      strings[1] = (char *)"Bold";+    }++    prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );+    if ( prop && prop->format == BDF_ATOM                              &&+         prop->value.atom && *(prop->value.atom)                       &&+         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )+      strings[3] = (char *)(prop->value.atom);++    prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );+    if ( prop && prop->format == BDF_ATOM                              &&+         prop->value.atom && *(prop->value.atom)                       &&+         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )+      strings[0] = (char *)(prop->value.atom);++    len = 0;++    for ( len = 0, nn = 0; nn < 4; nn++ )+    {+      lengths[nn] = 0;+      if ( strings[nn] )+      {+        lengths[nn] = ft_strlen( strings[nn] );+        len        += lengths[nn] + 1;+      }+    }++    if ( len == 0 )+    {+      strings[0] = (char *)"Regular";+      lengths[0] = ft_strlen( strings[0] );+      len        = lengths[0] + 1;+    }++    {+      char*  s;+++      if ( FT_ALLOC( face->style_name, len ) )+        return error;++      s = face->style_name;++      for ( nn = 0; nn < 4; nn++ )+      {+        char*  src = strings[nn];+++        len = lengths[nn];++        if ( src == NULL )+          continue;++        /* separate elements with a space */+        if ( s != face->style_name )+          *s++ = ' ';++        ft_memcpy( s, src, len );++        /* need to convert spaces to dashes for */+        /* add_style_name and setwidth_name     */+        if ( nn == 0 || nn == 3 )+        {+          size_t  mm;+++          for ( mm = 0; mm < len; mm++ )+            if ( s[mm] == ' ' )+              s[mm] = '-';+        }++        s += len;+      }+      *s = 0;+    }++    return error;+  }+++  FT_CALLBACK_DEF( void )+  BDF_Face_Done( FT_Face  bdfface )         /* BDF_Face */+  {+    BDF_Face   face = (BDF_Face)bdfface;+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );++    bdf_free_font( face->bdffont );++    FT_FREE( face->en_table );++    FT_FREE( face->charset_encoding );+    FT_FREE( face->charset_registry );+    FT_FREE( bdfface->family_name );+    FT_FREE( bdfface->style_name );++    FT_FREE( bdfface->available_sizes );++    FT_FREE( face->bdffont );++    FT_TRACE4(( "BDF_Face_Done: done face\n" ));+  }+++  FT_CALLBACK_DEF( FT_Error )+  BDF_Face_Init( FT_Stream      stream,+                 FT_Face        bdfface,        /* BDF_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    FT_Error       error  = BDF_Err_Ok;+    BDF_Face       face   = (BDF_Face)bdfface;+    FT_Memory      memory = FT_FACE_MEMORY( face );++    bdf_font_t*    font = NULL;+    bdf_options_t  options;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+    FT_UNUSED( face_index );+++    if ( FT_STREAM_SEEK( 0 ) )+      goto Exit;++    options.correct_metrics = 1;   /* FZ XXX: options semantics */+    options.keep_unencoded  = 1;+    options.keep_comments   = 0;+    options.font_spacing    = BDF_PROPORTIONAL;++    error = bdf_load_font( stream, memory, &options, &font );+    if ( error == BDF_Err_Missing_Startfont_Field )+    {+      FT_TRACE2(( "[not a valid BDF file]\n" ));+      goto Fail;+    }+    else if ( error )+      goto Exit;++    /* we have a bdf font: let's construct the face object */+    face->bdffont = font;+    {+      bdf_property_t*  prop = NULL;+++      FT_TRACE4(( "number of glyphs: %d (%d)\n",+                  font->glyphs_size,+                  font->glyphs_used ));+      FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n",+                  font->unencoded_size,+                  font->unencoded_used ));++      bdfface->num_faces  = 1;+      bdfface->face_index = 0;+      bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES |+                            FT_FACE_FLAG_HORIZONTAL  |+                            FT_FACE_FLAG_FAST_GLYPHS;++      prop = bdf_get_font_property( font, "SPACING" );+      if ( prop && prop->format == BDF_ATOM                             &&+           prop->value.atom                                             &&+           ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' ||+             *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) )+        bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL   */+      /* FZ XXX: I need a font to implement this */++      prop = bdf_get_font_property( font, "FAMILY_NAME" );+      if ( prop && prop->value.atom )+      {+        if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) )+          goto Exit;+      }+      else+        bdfface->family_name = 0;++      if ( ( error = bdf_interpret_style( face ) ) != 0 )+        goto Exit;++      /* the number of glyphs (with one slot for the undefined glyph */+      /* at position 0 and all unencoded glyphs)                     */+      bdfface->num_glyphs = font->glyphs_size + 1;++      bdfface->num_fixed_sizes = 1;+      if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) )+        goto Exit;++      {+        FT_Bitmap_Size*  bsize = bdfface->available_sizes;+        FT_Short         resolution_x = 0, resolution_y = 0;+++        FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );++        bsize->height = (FT_Short)( font->font_ascent + font->font_descent );++        prop = bdf_get_font_property( font, "AVERAGE_WIDTH" );+        if ( prop )+          bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 );+        else+          bsize->width = (FT_Short)( bsize->height * 2/3 );++        prop = bdf_get_font_property( font, "POINT_SIZE" );+        if ( prop )+          /* convert from 722.7 decipoints to 72 points per inch */+          bsize->size =+            (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L );+        else+          bsize->size = bsize->width << 6;++        prop = bdf_get_font_property( font, "PIXEL_SIZE" );+        if ( prop )+          bsize->y_ppem = (FT_Short)prop->value.l << 6;++        prop = bdf_get_font_property( font, "RESOLUTION_X" );+        if ( prop )+          resolution_x = (FT_Short)prop->value.l;++        prop = bdf_get_font_property( font, "RESOLUTION_Y" );+        if ( prop )+          resolution_y = (FT_Short)prop->value.l;++        if ( bsize->y_ppem == 0 )+        {+          bsize->y_ppem = bsize->size;+          if ( resolution_y )+            bsize->y_ppem = bsize->y_ppem * resolution_y / 72;+        }+        if ( resolution_x && resolution_y )+          bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;+        else+          bsize->x_ppem = bsize->y_ppem;+      }++      /* encoding table */+      {+        bdf_glyph_t*   cur = font->glyphs;+        unsigned long  n;+++        if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )+          goto Exit;++        face->default_glyph = 0;+        for ( n = 0; n < font->glyphs_size; n++ )+        {+          (face->en_table[n]).enc = cur[n].encoding;+          FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding ));+          (face->en_table[n]).glyph = (FT_Short)n;++          if ( cur[n].encoding == font->default_char )+          {+            if ( n < FT_UINT_MAX )+              face->default_glyph = (FT_UInt)n;+            else+              FT_TRACE1(( "idx %d is too large for this system\n", n ));+          }+        }+      }++      /* charmaps */+      {+        bdf_property_t  *charset_registry = 0, *charset_encoding = 0;+        FT_Bool          unicode_charmap  = 0;+++        charset_registry =+          bdf_get_font_property( font, "CHARSET_REGISTRY" );+        charset_encoding =+          bdf_get_font_property( font, "CHARSET_ENCODING" );+        if ( charset_registry && charset_encoding )+        {+          if ( charset_registry->format == BDF_ATOM &&+               charset_encoding->format == BDF_ATOM &&+               charset_registry->value.atom         &&+               charset_encoding->value.atom         )+          {+            const char*  s;+++            if ( FT_STRDUP( face->charset_encoding,+                            charset_encoding->value.atom ) ||+                 FT_STRDUP( face->charset_registry,+                            charset_registry->value.atom ) )+              goto Exit;++            /* Uh, oh, compare first letters manually to avoid dependency */+            /* on locales.                                                */+            s = face->charset_registry;+            if ( ( s[0] == 'i' || s[0] == 'I' ) &&+                 ( s[1] == 's' || s[1] == 'S' ) &&+                 ( s[2] == 'o' || s[2] == 'O' ) )+            {+              s += 3;+              if ( !ft_strcmp( s, "10646" )                      ||+                   ( !ft_strcmp( s, "8859" ) &&+                     !ft_strcmp( face->charset_encoding, "1" ) ) )+              unicode_charmap = 1;+            }++            {+              FT_CharMapRec  charmap;+++              charmap.face        = FT_FACE( face );+              charmap.encoding    = FT_ENCODING_NONE;+              /* initial platform/encoding should indicate unset status? */+              charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;+              charmap.encoding_id = TT_APPLE_ID_DEFAULT;++              if ( unicode_charmap )+              {+                charmap.encoding    = FT_ENCODING_UNICODE;+                charmap.platform_id = TT_PLATFORM_MICROSOFT;+                charmap.encoding_id = TT_MS_ID_UNICODE_CS;+              }++              error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );++#if 0+              /* Select default charmap */+              if ( bdfface->num_charmaps )+                bdfface->charmap = bdfface->charmaps[0];+#endif+            }++            goto Exit;+          }+        }++        /* otherwise assume Adobe standard encoding */++        {+          FT_CharMapRec  charmap;+++          charmap.face        = FT_FACE( face );+          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;+          charmap.platform_id = TT_PLATFORM_ADOBE;+          charmap.encoding_id = TT_ADOBE_ID_STANDARD;++          error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );++          /* Select default charmap */+          if ( bdfface->num_charmaps )+            bdfface->charmap = bdfface->charmaps[0];+        }+      }+    }++  Exit:+    return error;++  Fail:+    BDF_Face_Done( bdfface );+    return BDF_Err_Unknown_File_Format;+  }+++  FT_CALLBACK_DEF( FT_Error )+  BDF_Size_Select( FT_Size   size,+                   FT_ULong  strike_index )+  {+    bdf_font_t*  bdffont = ( (BDF_Face)size->face )->bdffont;+++    FT_Select_Metrics( size->face, strike_index );++    size->metrics.ascender    = bdffont->font_ascent << 6;+    size->metrics.descender   = -bdffont->font_descent << 6;+    size->metrics.max_advance = bdffont->bbx.width << 6;++    return BDF_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  BDF_Size_Request( FT_Size          size,+                    FT_Size_Request  req )+  {+    FT_Face          face    = size->face;+    FT_Bitmap_Size*  bsize   = face->available_sizes;+    bdf_font_t*      bdffont = ( (BDF_Face)face )->bdffont;+    FT_Error         error   = BDF_Err_Invalid_Pixel_Size;+    FT_Long          height;+++    height = FT_REQUEST_HEIGHT( req );+    height = ( height + 32 ) >> 6;++    switch ( req->type )+    {+    case FT_SIZE_REQUEST_TYPE_NOMINAL:+      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )+        error = BDF_Err_Ok;+      break;++    case FT_SIZE_REQUEST_TYPE_REAL_DIM:+      if ( height == ( bdffont->font_ascent ++                       bdffont->font_descent ) )+        error = BDF_Err_Ok;+      break;++    default:+      error = BDF_Err_Unimplemented_Feature;+      break;+    }++    if ( error )+      return error;+    else+      return BDF_Size_Select( size, 0 );+  }++++  FT_CALLBACK_DEF( FT_Error )+  BDF_Glyph_Load( FT_GlyphSlot  slot,+                  FT_Size       size,+                  FT_UInt       glyph_index,+                  FT_Int32      load_flags )+  {+    BDF_Face     bdf    = (BDF_Face)FT_SIZE_FACE( size );+    FT_Face      face   = FT_FACE( bdf );+    FT_Error     error  = BDF_Err_Ok;+    FT_Bitmap*   bitmap = &slot->bitmap;+    bdf_glyph_t  glyph;+    int          bpp    = bdf->bdffont->bpp;++    FT_UNUSED( load_flags );+++    if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )+    {+      error = BDF_Err_Invalid_Argument;+      goto Exit;+    }++    /* index 0 is the undefined glyph */+    if ( glyph_index == 0 )+      glyph_index = bdf->default_glyph;+    else+      glyph_index--;++    /* slot, bitmap => freetype, glyph => bdflib */+    glyph = bdf->bdffont->glyphs[glyph_index];++    bitmap->rows  = glyph.bbx.height;+    bitmap->width = glyph.bbx.width;+    if ( glyph.bpr > INT_MAX )+      FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n",+                   glyph.bpr ));+    bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */++    /* note: we don't allocate a new array to hold the bitmap; */+    /*       we can simply point to it                         */+    ft_glyphslot_set_bitmap( slot, glyph.bitmap );++    switch ( bpp )+    {+    case 1:+      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;+      break;+    case 2:+      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2;+      break;+    case 4:+      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4;+      break;+    case 8:+      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;+      bitmap->num_grays  = 256;+      break;+    }++    slot->format      = FT_GLYPH_FORMAT_BITMAP;+    slot->bitmap_left = glyph.bbx.x_offset;+    slot->bitmap_top  = glyph.bbx.ascent;++    slot->metrics.horiAdvance  = glyph.dwidth << 6;+    slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;+    slot->metrics.horiBearingY = glyph.bbx.ascent << 6;+    slot->metrics.width        = bitmap->width << 6;+    slot->metrics.height       = bitmap->rows << 6;++    /*+     * XXX DWIDTH1 and VVECTOR should be parsed and+     * used here, provided such fonts do exist.+     */+    ft_synthesize_vertical_metrics( &slot->metrics,+                                    bdf->bdffont->bbx.height << 6 );++  Exit:+    return error;+  }+++ /*+  *+  *  BDF SERVICE+  *+  */++  static FT_Error+  bdf_get_bdf_property( BDF_Face          face,+                        const char*       prop_name,+                        BDF_PropertyRec  *aproperty )+  {+    bdf_property_t*  prop;+++    FT_ASSERT( face && face->bdffont );++    prop = bdf_get_font_property( face->bdffont, prop_name );+    if ( prop )+    {+      switch ( prop->format )+      {+      case BDF_ATOM:+        aproperty->type   = BDF_PROPERTY_TYPE_ATOM;+        aproperty->u.atom = prop->value.atom;+        break;++      case BDF_INTEGER:+        if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )+        {+          FT_TRACE1(( "bdf_get_bdf_property: " ));+          FT_TRACE1(( "too large integer 0x%x is truncated\n" ));+        }+        aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;+        aproperty->u.integer = (FT_Int32)prop->value.l;+        break;++      case BDF_CARDINAL:+        if ( prop->value.ul > 0xFFFFFFFFUL )+        {+          FT_TRACE1(( "bdf_get_bdf_property: " ));+          FT_TRACE1(( "too large cardinal 0x%x is truncated\n" ));+        }+        aproperty->type       = BDF_PROPERTY_TYPE_CARDINAL;+        aproperty->u.cardinal = (FT_UInt32)prop->value.ul;+        break;++      default:+        goto Fail;+      }+      return 0;+    }++  Fail:+    return BDF_Err_Invalid_Argument;+  }+++  static FT_Error+  bdf_get_charset_id( BDF_Face      face,+                      const char*  *acharset_encoding,+                      const char*  *acharset_registry )+  {+    *acharset_encoding = face->charset_encoding;+    *acharset_registry = face->charset_registry;++    return 0;+  }+++  static const FT_Service_BDFRec  bdf_service_bdf =+  {+    (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id,+    (FT_BDF_GetPropertyFunc) bdf_get_bdf_property+  };+++ /*+  *+  *  SERVICES LIST+  *+  */++  static const FT_ServiceDescRec  bdf_services[] =+  {+    { FT_SERVICE_ID_BDF,       &bdf_service_bdf },+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF },+    { NULL, NULL }+  };+++  FT_CALLBACK_DEF( FT_Module_Interface )+  bdf_driver_requester( FT_Module    module,+                        const char*  name )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( bdf_services, name );+  }++++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  bdf_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER         |+      FT_MODULE_DRIVER_NO_OUTLINES,+      sizeof ( FT_DriverRec ),++      "bdf",+      0x10000L,+      0x20000L,++      0,++      (FT_Module_Constructor)0,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  bdf_driver_requester+    },++    sizeof ( BDF_FaceRec ),+    sizeof ( FT_SizeRec ),+    sizeof ( FT_GlyphSlotRec ),++    BDF_Face_Init,+    BDF_Face_Done,+    0,                          /* FT_Size_InitFunc */+    0,                          /* FT_Size_DoneFunc */+    0,                          /* FT_Slot_InitFunc */+    0,                          /* FT_Slot_DoneFunc */++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    BDF_Glyph_Load,++    0,                          /* FT_Face_GetKerningFunc   */+    0,                          /* FT_Face_AttachFunc       */+    0,                          /* FT_Face_GetAdvancesFunc  */++    BDF_Size_Request,+    BDF_Size_Select+  };+++/* END */
+ src/bdf/bdfdrivr.h view
@@ -0,0 +1,80 @@+/*  bdfdrivr.h++    FreeType font driver for bdf fonts++  Copyright (C) 2001, 2002, 2003, 2004 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __BDFDRIVR_H__+#define __BDFDRIVR_H__++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H++#include "bdf.h"+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  typedef struct  BDF_encoding_el_+  {+    FT_ULong   enc;+    FT_UShort  glyph;++  } BDF_encoding_el;+++  typedef struct  BDF_FaceRec_+  {+    FT_FaceRec        root;++    char*             charset_encoding;+    char*             charset_registry;++    bdf_font_t*       bdffont;++    BDF_encoding_el*  en_table;++    FT_CharMap        charmap_handle;+    FT_CharMapRec     charmap;  /* a single charmap per face */++    FT_UInt           default_glyph;++  } BDF_FaceRec, *BDF_Face;+++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  bdf_driver_class;+++FT_END_HEADER+++#endif /* __BDFDRIVR_H__ */+++/* END */
+ src/bdf/bdferror.h view
@@ -0,0 +1,44 @@+/*+ * Copyright 2001, 2002 Francesco Zappa Nardelli+ *+ * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the "Software"),+ * to deal in the Software without restriction, including without limitation+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,+ * and/or sell copies of the Software, and to permit persons to whom the+ * Software is furnished to do so, subject to the following conditions:+ *+ * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ *+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the BDF error enumeration constants.      */+  /*                                                                       */+  /*************************************************************************/++#ifndef __BDFERROR_H__+#define __BDFERROR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  BDF_Err_+#define FT_ERR_BASE    FT_Mod_Err_BDF++#include FT_ERRORS_H++#endif /* __BDFERROR_H__ */+++/* END */
+ src/bdf/bdflib.c view
@@ -0,0 +1,2542 @@+/*+ * Copyright 2000 Computing Research Labs, New Mexico State University+ * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010+ *   Francesco Zappa Nardelli+ *+ * Permission is hereby granted, free of charge, to any person obtaining a+ * copy of this software and associated documentation files (the "Software"),+ * to deal in the Software without restriction, including without limitation+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,+ * and/or sell copies of the Software, and to permit persons to whom the+ * Software is furnished to do so, subject to the following conditions:+ *+ * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ *+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++  /*************************************************************************/+  /*                                                                       */+  /*  This file is based on bdf.c,v 1.22 2000/03/16 20:08:50               */+  /*                                                                       */+  /*  taken from Mark Leisher's xmbdfed package                            */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>++#include FT_FREETYPE_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_OBJECTS_H++#include "bdf.h"+#include "bdferror.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_bdflib+++  /*************************************************************************/+  /*                                                                       */+  /* Default BDF font options.                                             */+  /*                                                                       */+  /*************************************************************************/+++  static const bdf_options_t  _bdf_opts =+  {+    1,                /* Correct metrics.               */+    1,                /* Preserve unencoded glyphs.     */+    0,                /* Preserve comments.             */+    BDF_PROPORTIONAL  /* Default spacing.               */+  };+++  /*************************************************************************/+  /*                                                                       */+  /* Builtin BDF font properties.                                          */+  /*                                                                       */+  /*************************************************************************/++  /* List of most properties that might appear in a font.  Doesn't include */+  /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts.           */++  static const bdf_property_t  _bdf_properties[] =+  {+    { (char *)"ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },+    { (char *)"AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },+    { (char *)"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },+    { (char *)"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },+    { (char *)"CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },+    { (char *)"CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },+    { (char *)"CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },+    { (char *)"CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },+    { (char *)"COMMENT",                 BDF_ATOM,     1, { 0 } },+    { (char *)"COPYRIGHT",               BDF_ATOM,     1, { 0 } },+    { (char *)"DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },+    { (char *)"DESTINATION",             BDF_CARDINAL, 1, { 0 } },+    { (char *)"DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },+    { (char *)"END_SPACE",               BDF_INTEGER,  1, { 0 } },+    { (char *)"FACE_NAME",               BDF_ATOM,     1, { 0 } },+    { (char *)"FAMILY_NAME",             BDF_ATOM,     1, { 0 } },+    { (char *)"FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },+    { (char *)"FONT",                    BDF_ATOM,     1, { 0 } },+    { (char *)"FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },+    { (char *)"FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },+    { (char *)"FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },+    { (char *)"FOUNDRY",                 BDF_ATOM,     1, { 0 } },+    { (char *)"FULL_NAME",               BDF_ATOM,     1, { 0 } },+    { (char *)"ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },+    { (char *)"MAX_SPACE",               BDF_INTEGER,  1, { 0 } },+    { (char *)"MIN_SPACE",               BDF_INTEGER,  1, { 0 } },+    { (char *)"NORM_SPACE",              BDF_INTEGER,  1, { 0 } },+    { (char *)"NOTICE",                  BDF_ATOM,     1, { 0 } },+    { (char *)"PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },+    { (char *)"POINT_SIZE",              BDF_INTEGER,  1, { 0 } },+    { (char *)"QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },+    { (char *)"RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },+    { (char *)"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },+    { (char *)"RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },+    { (char *)"RESOLUTION",              BDF_INTEGER,  1, { 0 } },+    { (char *)"RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },+    { (char *)"RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },+    { (char *)"SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },+    { (char *)"SLANT",                   BDF_ATOM,     1, { 0 } },+    { (char *)"SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },+    { (char *)"SPACING",                 BDF_ATOM,     1, { 0 } },+    { (char *)"STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },+    { (char *)"STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },+    { (char *)"SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },+    { (char *)"SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },+    { (char *)"SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },+    { (char *)"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },+    { (char *)"SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },+    { (char *)"SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },+    { (char *)"UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },+    { (char *)"UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },+    { (char *)"WEIGHT",                  BDF_CARDINAL, 1, { 0 } },+    { (char *)"WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },+    { (char *)"X_HEIGHT",                BDF_INTEGER,  1, { 0 } },+    { (char *)"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },+    { (char *)"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },+  };++  static const unsigned long+  _num_bdf_properties = sizeof ( _bdf_properties ) /+                        sizeof ( _bdf_properties[0] );+++  /*************************************************************************/+  /*                                                                       */+  /* Hash table utilities for the properties.                              */+  /*                                                                       */+  /*************************************************************************/++  /* XXX: Replace this with FreeType's hash functions */+++#define INITIAL_HT_SIZE  241++  typedef void+  (*hash_free_func)( hashnode  node );++  static hashnode*+  hash_bucket( const char*  key,+               hashtable*   ht )+  {+    const char*    kp  = key;+    unsigned long  res = 0;+    hashnode*      bp  = ht->table, *ndp;+++    /* Mocklisp hash function. */+    while ( *kp )+      res = ( res << 5 ) - res + *kp++;++    ndp = bp + ( res % ht->size );+    while ( *ndp )+    {+      kp = (*ndp)->key;+      if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 )+        break;+      ndp--;+      if ( ndp < bp )+        ndp = bp + ( ht->size - 1 );+    }++    return ndp;+  }+++  static FT_Error+  hash_rehash( hashtable*  ht,+               FT_Memory   memory )+  {+    hashnode*  obp = ht->table, *bp, *nbp;+    int        i, sz = ht->size;+    FT_Error   error = BDF_Err_Ok;+++    ht->size <<= 1;+    ht->limit  = ht->size / 3;++    if ( FT_NEW_ARRAY( ht->table, ht->size ) )+      goto Exit;++    for ( i = 0, bp = obp; i < sz; i++, bp++ )+    {+      if ( *bp )+      {+        nbp = hash_bucket( (*bp)->key, ht );+        *nbp = *bp;+      }+    }+    FT_FREE( obp );++  Exit:+    return error;+  }+++  static FT_Error+  hash_init( hashtable*  ht,+             FT_Memory   memory )+  {+    int       sz = INITIAL_HT_SIZE;+    FT_Error  error = BDF_Err_Ok;+++    ht->size  = sz;+    ht->limit = sz / 3;+    ht->used  = 0;++    if ( FT_NEW_ARRAY( ht->table, sz ) )+      goto Exit;++  Exit:+    return error;+  }+++  static void+  hash_free( hashtable*  ht,+             FT_Memory   memory )+  {+    if ( ht != 0 )+    {+      int        i, sz = ht->size;+      hashnode*  bp = ht->table;+++      for ( i = 0; i < sz; i++, bp++ )+        FT_FREE( *bp );++      FT_FREE( ht->table );+    }+  }+++  static FT_Error+  hash_insert( char*       key,+               size_t      data,+               hashtable*  ht,+               FT_Memory   memory )+  {+    hashnode  nn, *bp = hash_bucket( key, ht );+    FT_Error  error = BDF_Err_Ok;+++    nn = *bp;+    if ( !nn )+    {+      if ( FT_NEW( nn ) )+        goto Exit;+      *bp = nn;++      nn->key  = key;+      nn->data = data;++      if ( ht->used >= ht->limit )+      {+        error = hash_rehash( ht, memory );+        if ( error )+          goto Exit;+      }+      ht->used++;+    }+    else+      nn->data = data;++  Exit:+    return error;+  }+++  static hashnode+  hash_lookup( const char* key,+               hashtable*  ht )+  {+    hashnode *np = hash_bucket( key, ht );+++    return *np;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Utility types and functions.                                          */+  /*                                                                       */+  /*************************************************************************/+++  /* Function type for parsing lines of a BDF font. */++  typedef FT_Error+  (*_bdf_line_func_t)( char*          line,+                       unsigned long  linelen,+                       unsigned long  lineno,+                       void*          call_data,+                       void*          client_data );+++  /* List structure for splitting lines into fields. */++  typedef struct  _bdf_list_t_+  {+    char**         field;+    unsigned long  size;+    unsigned long  used;+    FT_Memory      memory;++  } _bdf_list_t;+++  /* Structure used while loading BDF fonts. */++  typedef struct  _bdf_parse_t_+  {+    unsigned long   flags;+    unsigned long   cnt;+    unsigned long   row;++    short           minlb;+    short           maxlb;+    short           maxrb;+    short           maxas;+    short           maxds;++    short           rbearing;++    char*           glyph_name;+    long            glyph_enc;++    bdf_font_t*     font;+    bdf_options_t*  opts;++    unsigned long   have[2048];+    _bdf_list_t     list;++    FT_Memory       memory;++  } _bdf_parse_t;+++#define setsbit( m, cc ) \+          ( m[(FT_Byte)(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) )+#define sbitset( m, cc ) \+          ( m[(FT_Byte)(cc) >> 3]  & ( 1 << ( (cc) & 7 ) ) )+++  static void+  _bdf_list_init( _bdf_list_t*  list,+                  FT_Memory     memory )+  {+    FT_ZERO( list );+    list->memory = memory;+  }+++  static void+  _bdf_list_done( _bdf_list_t*  list )+  {+    FT_Memory  memory = list->memory;+++    if ( memory )+    {+      FT_FREE( list->field );+      FT_ZERO( list );+    }+  }+++  static FT_Error+  _bdf_list_ensure( _bdf_list_t*   list,+                    unsigned long  num_items ) /* same as _bdf_list_t.used */+  {+    FT_Error  error = BDF_Err_Ok;+++    if ( num_items > list->size )+    {+      unsigned long  oldsize = list->size; /* same as _bdf_list_t.size */+      unsigned long  newsize = oldsize + ( oldsize >> 1 ) + 4;+      unsigned long  bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) );+      FT_Memory      memory  = list->memory;+++      if ( oldsize == bigsize )+      {+        error = BDF_Err_Out_Of_Memory;+        goto Exit;+      }+      else if ( newsize < oldsize || newsize > bigsize )+        newsize = bigsize;++      if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) )+        goto Exit;++      list->size = newsize;+    }++  Exit:+    return error;+  }+++  static void+  _bdf_list_shift( _bdf_list_t*   list,+                   unsigned long  n )+  {+    unsigned long  i, u;+++    if ( list == 0 || list->used == 0 || n == 0 )+      return;++    if ( n >= list->used )+    {+      list->used = 0;+      return;+    }++    for ( u = n, i = 0; u < list->used; i++, u++ )+      list->field[i] = list->field[u];+    list->used -= n;+  }+++  /* An empty string for empty fields. */++  static const char  empty[1] = { 0 };      /* XXX eliminate this */+++  static char *+  _bdf_list_join( _bdf_list_t*    list,+                  int             c,+                  unsigned long  *alen )+  {+    unsigned long  i, j;+    char           *fp, *dp;+++    *alen = 0;++    if ( list == 0 || list->used == 0 )+      return 0;++    dp = list->field[0];+    for ( i = j = 0; i < list->used; i++ )+    {+      fp = list->field[i];+      while ( *fp )+        dp[j++] = *fp++;++      if ( i + 1 < list->used )+        dp[j++] = (char)c;+    }+    if ( dp != empty )+      dp[j] = 0;++    *alen = j;+    return dp;+  }+++  static FT_Error+  _bdf_list_split( _bdf_list_t*   list,+                   char*          separators,+                   char*          line,+                   unsigned long  linelen )+  {+    int       mult, final_empty;+    char      *sp, *ep, *end;+    char      seps[32];+    FT_Error  error = BDF_Err_Ok;+++    /* Initialize the list. */+    list->used = 0;++    /* If the line is empty, then simply return. */+    if ( linelen == 0 || line[0] == 0 )+      goto Exit;++    /* In the original code, if the `separators' parameter is NULL or */+    /* empty, the list is split into individual bytes.  We don't need */+    /* this, so an error is signaled.                                 */+    if ( separators == 0 || *separators == 0 )+    {+      error = BDF_Err_Invalid_Argument;+      goto Exit;+    }++    /* Prepare the separator bitmap. */+    FT_MEM_ZERO( seps, 32 );++    /* If the very last character of the separator string is a plus, then */+    /* set the `mult' flag to indicate that multiple separators should be */+    /* collapsed into one.                                                */+    for ( mult = 0, sp = separators; sp && *sp; sp++ )+    {+      if ( *sp == '+' && *( sp + 1 ) == 0 )+        mult = 1;+      else+        setsbit( seps, *sp );+    }++    /* Break the line up into fields. */+    for ( final_empty = 0, sp = ep = line, end = sp + linelen;+          sp < end && *sp; )+    {+      /* Collect everything that is not a separator. */+      for ( ; *ep && !sbitset( seps, *ep ); ep++ )+        ;++      /* Resize the list if necessary. */+      if ( list->used == list->size )+      {+        error = _bdf_list_ensure( list, list->used + 1 );+        if ( error )+          goto Exit;+      }++      /* Assign the field appropriately. */+      list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty;++      sp = ep;++      if ( mult )+      {+        /* If multiple separators should be collapsed, do it now by */+        /* setting all the separator characters to 0.               */+        for ( ; *ep && sbitset( seps, *ep ); ep++ )+          *ep = 0;+      }+      else if ( *ep != 0 )+        /* Don't collapse multiple separators by making them 0, so just */+        /* make the one encountered 0.                                  */+        *ep++ = 0;++      final_empty = ( ep > sp && *ep == 0 );+      sp = ep;+    }++    /* Finally, NULL-terminate the list. */+    if ( list->used + final_empty >= list->size )+    {+      error = _bdf_list_ensure( list, list->used + final_empty + 1 );+      if ( error )+        goto Exit;+    }++    if ( final_empty )+      list->field[list->used++] = (char*)empty;++    list->field[list->used] = 0;++  Exit:+    return error;+  }+++#define NO_SKIP  256  /* this value cannot be stored in a 'char' */+++  static FT_Error+  _bdf_readstream( FT_Stream         stream,+                   _bdf_line_func_t  callback,+                   void*             client_data,+                   unsigned long    *lno )+  {+    _bdf_line_func_t  cb;+    unsigned long     lineno, buf_size;+    int               refill, hold, to_skip;+    ptrdiff_t         bytes, start, end, cursor, avail;+    char*             buf = 0;+    FT_Memory         memory = stream->memory;+    FT_Error          error = BDF_Err_Ok;+++    if ( callback == 0 )+    {+      error = BDF_Err_Invalid_Argument;+      goto Exit;+    }++    /* initial size and allocation of the input buffer */+    buf_size = 1024;++    if ( FT_NEW_ARRAY( buf, buf_size ) )+      goto Exit;++    cb      = callback;+    lineno  = 1;+    buf[0]  = 0;+    start   = 0;+    end     = 0;+    avail   = 0;+    cursor  = 0;+    refill  = 1;+    to_skip = NO_SKIP;+    bytes   = 0;        /* make compiler happy */++    for (;;)+    {+      if ( refill )+      {+        bytes  = (ptrdiff_t)FT_Stream_TryRead(+                   stream, (FT_Byte*)buf + cursor,+                   (FT_ULong)( buf_size - cursor ) );+        avail  = cursor + bytes;+        cursor = 0;+        refill = 0;+      }++      end = start;++      /* should we skip an optional character like \n or \r? */+      if ( start < avail && buf[start] == to_skip )+      {+        start  += 1;+        to_skip = NO_SKIP;+        continue;+      }++      /* try to find the end of the line */+      while ( end < avail && buf[end] != '\n' && buf[end] != '\r' )+        end++;++      /* if we hit the end of the buffer, try shifting its content */+      /* or even resizing it                                       */+      if ( end >= avail )+      {+        if ( bytes == 0 )  /* last line in file doesn't end in \r or \n */+          break;           /* ignore it then exit                       */++        if ( start == 0 )+        {+          /* this line is definitely too long; try resizing the input */+          /* buffer a bit to handle it.                               */+          FT_ULong  new_size;+++          if ( buf_size >= 65536UL )  /* limit ourselves to 64KByte */+          {+            error = BDF_Err_Invalid_Argument;+            goto Exit;+          }++          new_size = buf_size * 2;+          if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) )+            goto Exit;++          cursor   = buf_size;+          buf_size = new_size;+        }+        else+        {+          bytes = avail - start;++          FT_MEM_COPY( buf, buf + start, bytes );++          cursor = bytes;+          avail -= bytes;+          start  = 0;+        }+        refill = 1;+        continue;+      }++      /* Temporarily NUL-terminate the line. */+      hold     = buf[end];+      buf[end] = 0;++      /* XXX: Use encoding independent value for 0x1a */+      if ( buf[start] != '#' && buf[start] != 0x1a && end > start )+      {+        error = (*cb)( buf + start, end - start, lineno,+                       (void*)&cb, client_data );+        /* Redo if we have encountered CHARS without properties. */+        if ( error == -1 )+          error = (*cb)( buf + start, end - start, lineno,+                         (void*)&cb, client_data );+        if ( error )+          break;+      }++      lineno  += 1;+      buf[end] = (char)hold;+      start    = end + 1;++      if ( hold == '\n' )+        to_skip = '\r';+      else if ( hold == '\r' )+        to_skip = '\n';+      else+        to_skip = NO_SKIP;+    }++    *lno = lineno;++  Exit:+    FT_FREE( buf );+    return error;+  }+++  /* XXX: make this work with EBCDIC also */++  static const unsigned char  a2i[128] =+  {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00+  };++  static const unsigned char  odigits[32] =+  {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+  };++  static const unsigned char  ddigits[32] =+  {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+  };++  static const unsigned char  hdigits[32] =+  {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,+    0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+  };+++#define isdigok( m, d )  (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) )+++  /* Routine to convert an ASCII string into an unsigned long integer. */+  static unsigned long+  _bdf_atoul( char*   s,+              char**  end,+              int     base )+  {+    unsigned long         v;+    const unsigned char*  dmap;+++    if ( s == 0 || *s == 0 )+      return 0;++    /* Make sure the radix is something recognizable.  Default to 10. */+    switch ( base )+    {+    case 8:+      dmap = odigits;+      break;+    case 16:+      dmap = hdigits;+      break;+    default:+      base = 10;+      dmap = ddigits;+      break;+    }++    /* Check for the special hex prefix. */+    if ( *s == '0'                                  &&+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )+    {+      base = 16;+      dmap = hdigits;+      s   += 2;+    }++    for ( v = 0; isdigok( dmap, *s ); s++ )+      v = v * base + a2i[(int)*s];++    if ( end != 0 )+      *end = s;++    return v;+  }+++  /* Routine to convert an ASCII string into an signed long integer. */+  static long+  _bdf_atol( char*   s,+             char**  end,+             int     base )+  {+    long                  v, neg;+    const unsigned char*  dmap;+++    if ( s == 0 || *s == 0 )+      return 0;++    /* Make sure the radix is something recognizable.  Default to 10. */+    switch ( base )+    {+    case 8:+      dmap = odigits;+      break;+    case 16:+      dmap = hdigits;+      break;+    default:+      base = 10;+      dmap = ddigits;+      break;+    }++    /* Check for a minus sign. */+    neg = 0;+    if ( *s == '-' )+    {+      s++;+      neg = 1;+    }++    /* Check for the special hex prefix. */+    if ( *s == '0'                                  &&+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )+    {+      base = 16;+      dmap = hdigits;+      s   += 2;+    }++    for ( v = 0; isdigok( dmap, *s ); s++ )+      v = v * base + a2i[(int)*s];++    if ( end != 0 )+      *end = s;++    return ( !neg ) ? v : -v;+  }+++  /* Routine to convert an ASCII string into an signed short integer. */+  static short+  _bdf_atos( char*   s,+             char**  end,+             int     base )+  {+    short                 v, neg;+    const unsigned char*  dmap;+++    if ( s == 0 || *s == 0 )+      return 0;++    /* Make sure the radix is something recognizable.  Default to 10. */+    switch ( base )+    {+    case 8:+      dmap = odigits;+      break;+    case 16:+      dmap = hdigits;+      break;+    default:+      base = 10;+      dmap = ddigits;+      break;+    }++    /* Check for a minus. */+    neg = 0;+    if ( *s == '-' )+    {+      s++;+      neg = 1;+    }++    /* Check for the special hex prefix. */+    if ( *s == '0'                                  &&+         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )+    {+      base = 16;+      dmap = hdigits;+      s   += 2;+    }++    for ( v = 0; isdigok( dmap, *s ); s++ )+      v = (short)( v * base + a2i[(int)*s] );++    if ( end != 0 )+      *end = s;++    return (short)( ( !neg ) ? v : -v );+  }+++  /* Routine to compare two glyphs by encoding so they can be sorted. */+  static int+  by_encoding( const void*  a,+               const void*  b )+  {+    bdf_glyph_t  *c1, *c2;+++    c1 = (bdf_glyph_t *)a;+    c2 = (bdf_glyph_t *)b;++    if ( c1->encoding < c2->encoding )+      return -1;++    if ( c1->encoding > c2->encoding )+      return 1;++    return 0;+  }+++  static FT_Error+  bdf_create_property( char*        name,+                       int          format,+                       bdf_font_t*  font )+  {+    size_t           n;+    bdf_property_t*  p;+    FT_Memory        memory = font->memory;+    FT_Error         error = BDF_Err_Ok;+++    /* First check to see if the property has      */+    /* already been added or not.  If it has, then */+    /* simply ignore it.                           */+    if ( hash_lookup( name, &(font->proptbl) ) )+      goto Exit;++    if ( FT_RENEW_ARRAY( font->user_props,+                         font->nuser_props,+                         font->nuser_props + 1 ) )+      goto Exit;++    p = font->user_props + font->nuser_props;+    FT_ZERO( p );++    n = ft_strlen( name ) + 1;+    if ( n > FT_ULONG_MAX )+      return BDF_Err_Invalid_Argument;++    if ( FT_NEW_ARRAY( p->name, n ) )+      goto Exit;++    FT_MEM_COPY( (char *)p->name, name, n );++    p->format  = format;+    p->builtin = 0;++    n = _num_bdf_properties + font->nuser_props;++    error = hash_insert( p->name, n, &(font->proptbl), memory );+    if ( error )+      goto Exit;++    font->nuser_props++;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( bdf_property_t * )+  bdf_get_property( char*        name,+                    bdf_font_t*  font )+  {+    hashnode  hn;+    size_t    propid;+++    if ( name == 0 || *name == 0 )+      return 0;++    if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 )+      return 0;++    propid = hn->data;+    if ( propid >= _num_bdf_properties )+      return font->user_props + ( propid - _num_bdf_properties );++    return (bdf_property_t*)_bdf_properties + propid;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* BDF font file parsing flags and functions.                            */+  /*                                                                       */+  /*************************************************************************/+++  /* Parse flags. */++#define _BDF_START      0x0001+#define _BDF_FONT_NAME  0x0002+#define _BDF_SIZE       0x0004+#define _BDF_FONT_BBX   0x0008+#define _BDF_PROPS      0x0010+#define _BDF_GLYPHS     0x0020+#define _BDF_GLYPH      0x0040+#define _BDF_ENCODING   0x0080+#define _BDF_SWIDTH     0x0100+#define _BDF_DWIDTH     0x0200+#define _BDF_BBX        0x0400+#define _BDF_BITMAP     0x0800++#define _BDF_SWIDTH_ADJ  0x1000++#define _BDF_GLYPH_BITS ( _BDF_GLYPH    | \+                          _BDF_ENCODING | \+                          _BDF_SWIDTH   | \+                          _BDF_DWIDTH   | \+                          _BDF_BBX      | \+                          _BDF_BITMAP   )++#define _BDF_GLYPH_WIDTH_CHECK   0x40000000UL+#define _BDF_GLYPH_HEIGHT_CHECK  0x80000000UL+++  /* Auto correction messages. */+#define ACMSG1   "FONT_ASCENT property missing.  " \+                 "Added \"FONT_ASCENT %hd\".\n"+#define ACMSG2   "FONT_DESCENT property missing.  " \+                 "Added \"FONT_DESCENT %hd\".\n"+#define ACMSG3   "Font width != actual width.  Old: %hd New: %hd.\n"+#define ACMSG4   "Font left bearing != actual left bearing.  " \+                 "Old: %hd New: %hd.\n"+#define ACMSG5   "Font ascent != actual ascent.  Old: %hd New: %hd.\n"+#define ACMSG6   "Font descent != actual descent.  Old: %hd New: %hd.\n"+#define ACMSG7   "Font height != actual height. Old: %hd New: %hd.\n"+#define ACMSG8   "Glyph scalable width (SWIDTH) adjustments made.\n"+#define ACMSG9   "SWIDTH field missing at line %ld.  Set automatically.\n"+#define ACMSG10  "DWIDTH field missing at line %ld.  Set to glyph width.\n"+#define ACMSG11  "SIZE bits per pixel field adjusted to %hd.\n"+#define ACMSG12  "Duplicate encoding %ld (%s) changed to unencoded.\n"+#define ACMSG13  "Glyph %ld extra rows removed.\n"+#define ACMSG14  "Glyph %ld extra columns removed.\n"+#define ACMSG15  "Incorrect glyph count: %ld indicated but %ld found.\n"++  /* Error messages. */+#define ERRMSG1  "[line %ld] Missing \"%s\" line.\n"+#define ERRMSG2  "[line %ld] Font header corrupted or missing fields.\n"+#define ERRMSG3  "[line %ld] Font glyphs corrupted or missing fields.\n"+#define ERRMSG4  "[line %ld] BBX too big.\n"+++  static FT_Error+  _bdf_add_comment( bdf_font_t*    font,+                    char*          comment,+                    unsigned long  len )+  {+    char*      cp;+    FT_Memory  memory = font->memory;+    FT_Error   error = BDF_Err_Ok;+++    if ( FT_RENEW_ARRAY( font->comments,+                         font->comments_len,+                         font->comments_len + len + 1 ) )+      goto Exit;++    cp = font->comments + font->comments_len;++    FT_MEM_COPY( cp, comment, len );+    cp[len] = '\n';++    font->comments_len += len + 1;++  Exit:+    return error;+  }+++  /* Set the spacing from the font name if it exists, or set it to the */+  /* default specified in the options.                                 */+  static FT_Error+  _bdf_set_default_spacing( bdf_font_t*     font,+                            bdf_options_t*  opts )+  {+    size_t       len;+    char         name[256];+    _bdf_list_t  list;+    FT_Memory    memory;+    FT_Error     error = BDF_Err_Ok;+++    if ( font == 0 || font->name == 0 || font->name[0] == 0 )+    {+      error = BDF_Err_Invalid_Argument;+      goto Exit;+    }++    memory = font->memory;++    _bdf_list_init( &list, memory );++    font->spacing = opts->font_spacing;++    len = ft_strlen( font->name ) + 1;+    /* Limit ourselves to 256 characters in the font name. */+    if ( len >= 256 )+    {+      error = BDF_Err_Invalid_Argument;+      goto Exit;+    }++    FT_MEM_COPY( name, font->name, len );++    error = _bdf_list_split( &list, (char *)"-", name, len );+    if ( error )+      goto Fail;++    if ( list.used == 15 )+    {+      switch ( list.field[11][0] )+      {+      case 'C':+      case 'c':+        font->spacing = BDF_CHARCELL;+        break;+      case 'M':+      case 'm':+        font->spacing = BDF_MONOWIDTH;+        break;+      case 'P':+      case 'p':+        font->spacing = BDF_PROPORTIONAL;+        break;+      }+    }++  Fail:+    _bdf_list_done( &list );++  Exit:+    return error;+  }+++  /* Determine whether the property is an atom or not.  If it is, then */+  /* clean it up so the double quotes are removed if they exist.       */+  static int+  _bdf_is_atom( char*          line,+                unsigned long  linelen,+                char**         name,+                char**         value,+                bdf_font_t*    font )+  {+    int              hold;+    char             *sp, *ep;+    bdf_property_t*  p;+++    *name = sp = ep = line;++    while ( *ep && *ep != ' ' && *ep != '\t' )+      ep++;++    hold = -1;+    if ( *ep )+    {+      hold = *ep;+      *ep  = 0;+    }++    p = bdf_get_property( sp, font );++    /* Restore the character that was saved before any return can happen. */+    if ( hold != -1 )+      *ep = (char)hold;++    /* If the property exists and is not an atom, just return here. */+    if ( p && p->format != BDF_ATOM )+      return 0;++    /* The property is an atom.  Trim all leading and trailing whitespace */+    /* and double quotes for the atom value.                              */+    sp = ep;+    ep = line + linelen;++    /* Trim the leading whitespace if it exists. */+    *sp++ = 0;+    while ( *sp                           &&+            ( *sp == ' ' || *sp == '\t' ) )+      sp++;++    /* Trim the leading double quote if it exists. */+    if ( *sp == '"' )+      sp++;+    *value = sp;++    /* Trim the trailing whitespace if it exists. */+    while ( ep > sp                                       &&+            ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) )+      *--ep = 0;++    /* Trim the trailing double quote if it exists. */+    if ( ep > sp && *( ep - 1 ) == '"' )+      *--ep = 0;++    return 1;+  }+++  static FT_Error+  _bdf_add_property( bdf_font_t*  font,+                     char*        name,+                     char*        value )+  {+    size_t          propid;+    hashnode        hn;+    bdf_property_t  *prop, *fp;+    FT_Memory       memory = font->memory;+    FT_Error        error = BDF_Err_Ok;+++    /* First, check to see if the property already exists in the font. */+    if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 )+    {+      /* The property already exists in the font, so simply replace */+      /* the value of the property with the current value.          */+      fp = font->props + hn->data;++      switch ( fp->format )+      {+      case BDF_ATOM:+        /* Delete the current atom if it exists. */+        FT_FREE( fp->value.atom );++        if ( value && value[0] != 0 )+        {+          if ( FT_STRDUP( fp->value.atom, value ) )+            goto Exit;+        }+        break;++      case BDF_INTEGER:+        fp->value.l = _bdf_atol( value, 0, 10 );+        break;++      case BDF_CARDINAL:+        fp->value.ul = _bdf_atoul( value, 0, 10 );+        break;++      default:+        ;+      }++      goto Exit;+    }++    /* See whether this property type exists yet or not. */+    /* If not, create it.                                */+    hn = hash_lookup( name, &(font->proptbl) );+    if ( hn == 0 )+    {+      error = bdf_create_property( name, BDF_ATOM, font );+      if ( error )+        goto Exit;+      hn = hash_lookup( name, &(font->proptbl) );+    }++    /* Allocate another property if this is overflow. */+    if ( font->props_used == font->props_size )+    {+      if ( font->props_size == 0 )+      {+        if ( FT_NEW_ARRAY( font->props, 1 ) )+          goto Exit;+      }+      else+      {+        if ( FT_RENEW_ARRAY( font->props,+                             font->props_size,+                             font->props_size + 1 ) )+          goto Exit;+      }++      fp = font->props + font->props_size;+      FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) );+      font->props_size++;+    }++    propid = hn->data;+    if ( propid >= _num_bdf_properties )+      prop = font->user_props + ( propid - _num_bdf_properties );+    else+      prop = (bdf_property_t*)_bdf_properties + propid;++    fp = font->props + font->props_used;++    fp->name    = prop->name;+    fp->format  = prop->format;+    fp->builtin = prop->builtin;++    switch ( prop->format )+    {+    case BDF_ATOM:+      fp->value.atom = 0;+      if ( value != 0 && value[0] )+      {+        if ( FT_STRDUP( fp->value.atom, value ) )+          goto Exit;+      }+      break;++    case BDF_INTEGER:+      fp->value.l = _bdf_atol( value, 0, 10 );+      break;++    case BDF_CARDINAL:+      fp->value.ul = _bdf_atoul( value, 0, 10 );+      break;+    }++    /* If the property happens to be a comment, then it doesn't need */+    /* to be added to the internal hash table.                       */+    if ( ft_memcmp( name, "COMMENT", 7 ) != 0 )+    {+      /* Add the property to the font property table. */+      error = hash_insert( fp->name,+                           font->props_used,+                           (hashtable *)font->internal,+                           memory );+      if ( error )+        goto Exit;+    }++    font->props_used++;++    /* Some special cases need to be handled here.  The DEFAULT_CHAR       */+    /* property needs to be located if it exists in the property list, the */+    /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are        */+    /* present, and the SPACING property should override the default       */+    /* spacing.                                                            */+    if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 )+      font->default_char = fp->value.l;+    else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 )+      font->font_ascent = fp->value.l;+    else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 )+      font->font_descent = fp->value.l;+    else if ( ft_memcmp( name, "SPACING", 7 ) == 0 )+    {+      if ( !fp->value.atom )+      {+        error = BDF_Err_Invalid_File_Format;+        goto Exit;+      }++      if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' )+        font->spacing = BDF_PROPORTIONAL;+      else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' )+        font->spacing = BDF_MONOWIDTH;+      else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' )+        font->spacing = BDF_CHARCELL;+    }++  Exit:+    return error;+  }+++  static const unsigned char nibble_mask[8] =+  {+    0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE+  };+++  /* Actually parse the glyph info and bitmaps. */+  static FT_Error+  _bdf_parse_glyphs( char*          line,+                     unsigned long  linelen,+                     unsigned long  lineno,+                     void*          call_data,+                     void*          client_data )+  {+    int                c, mask_index;+    char*              s;+    unsigned char*     bp;+    unsigned long      i, slen, nibbles;++    _bdf_parse_t*      p;+    bdf_glyph_t*       glyph;+    bdf_font_t*        font;++    FT_Memory          memory;+    FT_Error           error = BDF_Err_Ok;++    FT_UNUSED( call_data );+    FT_UNUSED( lineno );        /* only used in debug mode */+++    p = (_bdf_parse_t *)client_data;++    font   = p->font;+    memory = font->memory;++    /* Check for a comment. */+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )+    {+      linelen -= 7;++      s = line + 7;+      if ( *s != 0 )+      {+        s++;+        linelen--;+      }+      error = _bdf_add_comment( p->font, s, linelen );+      goto Exit;+    }++    /* The very first thing expected is the number of glyphs. */+    if ( !( p->flags & _BDF_GLYPHS ) )+    {+      if ( ft_memcmp( line, "CHARS", 5 ) != 0 )+      {+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" ));+        error = BDF_Err_Missing_Chars_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;+      p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 );++      /* Make sure the number of glyphs is non-zero. */+      if ( p->cnt == 0 )+        font->glyphs_size = 64;++      /* Limit ourselves to 1,114,112 glyphs in the font (this is the */+      /* number of code points available in Unicode).                 */+      if ( p->cnt >= 1114112UL )+      {+        error = BDF_Err_Invalid_Argument;+        goto Exit;+      }++      if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) )+        goto Exit;++      p->flags |= _BDF_GLYPHS;++      goto Exit;+    }++    /* Check for the ENDFONT field. */+    if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 )+    {+      /* Sort the glyphs by encoding. */+      ft_qsort( (char *)font->glyphs,+                font->glyphs_used,+                sizeof ( bdf_glyph_t ),+                by_encoding );++      p->flags &= ~_BDF_START;++      goto Exit;+    }++    /* Check for the ENDCHAR field. */+    if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 )+    {+      p->glyph_enc = 0;+      p->flags    &= ~_BDF_GLYPH_BITS;++      goto Exit;+    }++    /* Check to see whether a glyph is being scanned but should be */+    /* ignored because it is an unencoded glyph.                   */+    if ( ( p->flags & _BDF_GLYPH )     &&+         p->glyph_enc            == -1 &&+         p->opts->keep_unencoded == 0  )+      goto Exit;++    /* Check for the STARTCHAR field. */+    if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 )+    {+      /* Set the character name in the parse info first until the */+      /* encoding can be checked for an unencoded character.      */+      FT_FREE( p->glyph_name );++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      _bdf_list_shift( &p->list, 1 );++      s = _bdf_list_join( &p->list, ' ', &slen );++      if ( !s )+      {+        error = BDF_Err_Invalid_File_Format;+        goto Exit;+      }++      if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) )+        goto Exit;++      FT_MEM_COPY( p->glyph_name, s, slen + 1 );++      p->flags |= _BDF_GLYPH;++      goto Exit;+    }++    /* Check for the ENCODING field. */+    if ( ft_memcmp( line, "ENCODING", 8 ) == 0 )+    {+      if ( !( p->flags & _BDF_GLYPH ) )+      {+        /* Missing STARTCHAR field. */+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" ));+        error = BDF_Err_Missing_Startchar_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 );++      /* Check that the encoding is in the range [0,65536] because        */+      /* otherwise p->have (a bitmap with static size) overflows.         */+      if ( (size_t)p->glyph_enc >= sizeof ( p->have ) * 8 )+      {+        error = BDF_Err_Invalid_File_Format;+        goto Exit;+      }++      /* Check to see whether this encoding has already been encountered. */+      /* If it has then change it to unencoded so it gets added if        */+      /* indicated.                                                       */+      if ( p->glyph_enc >= 0 )+      {+        if ( _bdf_glyph_modified( p->have, p->glyph_enc ) )+        {+          /* Emit a message saying a glyph has been moved to the */+          /* unencoded area.                                     */+          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12,+                      p->glyph_enc, p->glyph_name ));+          p->glyph_enc = -1;+          font->modified = 1;+        }+        else+          _bdf_set_glyph_modified( p->have, p->glyph_enc );+      }++      if ( p->glyph_enc >= 0 )+      {+        /* Make sure there are enough glyphs allocated in case the */+        /* number of characters happen to be wrong.                */+        if ( font->glyphs_used == font->glyphs_size )+        {+          if ( FT_RENEW_ARRAY( font->glyphs,+                               font->glyphs_size,+                               font->glyphs_size + 64 ) )+            goto Exit;++          font->glyphs_size += 64;+        }++        glyph           = font->glyphs + font->glyphs_used++;+        glyph->name     = p->glyph_name;+        glyph->encoding = p->glyph_enc;++        /* Reset the initial glyph info. */+        p->glyph_name = 0;+      }+      else+      {+        /* Unencoded glyph.  Check to see whether it should */+        /* be added or not.                                 */+        if ( p->opts->keep_unencoded != 0 )+        {+          /* Allocate the next unencoded glyph. */+          if ( font->unencoded_used == font->unencoded_size )+          {+            if ( FT_RENEW_ARRAY( font->unencoded ,+                                 font->unencoded_size,+                                 font->unencoded_size + 4 ) )+              goto Exit;++            font->unencoded_size += 4;+          }++          glyph           = font->unencoded + font->unencoded_used;+          glyph->name     = p->glyph_name;+          glyph->encoding = font->unencoded_used++;+        }+        else+          /* Free up the glyph name if the unencoded shouldn't be */+          /* kept.                                                */+          FT_FREE( p->glyph_name );++        p->glyph_name = 0;+      }++      /* Clear the flags that might be added when width and height are */+      /* checked for consistency.                                      */+      p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK );++      p->flags |= _BDF_ENCODING;++      goto Exit;+    }++    /* Point at the glyph being constructed. */+    if ( p->glyph_enc == -1 )+      glyph = font->unencoded + ( font->unencoded_used - 1 );+    else+      glyph = font->glyphs + ( font->glyphs_used - 1 );++    /* Check to see whether a bitmap is being constructed. */+    if ( p->flags & _BDF_BITMAP )+    {+      /* If there are more rows than are specified in the glyph metrics, */+      /* ignore the remaining lines.                                     */+      if ( p->row >= (unsigned long)glyph->bbx.height )+      {+        if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) )+        {+          FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding ));+          p->flags |= _BDF_GLYPH_HEIGHT_CHECK;+          font->modified = 1;+        }++        goto Exit;+      }++      /* Only collect the number of nibbles indicated by the glyph     */+      /* metrics.  If there are more columns, they are simply ignored. */+      nibbles = glyph->bpr << 1;+      bp      = glyph->bitmap + p->row * glyph->bpr;++      for ( i = 0; i < nibbles; i++ )+      {+        c = line[i];+        *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] );+        if ( i + 1 < nibbles && ( i & 1 ) )+          *++bp = 0;+      }++      /* Remove possible garbage at the right. */+      mask_index = ( glyph->bbx.width * p->font->bpp ) & 7;+      if ( glyph->bbx.width )+        *bp &= nibble_mask[mask_index];++      /* If any line has extra columns, indicate they have been removed. */+      if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) &&+           !( p->flags & _BDF_GLYPH_WIDTH_CHECK )                   )+      {+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding ));+        p->flags       |= _BDF_GLYPH_WIDTH_CHECK;+        font->modified  = 1;+      }++      p->row++;+      goto Exit;+    }++    /* Expect the SWIDTH (scalable width) field next. */+    if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 )+    {+      if ( !( p->flags & _BDF_ENCODING ) )+      {+        /* Missing ENCODING field. */+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" ));+        error = BDF_Err_Missing_Encoding_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 );+      p->flags |= _BDF_SWIDTH;++      goto Exit;+    }++    /* Expect the DWIDTH (scalable width) field next. */+    if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 )+    {+      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 );++      if ( !( p->flags & _BDF_SWIDTH ) )+      {+        /* Missing SWIDTH field.  Emit an auto correction message and set */+        /* the scalable width from the device width.                      */+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno ));++        glyph->swidth = (unsigned short)FT_MulDiv(+                          glyph->dwidth, 72000L,+                          (FT_Long)( font->point_size *+                                     font->resolution_x ) );+      }++      p->flags |= _BDF_DWIDTH;+      goto Exit;+    }++    /* Expect the BBX field next. */+    if ( ft_memcmp( line, "BBX", 3 ) == 0 )+    {+      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      glyph->bbx.width    = _bdf_atos( p->list.field[1], 0, 10 );+      glyph->bbx.height   = _bdf_atos( p->list.field[2], 0, 10 );+      glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 );+      glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 );++      /* Generate the ascent and descent of the character. */+      glyph->bbx.ascent  = (short)( glyph->bbx.height + glyph->bbx.y_offset );+      glyph->bbx.descent = (short)( -glyph->bbx.y_offset );++      /* Determine the overall font bounding box as the characters are */+      /* loaded so corrections can be done later if indicated.         */+      p->maxas    = (short)FT_MAX( glyph->bbx.ascent, p->maxas );+      p->maxds    = (short)FT_MAX( glyph->bbx.descent, p->maxds );++      p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset );++      p->maxrb    = (short)FT_MAX( p->rbearing, p->maxrb );+      p->minlb    = (short)FT_MIN( glyph->bbx.x_offset, p->minlb );+      p->maxlb    = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb );++      if ( !( p->flags & _BDF_DWIDTH ) )+      {+        /* Missing DWIDTH field.  Emit an auto correction message and set */+        /* the device width to the glyph width.                           */+        FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno ));+        glyph->dwidth = glyph->bbx.width;+      }++      /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */+      /* value if necessary.                                            */+      if ( p->opts->correct_metrics != 0 )+      {+        /* Determine the point size of the glyph. */+        unsigned short  sw = (unsigned short)FT_MulDiv(+                               glyph->dwidth, 72000L,+                               (FT_Long)( font->point_size *+                                          font->resolution_x ) );+++        if ( sw != glyph->swidth )+        {+          glyph->swidth = sw;++          if ( p->glyph_enc == -1 )+            _bdf_set_glyph_modified( font->umod,+                                     font->unencoded_used - 1 );+          else+            _bdf_set_glyph_modified( font->nmod, glyph->encoding );++          p->flags       |= _BDF_SWIDTH_ADJ;+          font->modified  = 1;+        }+      }++      p->flags |= _BDF_BBX;+      goto Exit;+    }++    /* And finally, gather up the bitmap. */+    if ( ft_memcmp( line, "BITMAP", 6 ) == 0 )+    {+      unsigned long  bitmap_size;+++      if ( !( p->flags & _BDF_BBX ) )+      {+        /* Missing BBX field. */+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" ));+        error = BDF_Err_Missing_Bbx_Field;+        goto Exit;+      }++      /* Allocate enough space for the bitmap. */+      glyph->bpr   = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3;++      bitmap_size = glyph->bpr * glyph->bbx.height;+      if ( bitmap_size > 0xFFFFU )+      {+        FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno ));+        error = BDF_Err_Bbx_Too_Big;+        goto Exit;+      }+      else+        glyph->bytes = (unsigned short)bitmap_size;++      if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) )+        goto Exit;++      p->row    = 0;+      p->flags |= _BDF_BITMAP;++      goto Exit;+    }++    error = BDF_Err_Invalid_File_Format;++  Exit:+    if ( error && ( p->flags & _BDF_GLYPH ) )+      FT_FREE( p->glyph_name );++    return error;+  }+++  /* Load the font properties. */+  static FT_Error+  _bdf_parse_properties( char*          line,+                         unsigned long  linelen,+                         unsigned long  lineno,+                         void*          call_data,+                         void*          client_data )+  {+    unsigned long      vlen;+    _bdf_line_func_t*  next;+    _bdf_parse_t*      p;+    char*              name;+    char*              value;+    char               nbuf[128];+    FT_Error           error = BDF_Err_Ok;++    FT_UNUSED( lineno );+++    next = (_bdf_line_func_t *)call_data;+    p    = (_bdf_parse_t *)    client_data;++    /* Check for the end of the properties. */+    if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 )+    {+      /* If the FONT_ASCENT or FONT_DESCENT properties have not been      */+      /* encountered yet, then make sure they are added as properties and */+      /* make sure they are set from the font bounding box info.          */+      /*                                                                  */+      /* This is *always* done regardless of the options, because X11     */+      /* requires these two fields to compile fonts.                      */+      if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 )+      {+        p->font->font_ascent = p->font->bbx.ascent;+        ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );+        error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf );+        if ( error )+          goto Exit;++        FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));+        p->font->modified = 1;+      }++      if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 )+      {+        p->font->font_descent = p->font->bbx.descent;+        ft_sprintf( nbuf, "%hd", p->font->bbx.descent );+        error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf );+        if ( error )+          goto Exit;++        FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));+        p->font->modified = 1;+      }++      p->flags &= ~_BDF_PROPS;+      *next     = _bdf_parse_glyphs;++      goto Exit;+    }++    /* Ignore the _XFREE86_GLYPH_RANGES properties. */+    if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 )+      goto Exit;++    /* Handle COMMENT fields and properties in a special way to preserve */+    /* the spacing.                                                      */+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )+    {+      name = value = line;+      value += 7;+      if ( *value )+        *value++ = 0;+      error = _bdf_add_property( p->font, name, value );+      if ( error )+        goto Exit;+    }+    else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) )+    {+      error = _bdf_add_property( p->font, name, value );+      if ( error )+        goto Exit;+    }+    else+    {+      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;+      name = p->list.field[0];++      _bdf_list_shift( &p->list, 1 );+      value = _bdf_list_join( &p->list, ' ', &vlen );++      error = _bdf_add_property( p->font, name, value );+      if ( error )+        goto Exit;+    }++  Exit:+    return error;+  }+++  /* Load the font header. */+  static FT_Error+  _bdf_parse_start( char*          line,+                    unsigned long  linelen,+                    unsigned long  lineno,+                    void*          call_data,+                    void*          client_data )+  {+    unsigned long      slen;+    _bdf_line_func_t*  next;+    _bdf_parse_t*      p;+    bdf_font_t*        font;+    char               *s;++    FT_Memory          memory = NULL;+    FT_Error           error  = BDF_Err_Ok;++    FT_UNUSED( lineno );            /* only used in debug mode */+++    next = (_bdf_line_func_t *)call_data;+    p    = (_bdf_parse_t *)    client_data;++    if ( p->font )+      memory = p->font->memory;++    /* Check for a comment.  This is done to handle those fonts that have */+    /* comments before the STARTFONT line for some reason.                */+    if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )+    {+      if ( p->opts->keep_comments != 0 && p->font != 0 )+      {+        linelen -= 7;++        s = line + 7;+        if ( *s != 0 )+        {+          s++;+          linelen--;+        }++        error = _bdf_add_comment( p->font, s, linelen );+        if ( error )+          goto Exit;+        /* here font is not defined! */+      }++      goto Exit;+    }++    if ( !( p->flags & _BDF_START ) )+    {+      memory = p->memory;++      if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 )+      {+        /* No STARTFONT field is a good indication of a problem. */+        error = BDF_Err_Missing_Startfont_Field;+        goto Exit;+      }++      p->flags = _BDF_START;+      font = p->font = 0;++      if ( FT_NEW( font ) )+        goto Exit;+      p->font = font;++      font->memory = p->memory;+      p->memory    = 0;++      { /* setup */+        size_t           i;+        bdf_property_t*  prop;+++        error = hash_init( &(font->proptbl), memory );+        if ( error )+          goto Exit;+        for ( i = 0, prop = (bdf_property_t*)_bdf_properties;+              i < _num_bdf_properties; i++, prop++ )+        {+          error = hash_insert( prop->name, i,+                               &(font->proptbl), memory );+          if ( error )+            goto Exit;+        }+      }++      if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) )+        goto Exit;+      error = hash_init( (hashtable *)p->font->internal,memory );+      if ( error )+        goto Exit;+      p->font->spacing      = p->opts->font_spacing;+      p->font->default_char = -1;++      goto Exit;+    }++    /* Check for the start of the properties. */+    if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 )+    {+      if ( !( p->flags & _BDF_FONT_BBX ) )+      {+        /* Missing the FONTBOUNDINGBOX field. */+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));+        error = BDF_Err_Missing_Fontboundingbox_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;+      /* at this point, `p->font' can't be NULL */+      p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 );++      if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )+        goto Exit;++      p->flags |= _BDF_PROPS;+      *next     = _bdf_parse_properties;++      goto Exit;+    }++    /* Check for the FONTBOUNDINGBOX field. */+    if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )+    {+      if ( !( p->flags & _BDF_SIZE ) )+      {+        /* Missing the SIZE field. */+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" ));+        error = BDF_Err_Missing_Size_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      p->font->bbx.width  = _bdf_atos( p->list.field[1], 0, 10 );+      p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 );++      p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 );+      p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 );++      p->font->bbx.ascent  = (short)( p->font->bbx.height ++                                      p->font->bbx.y_offset );++      p->font->bbx.descent = (short)( -p->font->bbx.y_offset );++      p->flags |= _BDF_FONT_BBX;++      goto Exit;+    }++    /* The next thing to check for is the FONT field. */+    if ( ft_memcmp( line, "FONT", 4 ) == 0 )+    {+      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;+      _bdf_list_shift( &p->list, 1 );++      s = _bdf_list_join( &p->list, ' ', &slen );++      if ( !s )+      {+        error = BDF_Err_Invalid_File_Format;+        goto Exit;+      }++      /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */+      FT_FREE( p->font->name );++      if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) )+        goto Exit;+      FT_MEM_COPY( p->font->name, s, slen + 1 );++      /* If the font name is an XLFD name, set the spacing to the one in  */+      /* the font name.  If there is no spacing fall back on the default. */+      error = _bdf_set_default_spacing( p->font, p->opts );+      if ( error )+        goto Exit;++      p->flags |= _BDF_FONT_NAME;++      goto Exit;+    }++    /* Check for the SIZE field. */+    if ( ft_memcmp( line, "SIZE", 4 ) == 0 )+    {+      if ( !( p->flags & _BDF_FONT_NAME ) )+      {+        /* Missing the FONT field. */+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" ));+        error = BDF_Err_Missing_Font_Field;+        goto Exit;+      }++      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );+      if ( error )+        goto Exit;++      p->font->point_size   = _bdf_atoul( p->list.field[1], 0, 10 );+      p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 );+      p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 );++      /* Check for the bits per pixel field. */+      if ( p->list.used == 5 )+      {+        unsigned short bitcount, i, shift;+++        p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 );++        /* Only values 1, 2, 4, 8 are allowed. */+        shift = p->font->bpp;+        bitcount = 0;+        for ( i = 0; shift > 0; i++ )+        {+          if ( shift & 1 )+            bitcount = i;+          shift >>= 1;+        }++        shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) );++        if ( p->font->bpp > shift || p->font->bpp != shift )+        {+          /* select next higher value */+          p->font->bpp = (unsigned short)( shift << 1 );+          FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp ));+        }+      }+      else+        p->font->bpp = 1;++      p->flags |= _BDF_SIZE;++      goto Exit;+    }++    /* Check for the CHARS field -- font properties are optional */+    if ( ft_memcmp( line, "CHARS", 5 ) == 0 )+    {+      char  nbuf[128];+++      if ( !( p->flags & _BDF_FONT_BBX ) )+      {+        /* Missing the FONTBOUNDINGBOX field. */+        FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));+        error = BDF_Err_Missing_Fontboundingbox_Field;+        goto Exit;+      }++      /* Add the two standard X11 properties which are required */+      /* for compiling fonts.                                   */+      p->font->font_ascent = p->font->bbx.ascent;+      ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );+      error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf );+      if ( error )+        goto Exit;+      FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));++      p->font->font_descent = p->font->bbx.descent;+      ft_sprintf( nbuf, "%hd", p->font->bbx.descent );+      error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf );+      if ( error )+        goto Exit;+      FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));++      p->font->modified = 1;++      *next = _bdf_parse_glyphs;++      /* A special return value. */+      error = -1;+      goto Exit;+    }++    error = BDF_Err_Invalid_File_Format;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* API.                                                                  */+  /*                                                                       */+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  bdf_load_font( FT_Stream       stream,+                 FT_Memory       extmemory,+                 bdf_options_t*  opts,+                 bdf_font_t*    *font )+  {+    unsigned long  lineno = 0; /* make compiler happy */+    _bdf_parse_t   *p     = NULL;++    FT_Memory      memory = extmemory;+    FT_Error       error  = BDF_Err_Ok;+++    if ( FT_NEW( p ) )+      goto Exit;++    memory    = NULL;+    p->opts   = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts );+    p->minlb  = 32767;+    p->memory = extmemory;  /* only during font creation */++    _bdf_list_init( &p->list, extmemory );++    error = _bdf_readstream( stream, _bdf_parse_start,+                             (void *)p, &lineno );+    if ( error )+      goto Fail;++    if ( p->font != 0 )+    {+      /* If the font is not proportional, set the font's monowidth */+      /* field to the width of the font bounding box.              */+      memory = p->font->memory;++      if ( p->font->spacing != BDF_PROPORTIONAL )+        p->font->monowidth = p->font->bbx.width;++      /* If the number of glyphs loaded is not that of the original count, */+      /* indicate the difference.                                          */+      if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used )+      {+        FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt,+                    p->font->glyphs_used + p->font->unencoded_used ));+        p->font->modified = 1;+      }++      /* Once the font has been loaded, adjust the overall font metrics if */+      /* necessary.                                                        */+      if ( p->opts->correct_metrics != 0 &&+           ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) )+      {+        if ( p->maxrb - p->minlb != p->font->bbx.width )+        {+          FT_TRACE2(( "bdf_load_font: " ACMSG3,+                      p->font->bbx.width, p->maxrb - p->minlb ));+          p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb );+          p->font->modified  = 1;+        }++        if ( p->font->bbx.x_offset != p->minlb )+        {+          FT_TRACE2(( "bdf_load_font: " ACMSG4,+                      p->font->bbx.x_offset, p->minlb ));+          p->font->bbx.x_offset = p->minlb;+          p->font->modified     = 1;+        }++        if ( p->font->bbx.ascent != p->maxas )+        {+          FT_TRACE2(( "bdf_load_font: " ACMSG5,+                      p->font->bbx.ascent, p->maxas ));+          p->font->bbx.ascent = p->maxas;+          p->font->modified   = 1;+        }++        if ( p->font->bbx.descent != p->maxds )+        {+          FT_TRACE2(( "bdf_load_font: " ACMSG6,+                      p->font->bbx.descent, p->maxds ));+          p->font->bbx.descent  = p->maxds;+          p->font->bbx.y_offset = (short)( -p->maxds );+          p->font->modified     = 1;+        }++        if ( p->maxas + p->maxds != p->font->bbx.height )+        {+          FT_TRACE2(( "bdf_load_font: " ACMSG7,+                      p->font->bbx.height, p->maxas + p->maxds ));+          p->font->bbx.height = (unsigned short)( p->maxas + p->maxds );+        }++        if ( p->flags & _BDF_SWIDTH_ADJ )+          FT_TRACE2(( "bdf_load_font: " ACMSG8 ));+      }+    }++    if ( p->flags & _BDF_START )+    {+      {+        /* The ENDFONT field was never reached or did not exist. */+        if ( !( p->flags & _BDF_GLYPHS ) )+        {+          /* Error happened while parsing header. */+          FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));+          error = BDF_Err_Corrupted_Font_Header;+          goto Exit;+        }+        else+        {+          /* Error happened when parsing glyphs. */+          FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));+          error = BDF_Err_Corrupted_Font_Glyphs;+          goto Exit;+        }+      }+    }++    if ( p->font != 0 )+    {+      /* Make sure the comments are NULL terminated if they exist. */+      memory = p->font->memory;++      if ( p->font->comments_len > 0 )+      {+        if ( FT_RENEW_ARRAY( p->font->comments,+                             p->font->comments_len,+                             p->font->comments_len + 1 ) )+          goto Fail;++        p->font->comments[p->font->comments_len] = 0;+      }+    }+    else if ( error == BDF_Err_Ok )+      error = BDF_Err_Invalid_File_Format;++    *font = p->font;++  Exit:+    if ( p )+    {+      _bdf_list_done( &p->list );++      memory = extmemory;++      FT_FREE( p );+    }++    return error;++  Fail:+    bdf_free_font( p->font );++    memory = extmemory;++    FT_FREE( p->font );++    goto Exit;+  }+++  FT_LOCAL_DEF( void )+  bdf_free_font( bdf_font_t*  font )+  {+    bdf_property_t*  prop;+    unsigned long    i;+    bdf_glyph_t*     glyphs;+    FT_Memory        memory;+++    if ( font == 0 )+      return;++    memory = font->memory;++    FT_FREE( font->name );++    /* Free up the internal hash table of property names. */+    if ( font->internal )+    {+      hash_free( (hashtable *)font->internal, memory );+      FT_FREE( font->internal );+    }++    /* Free up the comment info. */+    FT_FREE( font->comments );++    /* Free up the properties. */+    for ( i = 0; i < font->props_size; i++ )+    {+      if ( font->props[i].format == BDF_ATOM )+        FT_FREE( font->props[i].value.atom );+    }++    FT_FREE( font->props );++    /* Free up the character info. */+    for ( i = 0, glyphs = font->glyphs;+          i < font->glyphs_used; i++, glyphs++ )+    {+      FT_FREE( glyphs->name );+      FT_FREE( glyphs->bitmap );+    }++    for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used;+          i++, glyphs++ )+    {+      FT_FREE( glyphs->name );+      FT_FREE( glyphs->bitmap );+    }++    FT_FREE( font->glyphs );+    FT_FREE( font->unencoded );++    /* Free up the overflow storage if it was used. */+    for ( i = 0, glyphs = font->overflow.glyphs;+          i < font->overflow.glyphs_used; i++, glyphs++ )+    {+      FT_FREE( glyphs->name );+      FT_FREE( glyphs->bitmap );+    }++    FT_FREE( font->overflow.glyphs );++    /* bdf_cleanup */+    hash_free( &(font->proptbl), memory );++    /* Free up the user defined properties. */+    for ( prop = font->user_props, i = 0;+          i < font->nuser_props; i++, prop++ )+    {+      FT_FREE( prop->name );+      if ( prop->format == BDF_ATOM )+        FT_FREE( prop->value.atom );+    }++    FT_FREE( font->user_props );++    /* FREE( font ); */ /* XXX Fixme */+  }+++  FT_LOCAL_DEF( bdf_property_t * )+  bdf_get_font_property( bdf_font_t*  font,+                         const char*  name )+  {+    hashnode  hn;+++    if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 )+      return 0;++    hn = hash_lookup( name, (hashtable *)font->internal );++    return hn ? ( font->props + hn->data ) : 0;+  }+++/* END */
+ src/cache/ftcache.c view
@@ -0,0 +1,31 @@+/***************************************************************************/+/*                                                                         */+/*  ftcache.c                                                              */+/*                                                                         */+/*    The FreeType Caching sub-system (body only).                         */+/*                                                                         */+/*  Copyright 2000-2001, 2003 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "ftcmru.c"+#include "ftcmanag.c"+#include "ftccache.c"+#include "ftccmap.c"+#include "ftcglyph.c"+#include "ftcimage.c"+#include "ftcsbits.c"+#include "ftcbasic.c"++/* END */
+ src/cache/ftcbasic.c view
@@ -0,0 +1,851 @@+/***************************************************************************/+/*                                                                         */+/*  ftcbasic.c                                                             */+/*                                                                         */+/*    The FreeType basic cache interface (body).                           */+/*                                                                         */+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_CACHE_H+#include "ftcglyph.h"+#include "ftcimage.h"+#include "ftcsbits.h"++#include "ftccback.h"+#include "ftcerror.h"++#define FT_COMPONENT  trace_cache+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*+   *  These structures correspond to the FTC_Font and FTC_ImageDesc types+   *  that were defined in version 2.1.7.+   */+  typedef struct  FTC_OldFontRec_+  {+    FTC_FaceID  face_id;+    FT_UShort   pix_width;+    FT_UShort   pix_height;++  } FTC_OldFontRec, *FTC_OldFont;+++  typedef struct  FTC_OldImageDescRec_+  {+    FTC_OldFontRec  font;+    FT_UInt32       flags;++  } FTC_OldImageDescRec, *FTC_OldImageDesc;+++  /*+   *  Notice that FTC_OldImageDescRec and FTC_ImageTypeRec are nearly+   *  identical, bit-wise.  The only difference is that the `width' and+   *  `height' fields are expressed as 16-bit integers in the old structure,+   *  and as normal `int' in the new one.+   *+   *  We are going to perform a weird hack to detect which structure is+   *  being passed to the image and sbit caches.  If the new structure's+   *  `width' is larger than 0x10000, we assume that we are really receiving+   *  an FTC_OldImageDesc.+   */++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*+   *  Basic Families+   *+   */+  typedef struct  FTC_BasicAttrRec_+  {+    FTC_ScalerRec  scaler;+    FT_UInt        load_flags;++  } FTC_BasicAttrRec, *FTC_BasicAttrs;++#define FTC_BASIC_ATTR_COMPARE( a, b )                                 \+          FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \+                   (a)->load_flags == (b)->load_flags               )++#define FTC_BASIC_ATTR_HASH( a )                                   \+          ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )+++  typedef struct  FTC_BasicQueryRec_+  {+    FTC_GQueryRec     gquery;+    FTC_BasicAttrRec  attrs;++  } FTC_BasicQueryRec, *FTC_BasicQuery;+++  typedef struct  FTC_BasicFamilyRec_+  {+    FTC_FamilyRec     family;+    FTC_BasicAttrRec  attrs;++  } FTC_BasicFamilyRec, *FTC_BasicFamily;+++  FT_CALLBACK_DEF( FT_Bool )+  ftc_basic_family_compare( FTC_MruNode  ftcfamily,+                            FT_Pointer   ftcquery )+  {+    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;+    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;+++    return FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs );+  }+++  FT_CALLBACK_DEF( FT_Error )+  ftc_basic_family_init( FTC_MruNode  ftcfamily,+                         FT_Pointer   ftcquery,+                         FT_Pointer   ftccache )+  {+    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;+    FTC_BasicQuery   query  = (FTC_BasicQuery)ftcquery;+    FTC_Cache        cache  = (FTC_Cache)ftccache;+++    FTC_Family_Init( FTC_FAMILY( family ), cache );+    family->attrs = query->attrs;+    return 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  ftc_basic_family_get_count( FTC_Family   ftcfamily,+                              FTC_Manager  manager )+  {+    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;+    FT_Error         error;+    FT_Face          face;+    FT_UInt          result = 0;+++    error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id,+                                    &face );++    if ( error || !face )+      return result;++    if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )+    {+      FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));+      FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));+    }++    if ( !error )+      result = (FT_UInt)face->num_glyphs;++    return result;+  }+++  FT_CALLBACK_DEF( FT_Error )+  ftc_basic_family_load_bitmap( FTC_Family   ftcfamily,+                                FT_UInt      gindex,+                                FTC_Manager  manager,+                                FT_Face     *aface )+  {+    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;+    FT_Error         error;+    FT_Size          size;+++    error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );+    if ( !error )+    {+      FT_Face  face = size->face;+++      error = FT_Load_Glyph( face, gindex,+                             family->attrs.load_flags | FT_LOAD_RENDER );+      if ( !error )+        *aface = face;+    }++    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  ftc_basic_family_load_glyph( FTC_Family  ftcfamily,+                               FT_UInt     gindex,+                               FTC_Cache   cache,+                               FT_Glyph   *aglyph )+  {+    FTC_BasicFamily  family = (FTC_BasicFamily)ftcfamily;+    FT_Error         error;+    FTC_Scaler       scaler = &family->attrs.scaler;+    FT_Face          face;+    FT_Size          size;+++    /* we will now load the glyph image */+    error = FTC_Manager_LookupSize( cache->manager,+                                    scaler,+                                    &size );+    if ( !error )+    {+      face = size->face;++      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );+      if ( !error )+      {+        if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||+             face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )+        {+          /* ok, copy it */+          FT_Glyph  glyph;+++          error = FT_Get_Glyph( face->glyph, &glyph );+          if ( !error )+          {+            *aglyph = glyph;+            goto Exit;+          }+        }+        else+          error = FTC_Err_Invalid_Argument;+      }+    }++  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( FT_Bool )+  ftc_basic_gnode_compare_faceid( FTC_Node    ftcgnode,+                                  FT_Pointer  ftcface_id,+                                  FTC_Cache   cache )+  {+    FTC_GNode        gnode   = (FTC_GNode)ftcgnode;+    FTC_FaceID       face_id = (FTC_FaceID)ftcface_id;+    FTC_BasicFamily  family  = (FTC_BasicFamily)gnode->family;+    FT_Bool          result;+++    result = FT_BOOL( family->attrs.scaler.face_id == face_id );+    if ( result )+    {+      /* we must call this function to avoid this node from appearing+       * in later lookups with the same face_id!+       */+      FTC_GNode_UnselectFamily( gnode, cache );+    }+    return result;+  }+++ /*+  *+  * basic image cache+  *+  */++  FT_CALLBACK_TABLE_DEF+  const FTC_IFamilyClassRec  ftc_basic_image_family_class =+  {+    {+      sizeof ( FTC_BasicFamilyRec ),+      ftc_basic_family_compare,+      ftc_basic_family_init,+      0,                        /* FTC_MruNode_ResetFunc */+      0                         /* FTC_MruNode_DoneFunc  */+    },+    ftc_basic_family_load_glyph+  };+++  FT_CALLBACK_TABLE_DEF+  const FTC_GCacheClassRec  ftc_basic_image_cache_class =+  {+    {+      ftc_inode_new,+      ftc_inode_weight,+      ftc_gnode_compare,+      ftc_basic_gnode_compare_faceid,+      ftc_inode_free,++      sizeof ( FTC_GCacheRec ),+      ftc_gcache_init,+      ftc_gcache_done+    },+    (FTC_MruListClass)&ftc_basic_image_family_class+  };+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_ImageCache_New( FTC_Manager      manager,+                      FTC_ImageCache  *acache )+  {+    return FTC_GCache_New( manager, &ftc_basic_image_cache_class,+                           (FTC_GCache*)acache );+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_ImageCache_Lookup( FTC_ImageCache  cache,+                         FTC_ImageType   type,+                         FT_UInt         gindex,+                         FT_Glyph       *aglyph,+                         FTC_Node       *anode )+  {+    FTC_BasicQueryRec  query;+    FTC_Node           node = 0; /* make compiler happy */+    FT_Error           error;+    FT_PtrDist         hash;+++    /* some argument checks are delayed to FTC_Cache_Lookup */+    if ( !aglyph )+    {+      error = FTC_Err_Invalid_Argument;+      goto Exit;+    }++    *aglyph = NULL;+    if ( anode )+      *anode  = NULL;++#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )++    /*+     *  This one is a major hack used to detect whether we are passed a+     *  regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.+     */+    if ( (FT_ULong)type->width >= 0x10000L )+    {+      FTC_OldImageDesc  desc = (FTC_OldImageDesc)type;+++      query.attrs.scaler.face_id = desc->font.face_id;+      query.attrs.scaler.width   = desc->font.pix_width;+      query.attrs.scaler.height  = desc->font.pix_height;+      query.attrs.load_flags     = desc->flags;+    }+    else++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++    {+      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )+      {+        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));+        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));+      }++      query.attrs.scaler.face_id = type->face_id;+      query.attrs.scaler.width   = type->width;+      query.attrs.scaler.height  = type->height;+      query.attrs.load_flags     = (FT_UInt)type->flags;+    }++    query.attrs.scaler.pixel = 1;+    query.attrs.scaler.x_res = 0;  /* make compilers happy */+    query.attrs.scaler.y_res = 0;++    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;++#if 1  /* inlining is about 50% faster! */+    FTC_GCACHE_LOOKUP_CMP( cache,+                           ftc_basic_family_compare,+                           FTC_GNode_Compare,+                           hash, gindex,+                           &query,+                           node,+                           error );+#else+    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),+                               hash, gindex,+                               FTC_GQUERY( &query ),+                               &node );+#endif+    if ( !error )+    {+      *aglyph = FTC_INODE( node )->glyph;++      if ( anode )+      {+        *anode = node;+        node->ref_count++;+      }+    }++  Exit:+    return error;+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_ImageCache_LookupScaler( FTC_ImageCache  cache,+                               FTC_Scaler      scaler,+                               FT_ULong        load_flags,+                               FT_UInt         gindex,+                               FT_Glyph       *aglyph,+                               FTC_Node       *anode )+  {+    FTC_BasicQueryRec  query;+    FTC_Node           node = 0; /* make compiler happy */+    FT_Error           error;+    FT_PtrDist         hash;+++    /* some argument checks are delayed to FTC_Cache_Lookup */+    if ( !aglyph || !scaler )+    {+      error = FTC_Err_Invalid_Argument;+      goto Exit;+    }++    *aglyph = NULL;+    if ( anode )+      *anode  = NULL;++    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */+    if ( load_flags > FT_UINT_MAX )+    {+      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));+      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));+    }++    query.attrs.scaler     = scaler[0];+    query.attrs.load_flags = (FT_UInt)load_flags;++    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex;++    FTC_GCACHE_LOOKUP_CMP( cache,+                           ftc_basic_family_compare,+                           FTC_GNode_Compare,+                           hash, gindex,+                           &query,+                           node,+                           error );+    if ( !error )+    {+      *aglyph = FTC_INODE( node )->glyph;++      if ( anode )+      {+        *anode = node;+        node->ref_count++;+      }+    }++  Exit:+    return error;+  }+++  +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /* yet another backwards-legacy structure */+  typedef struct  FTC_OldImage_Desc_+  {+    FTC_FontRec  font;+    FT_UInt      image_type;++  } FTC_OldImage_Desc;+++#define FTC_OLD_IMAGE_FORMAT( x )  ( (x) & 7 )+++#define ftc_old_image_format_bitmap    0x0000+#define ftc_old_image_format_outline   0x0001++#define ftc_old_image_format_mask      0x000F++#define ftc_old_image_flag_monochrome  0x0010+#define ftc_old_image_flag_unhinted    0x0020+#define ftc_old_image_flag_autohinted  0x0040+#define ftc_old_image_flag_unscaled    0x0080+#define ftc_old_image_flag_no_sbits    0x0100++  /* monochrome bitmap */+#define ftc_old_image_mono             ftc_old_image_format_bitmap   | \+                                       ftc_old_image_flag_monochrome++  /* anti-aliased bitmap */+#define ftc_old_image_grays            ftc_old_image_format_bitmap++  /* scaled outline */+#define ftc_old_image_outline          ftc_old_image_format_outline+++  static void+  ftc_image_type_from_old_desc( FTC_ImageType       typ,+                                FTC_OldImage_Desc*  desc )+  {+    typ->face_id = desc->font.face_id;+    typ->width   = desc->font.pix_width;+    typ->height  = desc->font.pix_height;++    /* convert image type flags to load flags */+    {+      FT_UInt  load_flags = FT_LOAD_DEFAULT;+      FT_UInt  type       = desc->image_type;+++      /* determine load flags, depending on the font description's */+      /* image type                                                */++      if ( FTC_OLD_IMAGE_FORMAT( type ) == ftc_old_image_format_bitmap )+      {+        if ( type & ftc_old_image_flag_monochrome )+          load_flags |= FT_LOAD_MONOCHROME;++        /* disable embedded bitmaps loading if necessary */+        if ( type & ftc_old_image_flag_no_sbits )+          load_flags |= FT_LOAD_NO_BITMAP;+      }+      else+      {+        /* we want an outline, don't load embedded bitmaps */+        load_flags |= FT_LOAD_NO_BITMAP;++        if ( type & ftc_old_image_flag_unscaled )+          load_flags |= FT_LOAD_NO_SCALE;+      }++      /* always render glyphs to bitmaps */+      load_flags |= FT_LOAD_RENDER;++      if ( type & ftc_old_image_flag_unhinted )+        load_flags |= FT_LOAD_NO_HINTING;++      if ( type & ftc_old_image_flag_autohinted )+        load_flags |= FT_LOAD_FORCE_AUTOHINT;++      typ->flags = load_flags;+    }+  }+++  FT_EXPORT( FT_Error )+  FTC_Image_Cache_New( FTC_Manager      manager,+                       FTC_ImageCache  *acache );++  FT_EXPORT( FT_Error )+  FTC_Image_Cache_Lookup( FTC_ImageCache      icache,+                          FTC_OldImage_Desc*  desc,+                          FT_UInt             gindex,+                          FT_Glyph           *aglyph );+++  FT_EXPORT_DEF( FT_Error )+  FTC_Image_Cache_New( FTC_Manager      manager,+                       FTC_ImageCache  *acache )+  {+    return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache );+  }++++  FT_EXPORT_DEF( FT_Error )+  FTC_Image_Cache_Lookup( FTC_ImageCache      icache,+                          FTC_OldImage_Desc*  desc,+                          FT_UInt             gindex,+                          FT_Glyph           *aglyph )+  {+    FTC_ImageTypeRec  type0;+++    if ( !desc )+      return FTC_Err_Invalid_Argument;++    ftc_image_type_from_old_desc( &type0, desc );++    return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,+                                   &type0,+                                   gindex,+                                   aglyph,+                                   NULL );+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++ /*+  *+  * basic small bitmap cache+  *+  */+++  FT_CALLBACK_TABLE_DEF+  const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =+  {+    {+      sizeof( FTC_BasicFamilyRec ),+      ftc_basic_family_compare,+      ftc_basic_family_init,+      0,                            /* FTC_MruNode_ResetFunc */+      0                             /* FTC_MruNode_DoneFunc  */+    },+    ftc_basic_family_get_count,+    ftc_basic_family_load_bitmap+  };+++  FT_CALLBACK_TABLE_DEF+  const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =+  {+    {+      ftc_snode_new,+      ftc_snode_weight,+      ftc_snode_compare,+      ftc_basic_gnode_compare_faceid,+      ftc_snode_free,++      sizeof ( FTC_GCacheRec ),+      ftc_gcache_init,+      ftc_gcache_done+    },+    (FTC_MruListClass)&ftc_basic_sbit_family_class+  };+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_SBitCache_New( FTC_Manager     manager,+                     FTC_SBitCache  *acache )+  {+    return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class,+                           (FTC_GCache*)acache );+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_SBitCache_Lookup( FTC_SBitCache  cache,+                        FTC_ImageType  type,+                        FT_UInt        gindex,+                        FTC_SBit      *ansbit,+                        FTC_Node      *anode )+  {+    FT_Error           error;+    FTC_BasicQueryRec  query;+    FTC_Node           node = 0; /* make compiler happy */+    FT_PtrDist         hash;+++    if ( anode )+      *anode = NULL;++    /* other argument checks delayed to FTC_Cache_Lookup */+    if ( !ansbit )+      return FTC_Err_Invalid_Argument;++    *ansbit = NULL;++#if defined( FT_CONFIG_OPTION_OLD_INTERNALS ) && ( FT_INT_MAX > 0xFFFFU )++    /*  This one is a major hack used to detect whether we are passed a+     *  regular FTC_ImageType handle, or a legacy FTC_OldImageDesc one.+     */+    if ( (FT_ULong)type->width >= 0x10000L )+    {+      FTC_OldImageDesc  desc = (FTC_OldImageDesc)type;+++      query.attrs.scaler.face_id = desc->font.face_id;+      query.attrs.scaler.width   = desc->font.pix_width;+      query.attrs.scaler.height  = desc->font.pix_height;+      query.attrs.load_flags     = desc->flags;+    }+    else++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++    {+      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )+      {+        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));+        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));+      }++      query.attrs.scaler.face_id = type->face_id;+      query.attrs.scaler.width   = type->width;+      query.attrs.scaler.height  = type->height;+      query.attrs.load_flags     = (FT_UInt)type->flags;+    }++    query.attrs.scaler.pixel = 1;+    query.attrs.scaler.x_res = 0;  /* make compilers happy */+    query.attrs.scaler.y_res = 0;++    /* beware, the hash must be the same for all glyph ranges! */+    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) ++           gindex / FTC_SBIT_ITEMS_PER_NODE;++#if 1  /* inlining is about 50% faster! */+    FTC_GCACHE_LOOKUP_CMP( cache,+                           ftc_basic_family_compare,+                           FTC_SNode_Compare,+                           hash, gindex,+                           &query,+                           node,+                           error );+#else+    error = FTC_GCache_Lookup( FTC_GCACHE( cache ),+                               hash,+                               gindex,+                               FTC_GQUERY( &query ),+                               &node );+#endif+    if ( error )+      goto Exit;++    *ansbit = FTC_SNODE( node )->sbits ++              ( gindex - FTC_GNODE( node )->gindex );++    if ( anode )+    {+      *anode = node;+      node->ref_count++;+    }++  Exit:+    return error;+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_SBitCache_LookupScaler( FTC_SBitCache  cache,+                              FTC_Scaler     scaler,+                              FT_ULong       load_flags,+                              FT_UInt        gindex,+                              FTC_SBit      *ansbit,+                              FTC_Node      *anode )+  {+    FT_Error           error;+    FTC_BasicQueryRec  query;+    FTC_Node           node = 0; /* make compiler happy */+    FT_PtrDist         hash;+++    if ( anode )+        *anode = NULL;++    /* other argument checks delayed to FTC_Cache_Lookup */+    if ( !ansbit || !scaler )+        return FTC_Err_Invalid_Argument;++    *ansbit = NULL;++    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */+    if ( load_flags > FT_UINT_MAX )+    {+      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));+      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));+    }++    query.attrs.scaler     = scaler[0];+    query.attrs.load_flags = (FT_UInt)load_flags;++    /* beware, the hash must be the same for all glyph ranges! */+    hash = FTC_BASIC_ATTR_HASH( &query.attrs ) ++             gindex / FTC_SBIT_ITEMS_PER_NODE;++    FTC_GCACHE_LOOKUP_CMP( cache,+                           ftc_basic_family_compare,+                           FTC_SNode_Compare,+                           hash, gindex,+                           &query,+                           node,+                           error );+    if ( error )+      goto Exit;++    *ansbit = FTC_SNODE( node )->sbits ++              ( gindex - FTC_GNODE( node )->gindex );++    if ( anode )+    {+      *anode = node;+      node->ref_count++;+    }++  Exit:+    return error;+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_EXPORT( FT_Error )+  FTC_SBit_Cache_New( FTC_Manager     manager,+                      FTC_SBitCache  *acache );++  FT_EXPORT( FT_Error )+  FTC_SBit_Cache_Lookup( FTC_SBitCache       cache,+                         FTC_OldImage_Desc*  desc,+                         FT_UInt             gindex,+                         FTC_SBit           *ansbit );+++  FT_EXPORT_DEF( FT_Error )+  FTC_SBit_Cache_New( FTC_Manager     manager,+                      FTC_SBitCache  *acache )+  {+    return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache );+  }+++  FT_EXPORT_DEF( FT_Error )+  FTC_SBit_Cache_Lookup( FTC_SBitCache       cache,+                         FTC_OldImage_Desc*  desc,+                         FT_UInt             gindex,+                         FTC_SBit           *ansbit )+  {+    FTC_ImageTypeRec  type0;+++    if ( !desc )+      return FTC_Err_Invalid_Argument;++    ftc_image_type_from_old_desc( &type0, desc );++    return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,+                                  &type0,+                                  gindex,+                                  ansbit,+                                  NULL );+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++/* END */
+ src/cache/ftccache.c view
@@ -0,0 +1,595 @@+/***************************************************************************/+/*                                                                         */+/*  ftccache.c                                                             */+/*                                                                         */+/*    The FreeType internal cache interface (body).                        */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "ftcmanag.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H++#include "ftccback.h"+#include "ftcerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cache+++#define FTC_HASH_MAX_LOAD  2+#define FTC_HASH_MIN_LOAD  1+#define FTC_HASH_SUB_LOAD  ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )++/* this one _must_ be a power of 2! */+#define FTC_HASH_INITIAL_SIZE  8+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                   CACHE NODE DEFINITIONS                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* add a new node to the head of the manager's circular MRU list */+  static void+  ftc_node_mru_link( FTC_Node     node,+                     FTC_Manager  manager )+  {+    void  *nl = &manager->nodes_list;+++    FTC_MruNode_Prepend( (FTC_MruNode*)nl,+                         (FTC_MruNode)node );+    manager->num_nodes++;+  }+++  /* remove a node from the manager's MRU list */+  static void+  ftc_node_mru_unlink( FTC_Node     node,+                       FTC_Manager  manager )+  {+    void  *nl = &manager->nodes_list;+++    FTC_MruNode_Remove( (FTC_MruNode*)nl,+                        (FTC_MruNode)node );+    manager->num_nodes--;+  }+++#ifndef FTC_INLINE++  /* move a node to the head of the manager's MRU list */+  static void+  ftc_node_mru_up( FTC_Node     node,+                   FTC_Manager  manager )+  {+    FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list,+                    (FTC_MruNode)node );+  }++#endif /* !FTC_INLINE */+++  /* Note that this function cannot fail.  If we cannot re-size the+   * buckets array appropriately, we simply degrade the hash table's+   * performance!+   */+  static void+  ftc_cache_resize( FTC_Cache  cache )+  {+    for (;;)+    {+      FTC_Node  node, *pnode;+      FT_UFast  p      = cache->p;+      FT_UFast  mask   = cache->mask;+      FT_UFast  count  = mask + p + 1;    /* number of buckets */+++      /* do we need to shrink the buckets array? */+      if ( cache->slack < 0 )+      {+        FTC_Node  new_list = NULL;+++        /* try to expand the buckets array _before_ splitting+         * the bucket lists+         */+        if ( p >= mask )+        {+          FT_Memory  memory = cache->memory;+          FT_Error   error;+++          /* if we can't expand the array, leave immediately */+          if ( FT_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) )+            break;+        }++        /* split a single bucket */+        pnode = cache->buckets + p;++        for (;;)+        {+          node = *pnode;+          if ( node == NULL )+            break;++          if ( node->hash & ( mask + 1 ) )+          {+            *pnode     = node->link;+            node->link = new_list;+            new_list   = node;+          }+          else+            pnode = &node->link;+        }++        cache->buckets[p + mask + 1] = new_list;++        cache->slack += FTC_HASH_MAX_LOAD;++        if ( p >= mask )+        {+          cache->mask = 2 * mask + 1;+          cache->p    = 0;+        }+        else+          cache->p = p + 1;+      }++      /* do we need to expand the buckets array? */+      else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )+      {+        FT_UFast   old_index = p + mask;+        FTC_Node*  pold;+++        if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )+          break;++        if ( p == 0 )+        {+          FT_Memory  memory = cache->memory;+          FT_Error   error;+++          /* if we can't shrink the array, leave immediately */+          if ( FT_RENEW_ARRAY( cache->buckets,+                               ( mask + 1 ) * 2, mask + 1 ) )+            break;++          cache->mask >>= 1;+          p             = cache->mask;+        }+        else+          p--;++        pnode = cache->buckets + p;+        while ( *pnode )+          pnode = &(*pnode)->link;++        pold   = cache->buckets + old_index;+        *pnode = *pold;+        *pold  = NULL;++        cache->slack -= FTC_HASH_MAX_LOAD;+        cache->p      = p;+      }+      else /* the hash table is balanced */+        break;+    }+  }+++  /* remove a node from its cache's hash table */+  static void+  ftc_node_hash_unlink( FTC_Node   node0,+                        FTC_Cache  cache )+  {+    FTC_Node  *pnode;+    FT_UInt    idx;+++    idx = (FT_UInt)( node0->hash & cache->mask );+    if ( idx < cache->p )+      idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) );++    pnode = cache->buckets + idx;++    for (;;)+    {+      FTC_Node  node = *pnode;+++      if ( node == NULL )+      {+        FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" ));+        return;+      }++      if ( node == node0 )+        break;++      pnode = &(*pnode)->link;+    }++    *pnode      = node0->link;+    node0->link = NULL;++    cache->slack++;+    ftc_cache_resize( cache );+  }+++  /* add a node to the `top' of its cache's hash table */+  static void+  ftc_node_hash_link( FTC_Node   node,+                      FTC_Cache  cache )+  {+    FTC_Node  *pnode;+    FT_UInt    idx;+++    idx = (FT_UInt)( node->hash & cache->mask );+    if ( idx < cache->p )+      idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) );++    pnode = cache->buckets + idx;++    node->link = *pnode;+    *pnode     = node;++    cache->slack--;+    ftc_cache_resize( cache );+  }+++  /* remove a node from the cache manager */+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+  FT_BASE_DEF( void )+#else+  FT_LOCAL_DEF( void )+#endif+  ftc_node_destroy( FTC_Node     node,+                    FTC_Manager  manager )+  {+    FTC_Cache  cache;+++#ifdef FT_DEBUG_ERROR+    /* find node's cache */+    if ( node->cache_index >= manager->num_caches )+    {+      FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));+      return;+    }+#endif++    cache = manager->caches[node->cache_index];++#ifdef FT_DEBUG_ERROR+    if ( cache == NULL )+    {+      FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));+      return;+    }+#endif++    manager->cur_weight -= cache->clazz.node_weight( node, cache );++    /* remove node from mru list */+    ftc_node_mru_unlink( node, manager );++    /* remove node from cache's hash table */+    ftc_node_hash_unlink( node, cache );++    /* now finalize it */+    cache->clazz.node_free( node, cache );++#if 0+    /* check, just in case of general corruption :-) */+    if ( manager->num_nodes == 0 )+      FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n",+                  manager->num_nodes ));+#endif+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    ABSTRACT CACHE CLASS                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  FTC_Cache_Init( FTC_Cache  cache )+  {+    return ftc_cache_init( cache );+  }+++  FT_LOCAL_DEF( FT_Error )+  ftc_cache_init( FTC_Cache  cache )+  {+    FT_Memory  memory = cache->memory;+    FT_Error   error;+++    cache->p     = 0;+    cache->mask  = FTC_HASH_INITIAL_SIZE - 1;+    cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;++    (void)FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );+    return error;+  }+++  static void+  FTC_Cache_Clear( FTC_Cache  cache )+  {+    if ( cache && cache->buckets )+    {+      FTC_Manager  manager = cache->manager;+      FT_UFast     i;+      FT_UFast     count;+++      count = cache->p + cache->mask + 1;++      for ( i = 0; i < count; i++ )+      {+        FTC_Node  *pnode = cache->buckets + i, next, node = *pnode;+++        while ( node )+        {+          next        = node->link;+          node->link  = NULL;++          /* remove node from mru list */+          ftc_node_mru_unlink( node, manager );++          /* now finalize it */+          manager->cur_weight -= cache->clazz.node_weight( node, cache );++          cache->clazz.node_free( node, cache );+          node = next;+        }+        cache->buckets[i] = NULL;+      }+      ftc_cache_resize( cache );+    }+  }+++  FT_LOCAL_DEF( void )+  ftc_cache_done( FTC_Cache  cache )+  {+    if ( cache->memory )+    {+      FT_Memory  memory = cache->memory;+++      FTC_Cache_Clear( cache );++      FT_FREE( cache->buckets );+      cache->mask  = 0;+      cache->p     = 0;+      cache->slack = 0;++      cache->memory = NULL;+    }+  }+++  FT_LOCAL_DEF( void )+  FTC_Cache_Done( FTC_Cache  cache )+  {+    ftc_cache_done( cache );+  }+++  static void+  ftc_cache_add( FTC_Cache  cache,+                 FT_PtrDist hash,+                 FTC_Node   node )+  {+    node->hash = hash;+    node->cache_index = (FT_UInt16) cache->index;+    node->ref_count   = 0;++    ftc_node_hash_link( node, cache );+    ftc_node_mru_link( node, cache->manager );++    {+      FTC_Manager  manager = cache->manager;+++      manager->cur_weight += cache->clazz.node_weight( node, cache );++      if ( manager->cur_weight >= manager->max_weight )+      {+        node->ref_count++;+        FTC_Manager_Compress( manager );+        node->ref_count--;+      }+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  FTC_Cache_NewNode( FTC_Cache   cache,+                     FT_PtrDist  hash,+                     FT_Pointer  query,+                     FTC_Node   *anode )+  {+    FT_Error  error;+    FTC_Node  node;+++    /*+     * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory+     * errors (OOM) correctly, i.e., by flushing the cache progressively+     * in order to make more room.+     */++    FTC_CACHE_TRYLOOP( cache )+    {+      error = cache->clazz.node_new( &node, query, cache );+    }+    FTC_CACHE_TRYLOOP_END();++    if ( error )+      node = NULL;+    else+    {+     /* don't assume that the cache has the same number of buckets, since+      * our allocation request might have triggered global cache flushing+      */+      ftc_cache_add( cache, hash, node );+    }++    *anode = node;+    return error;+  }+++#ifndef FTC_INLINE++  FT_LOCAL_DEF( FT_Error )+  FTC_Cache_Lookup( FTC_Cache   cache,+                    FT_PtrDist  hash,+                    FT_Pointer  query,+                    FTC_Node   *anode )+  {+    FT_UFast   idx;+    FTC_Node*  bucket;+    FTC_Node*  pnode;+    FTC_Node   node;+    FT_Error   error = FTC_Err_Ok;++    FTC_Node_CompareFunc  compare = cache->clazz.node_compare;+++    if ( cache == NULL || anode == NULL )+      return FTC_Err_Invalid_Argument;++    idx = hash & cache->mask;+    if ( idx < cache->p )+      idx = hash & ( cache->mask * 2 + 1 );++    bucket = cache->buckets + idx;+    pnode  = bucket;+    for (;;)+    {+      node = *pnode;+      if ( node == NULL )+        goto NewNode;++      if ( node->hash == hash && compare( node, query, cache ) )+        break;++      pnode = &node->link;+    }++    if ( node != *bucket )+    {+      *pnode     = node->link;+      node->link = *bucket;+      *bucket    = node;+    }++    /* move to head of MRU list */+    {+      FTC_Manager  manager = cache->manager;+++      if ( node != manager->nodes_list )+        ftc_node_mru_up( node, manager );+    }+    *anode = node;+    return error;++  NewNode:+    return FTC_Cache_NewNode( cache, hash, query, anode );+  }++#endif /* !FTC_INLINE */+++  FT_LOCAL_DEF( void )+  FTC_Cache_RemoveFaceID( FTC_Cache   cache,+                          FTC_FaceID  face_id )+  {+    FT_UFast     i, count;+    FTC_Manager  manager = cache->manager;+    FTC_Node     frees   = NULL;+++    count = cache->p + cache->mask;+    for ( i = 0; i < count; i++ )+    {+      FTC_Node*  bucket = cache->buckets + i;+      FTC_Node*  pnode  = bucket;+++      for ( ;; )+      {+        FTC_Node  node = *pnode;+++        if ( node == NULL )+          break;++        if ( cache->clazz.node_remove_faceid( node, face_id, cache ) )+        {+          *pnode     = node->link;+          node->link = frees;+          frees      = node;+        }+        else+          pnode = &node->link;+      }+    }++    /* remove all nodes in the free list */+    while ( frees )+    {+      FTC_Node  node;+++      node  = frees;+      frees = node->link;++      manager->cur_weight -= cache->clazz.node_weight( node, cache );+      ftc_node_mru_unlink( node, manager );++      cache->clazz.node_free( node, cache );++      cache->slack++;+    }++    ftc_cache_resize( cache );+  }+++/* END */
+ src/cache/ftccache.h view
@@ -0,0 +1,319 @@+/***************************************************************************/+/*                                                                         */+/*  ftccache.h                                                             */+/*                                                                         */+/*    FreeType internal cache interface (specification).                   */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTCCACHE_H__+#define __FTCCACHE_H__+++#include "ftcmru.h"++FT_BEGIN_HEADER++#define _FTC_FACE_ID_HASH( i )                              \+          ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 )))++  /* handle to cache object */+  typedef struct FTC_CacheRec_*  FTC_Cache;++  /* handle to cache class */+  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                   CACHE NODE DEFINITIONS                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* Each cache controls one or more cache nodes.  Each node is part of    */+  /* the global_lru list of the manager.  Its `data' field however is used */+  /* as a reference count for now.                                         */+  /*                                                                       */+  /* A node can be anything, depending on the type of information held by  */+  /* the cache.  It can be an individual glyph image, a set of bitmaps     */+  /* glyphs for a given size, some metrics, etc.                           */+  /*                                                                       */+  /*************************************************************************/++  /* structure size should be 20 bytes on 32-bits machines */+  typedef struct  FTC_NodeRec_+  {+    FTC_MruNodeRec  mru;          /* circular mru list pointer           */+    FTC_Node        link;         /* used for hashing                    */+    FT_PtrDist      hash;         /* used for hashing too                */+    FT_UShort       cache_index;  /* index of cache the node belongs to  */+    FT_Short        ref_count;    /* reference count for this node       */++  } FTC_NodeRec;+++#define FTC_NODE( x )    ( (FTC_Node)(x) )+#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )++#define FTC_NODE__NEXT( x )  FTC_NODE( (x)->mru.next )+#define FTC_NODE__PREV( x )  FTC_NODE( (x)->mru.prev )+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+  FT_BASE( void )+  ftc_node_destroy( FTC_Node     node,+                    FTC_Manager  manager );+#endif+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       CACHE DEFINITIONS                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* initialize a new cache node */+  typedef FT_Error+  (*FTC_Node_NewFunc)( FTC_Node    *pnode,+                       FT_Pointer   query,+                       FTC_Cache    cache );++  typedef FT_Offset+  (*FTC_Node_WeightFunc)( FTC_Node   node,+                          FTC_Cache  cache );++  /* compare a node to a given key pair */+  typedef FT_Bool+  (*FTC_Node_CompareFunc)( FTC_Node    node,+                           FT_Pointer  key,+                           FTC_Cache   cache );+++  typedef void+  (*FTC_Node_FreeFunc)( FTC_Node   node,+                        FTC_Cache  cache );++  typedef FT_Error+  (*FTC_Cache_InitFunc)( FTC_Cache  cache );++  typedef void+  (*FTC_Cache_DoneFunc)( FTC_Cache  cache );+++  typedef struct  FTC_CacheClassRec_+  {+    FTC_Node_NewFunc      node_new;+    FTC_Node_WeightFunc   node_weight;+    FTC_Node_CompareFunc  node_compare;+    FTC_Node_CompareFunc  node_remove_faceid;+    FTC_Node_FreeFunc     node_free;++    FT_Offset             cache_size;+    FTC_Cache_InitFunc    cache_init;+    FTC_Cache_DoneFunc    cache_done;++  } FTC_CacheClassRec;+++  /* each cache really implements a dynamic hash table to manage its nodes */+  typedef struct  FTC_CacheRec_+  {+    FT_UFast           p;+    FT_UFast           mask;+    FT_Long            slack;+    FTC_Node*          buckets;++    FTC_CacheClassRec  clazz;       /* local copy, for speed  */++    FTC_Manager        manager;+    FT_Memory          memory;+    FT_UInt            index;       /* in manager's table     */++    FTC_CacheClass     org_class;   /* original class pointer */++  } FTC_CacheRec;+++#define FTC_CACHE( x )    ( (FTC_Cache)(x) )+#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )+++  /* default cache initialize */+  FT_LOCAL( FT_Error )+  FTC_Cache_Init( FTC_Cache  cache );++  /* default cache finalizer */+  FT_LOCAL( void )+  FTC_Cache_Done( FTC_Cache  cache );++  /* Call this function to lookup the cache.  If no corresponding+   * node is found, a new one is automatically created.  This function+   * is capable of flushing the cache adequately to make room for the+   * new cache object.+   */++#ifndef FTC_INLINE+  FT_LOCAL( FT_Error )+  FTC_Cache_Lookup( FTC_Cache   cache,+                    FT_PtrDist  hash,+                    FT_Pointer  query,+                    FTC_Node   *anode );+#endif++  FT_LOCAL( FT_Error )+  FTC_Cache_NewNode( FTC_Cache   cache,+                     FT_PtrDist  hash,+                     FT_Pointer  query,+                     FTC_Node   *anode );++  /* Remove all nodes that relate to a given face_id.  This is useful+   * when un-installing fonts.  Note that if a cache node relates to+   * the face_id, but is locked (i.e., has `ref_count > 0'), the node+   * will _not_ be destroyed, but its internal face_id reference will+   * be modified.+   *+   * The final result will be that the node will never come back+   * in further lookup requests, and will be flushed on demand from+   * the cache normally when its reference count reaches 0.+   */+  FT_LOCAL( void )+  FTC_Cache_RemoveFaceID( FTC_Cache   cache,+                          FTC_FaceID  face_id );+++#ifdef FTC_INLINE++#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \+  FT_BEGIN_STMNT                                                         \+    FTC_Node             *_bucket, *_pnode, _node;                       \+    FTC_Cache             _cache   = FTC_CACHE(cache);                   \+    FT_PtrDist            _hash    = (FT_PtrDist)(hash);                 \+    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);    \+    FT_UFast              _idx;                                          \+                                                                         \+                                                                         \+    error = FTC_Err_Ok;                                                  \+    node  = NULL;                                                        \+    _idx  = _hash & _cache->mask;                                        \+    if ( _idx < _cache->p )                                              \+      _idx = _hash & ( _cache->mask*2 + 1 );                             \+                                                                         \+    _bucket = _pnode = _cache->buckets + _idx;                           \+    for (;;)                                                             \+    {                                                                    \+      _node = *_pnode;                                                   \+      if ( _node == NULL )                                               \+        goto _NewNode;                                                   \+                                                                         \+      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )    \+        break;                                                           \+                                                                         \+      _pnode = &_node->link;                                             \+    }                                                                    \+                                                                         \+    if ( _node != *_bucket )                                             \+    {                                                                    \+      *_pnode     = _node->link;                                         \+      _node->link = *_bucket;                                            \+      *_bucket    = _node;                                               \+    }                                                                    \+                                                                         \+    {                                                                    \+      FTC_Manager  _manager = _cache->manager;                           \+      void*        _nl      = &_manager->nodes_list;                     \+                                                                         \+                                                                         \+      if ( _node != _manager->nodes_list )                               \+        FTC_MruNode_Up( (FTC_MruNode*)_nl,                               \+                        (FTC_MruNode)_node );                            \+    }                                                                    \+    goto _Ok;                                                            \+                                                                         \+  _NewNode:                                                              \+    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );           \+                                                                         \+  _Ok:                                                                   \+    node = _node;                                                        \+  FT_END_STMNT++#else /* !FTC_INLINE */++#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \+  FT_BEGIN_STMNT                                                         \+    error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query,           \+                              (FTC_Node*)&(node) );                      \+  FT_END_STMNT++#endif /* !FTC_INLINE */+++  /*+   * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry+   * loop to flush the cache repeatedly in case of memory overflows.+   *+   * It is used when creating a new cache node, or within a lookup+   * that needs to allocate data (e.g., the sbit cache lookup).+   *+   * Example:+   *+   *   {+   *     FTC_CACHE_TRYLOOP( cache )+   *       error = load_data( ... );+   *     FTC_CACHE_TRYLOOP_END()+   *   }+   *+   */+#define FTC_CACHE_TRYLOOP( cache )                           \+  {                                                          \+    FTC_Manager  _try_manager = FTC_CACHE( cache )->manager; \+    FT_UInt      _try_count   = 4;                           \+                                                             \+                                                             \+    for (;;)                                                 \+    {                                                        \+      FT_UInt  _try_done;+++#define FTC_CACHE_TRYLOOP_END()                                   \+      if ( !error || error != FTC_Err_Out_Of_Memory )             \+        break;                                                    \+                                                                  \+      _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \+      if ( _try_done == 0 )                                       \+        break;                                                    \+                                                                  \+      if ( _try_done == _try_count )                              \+      {                                                           \+        _try_count *= 2;                                          \+        if ( _try_count < _try_done              ||               \+            _try_count > _try_manager->num_nodes )                \+          _try_count = _try_manager->num_nodes;                   \+      }                                                           \+    }                                                             \+  }++ /* */++FT_END_HEADER+++#endif /* __FTCCACHE_H__ */+++/* END */
+ src/cache/ftccback.h view
@@ -0,0 +1,90 @@+/***************************************************************************/+/*                                                                         */+/*  ftccback.h                                                             */+/*                                                                         */+/*    Callback functions of the caching sub-system (specification only).   */+/*                                                                         */+/*  Copyright 2004, 2005, 2006 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#ifndef __FTCCBACK_H__+#define __FTCCBACK_H__++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcmru.h"+#include "ftcimage.h"+#include "ftcmanag.h"+#include "ftcglyph.h"+#include "ftcsbits.h"+++  FT_LOCAL( void )+  ftc_inode_free( FTC_Node   inode,+                  FTC_Cache  cache );++  FT_LOCAL( FT_Error )+  ftc_inode_new( FTC_Node   *pinode,+                 FT_Pointer  gquery,+                 FTC_Cache   cache );++  FT_LOCAL( FT_Offset )+  ftc_inode_weight( FTC_Node   inode,+                    FTC_Cache  cache );+++  FT_LOCAL( void )+  ftc_snode_free( FTC_Node   snode,+                  FTC_Cache  cache );++  FT_LOCAL( FT_Error )+  ftc_snode_new( FTC_Node   *psnode,+                 FT_Pointer  gquery,+                 FTC_Cache   cache );++  FT_LOCAL( FT_Offset )+  ftc_snode_weight( FTC_Node   snode,+                    FTC_Cache  cache );++  FT_LOCAL( FT_Bool )+  ftc_snode_compare( FTC_Node    snode,+                     FT_Pointer  gquery,+                     FTC_Cache   cache );+++  FT_LOCAL( FT_Bool )+  ftc_gnode_compare( FTC_Node    gnode,+                     FT_Pointer  gquery,+                     FTC_Cache   cache );+++  FT_LOCAL( FT_Error )+  ftc_gcache_init( FTC_Cache  cache );++  FT_LOCAL( void )+  ftc_gcache_done( FTC_Cache  cache );+++  FT_LOCAL( FT_Error )+  ftc_cache_init( FTC_Cache  cache );++  FT_LOCAL( void )+  ftc_cache_done( FTC_Cache  cache );++#ifndef FT_CONFIG_OPTION_OLD_INTERNALS+  FT_LOCAL( void )+  ftc_node_destroy( FTC_Node     node,+                    FTC_Manager  manager );+#endif++#endif /* __FTCCBACK_H__ */++/* END */
+ src/cache/ftccmap.c view
@@ -0,0 +1,430 @@+/***************************************************************************/+/*                                                                         */+/*  ftccmap.c                                                              */+/*                                                                         */+/*    FreeType CharMap cache (body)                                        */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_CACHE_H+#include "ftcmanag.h"+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_DEBUG_H++#include "ftccback.h"+#include "ftcerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cache+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  typedef enum  FTC_OldCMapType_+  {+    FTC_OLD_CMAP_BY_INDEX    = 0,+    FTC_OLD_CMAP_BY_ENCODING = 1,+    FTC_OLD_CMAP_BY_ID       = 2++  } FTC_OldCMapType;+++  typedef struct  FTC_OldCMapIdRec_+  {+    FT_UInt  platform;+    FT_UInt  encoding;++  } FTC_OldCMapIdRec, *FTC_OldCMapId;+++  typedef struct  FTC_OldCMapDescRec_+  {+    FTC_FaceID       face_id;+    FTC_OldCMapType  type;++    union+    {+      FT_UInt           index;+      FT_Encoding       encoding;+      FTC_OldCMapIdRec  id;++    } u;++  } FTC_OldCMapDescRec, *FTC_OldCMapDesc;++#endif /* FT_CONFIG_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* Each FTC_CMapNode contains a simple array to map a range of character */+  /* codes to equivalent glyph indices.                                    */+  /*                                                                       */+  /* For now, the implementation is very basic: Each node maps a range of  */+  /* 128 consecutive character codes to their corresponding glyph indices. */+  /*                                                                       */+  /* We could do more complex things, but I don't think it is really very  */+  /* useful.                                                               */+  /*                                                                       */+  /*************************************************************************/+++  /* number of glyph indices / character code per node */+#define FTC_CMAP_INDICES_MAX  128++  /* compute a query/node hash */+#define FTC_CMAP_HASH( faceid, index, charcode )         \+          ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \+            ( (charcode) / FTC_CMAP_INDICES_MAX )      )++  /* the charmap query */+  typedef struct  FTC_CMapQueryRec_+  {+    FTC_FaceID  face_id;+    FT_UInt     cmap_index;+    FT_UInt32   char_code;++  } FTC_CMapQueryRec, *FTC_CMapQuery;++#define FTC_CMAP_QUERY( x )  ((FTC_CMapQuery)(x))+#define FTC_CMAP_QUERY_HASH( x )                                         \+          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )++  /* the cmap cache node */+  typedef struct  FTC_CMapNodeRec_+  {+    FTC_NodeRec  node;+    FTC_FaceID   face_id;+    FT_UInt      cmap_index;+    FT_UInt32    first;                         /* first character in node */+    FT_UInt16    indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices  */++  } FTC_CMapNodeRec, *FTC_CMapNode;++#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )+#define FTC_CMAP_NODE_HASH( x )                                      \+          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )++  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */+  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */+#define FTC_CMAP_UNKNOWN  ( (FT_UInt16)-1 )+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                        CHARMAP NODES                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_CALLBACK_DEF( void )+  ftc_cmap_node_free( FTC_Node   ftcnode,+                      FTC_Cache  cache )+  {+    FTC_CMapNode  node   = (FTC_CMapNode)ftcnode;+    FT_Memory     memory = cache->memory;+++    FT_FREE( node );+  }+++  /* initialize a new cmap node */+  FT_CALLBACK_DEF( FT_Error )+  ftc_cmap_node_new( FTC_Node   *ftcanode,+                     FT_Pointer  ftcquery,+                     FTC_Cache   cache )+  {+    FTC_CMapNode  *anode  = (FTC_CMapNode*)ftcanode;+    FTC_CMapQuery  query  = (FTC_CMapQuery)ftcquery;+    FT_Error       error;+    FT_Memory      memory = cache->memory;+    FTC_CMapNode   node   = NULL;+    FT_UInt        nn;+++    if ( !FT_NEW( node ) )+    {+      node->face_id    = query->face_id;+      node->cmap_index = query->cmap_index;+      node->first      = (query->char_code / FTC_CMAP_INDICES_MAX) *+                         FTC_CMAP_INDICES_MAX;++      for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )+        node->indices[nn] = FTC_CMAP_UNKNOWN;+    }++    *anode = node;+    return error;+  }+++  /* compute the weight of a given cmap node */+  FT_CALLBACK_DEF( FT_Offset )+  ftc_cmap_node_weight( FTC_Node   cnode,+                        FTC_Cache  cache )+  {+    FT_UNUSED( cnode );+    FT_UNUSED( cache );++    return sizeof ( *cnode );+  }+++  /* compare a cmap node to a given query */+  FT_CALLBACK_DEF( FT_Bool )+  ftc_cmap_node_compare( FTC_Node    ftcnode,+                         FT_Pointer  ftcquery,+                         FTC_Cache   cache )+  {+    FTC_CMapNode   node  = (FTC_CMapNode)ftcnode;+    FTC_CMapQuery  query = (FTC_CMapQuery)ftcquery;+    FT_UNUSED( cache );+++    if ( node->face_id    == query->face_id    &&+         node->cmap_index == query->cmap_index )+    {+      FT_UInt32  offset = (FT_UInt32)( query->char_code - node->first );+++      return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );+    }++    return 0;+  }+++  FT_CALLBACK_DEF( FT_Bool )+  ftc_cmap_node_remove_faceid( FTC_Node    ftcnode,+                               FT_Pointer  ftcface_id,+                               FTC_Cache   cache )+  {+    FTC_CMapNode  node    = (FTC_CMapNode)ftcnode;+    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;+    FT_UNUSED( cache );++    return FT_BOOL( node->face_id == face_id );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    GLYPH IMAGE CACHE                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_CALLBACK_TABLE_DEF+  const FTC_CacheClassRec  ftc_cmap_cache_class =+  {+    ftc_cmap_node_new,+    ftc_cmap_node_weight,+    ftc_cmap_node_compare,+    ftc_cmap_node_remove_faceid,+    ftc_cmap_node_free,++    sizeof ( FTC_CacheRec ),+    ftc_cache_init,+    ftc_cache_done,+  };+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_CMapCache_New( FTC_Manager     manager,+                     FTC_CMapCache  *acache )+  {+    return FTC_Manager_RegisterCache( manager,+                                      &ftc_cmap_cache_class,+                                      FTC_CACHE_P( acache ) );+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  /*+   *  Unfortunately, it is not possible to support binary backwards+   *  compatibility in the cmap cache.  The FTC_CMapCache_Lookup signature+   *  changes were too deep, and there is no clever hackish way to detect+   *  what kind of structure we are being passed.+   *+   *  On the other hand it seems that no production code is using this+   *  function on Unix distributions.+   */++#endif+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_UInt )+  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,+                        FTC_FaceID     face_id,+                        FT_Int         cmap_index,+                        FT_UInt32      char_code )+  {+    FTC_Cache         cache = FTC_CACHE( cmap_cache );+    FTC_CMapQueryRec  query;+    FTC_Node          node;+    FT_Error          error;+    FT_UInt           gindex = 0;+    FT_PtrDist        hash;+    FT_Int            no_cmap_change = 0;+++    if ( cmap_index < 0 )+    {+      /* Treat a negative cmap index as a special value, meaning that you */+      /* don't want to change the FT_Face's character map through this    */+      /* call.  This can be useful if the face requester callback already */+      /* sets the face's charmap to the appropriate value.                */++      no_cmap_change = 1;+      cmap_index     = 0;+    }++    if ( !cache )+    {+      FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));+      return 0;+    }++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++    /*+     * If cmap_index is greater than the maximum number of cachable+     * charmaps, we assume the request is from a legacy rogue client +     * using old internal header. See include/config/ftoption.h.+     */+    if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )+    {+      FTC_OldCMapDesc  desc = (FTC_OldCMapDesc) face_id;+++      char_code     = (FT_UInt32)cmap_index;+      query.face_id = desc->face_id;+++      switch ( desc->type )+      {+      case FTC_OLD_CMAP_BY_INDEX:+        query.cmap_index = desc->u.index;+        query.char_code  = (FT_UInt32)cmap_index;+        break;++      case FTC_OLD_CMAP_BY_ENCODING:+        {+          FT_Face  face;+++          error = FTC_Manager_LookupFace( cache->manager, desc->face_id,+                                          &face );+          if ( error )+            return 0;++          FT_Select_Charmap( face, desc->u.encoding );++          return FT_Get_Char_Index( face, char_code );+        }++      default:+        return 0;+      }+    }+    else++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++    {+      query.face_id    = face_id;+      query.cmap_index = (FT_UInt)cmap_index;+      query.char_code  = char_code;+    }++    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );++#if 1+    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,+                          node, error );+#else+    error = FTC_Cache_Lookup( cache, hash, &query, &node );+#endif+    if ( error )+      goto Exit;++    FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <+                FTC_CMAP_INDICES_MAX );++    /* something rotten can happen with rogue clients */+    if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=+                    FTC_CMAP_INDICES_MAX ) )+      return 0; /* XXX: should return appropriate error */++    gindex = FTC_CMAP_NODE( node )->indices[char_code -+                                            FTC_CMAP_NODE( node )->first];+    if ( gindex == FTC_CMAP_UNKNOWN )+    {+      FT_Face  face;+++      gindex = 0;++      error = FTC_Manager_LookupFace( cache->manager,+                                      FTC_CMAP_NODE( node )->face_id,+                                      &face );+      if ( error )+        goto Exit;++#ifdef FT_MAX_CHARMAP_CACHEABLE+      /* something rotten can happen with rogue clients */+      if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )+        return 0; /* XXX: should return appropriate error */+#endif++      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )+      {+        FT_CharMap  old, cmap  = NULL;+++        old  = face->charmap;+        cmap = face->charmaps[cmap_index];++        if ( old != cmap && !no_cmap_change )+          FT_Set_Charmap( face, cmap );++        gindex = FT_Get_Char_Index( face, char_code );++        if ( old != cmap && !no_cmap_change )+          FT_Set_Charmap( face, old );+      }++      FTC_CMAP_NODE( node )->indices[char_code -+                                     FTC_CMAP_NODE( node )->first]+        = (FT_UShort)gindex;+    }++  Exit:+    return gindex;+  }+++/* END */
+ src/cache/ftcerror.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  ftcerror.h                                                             */+/*                                                                         */+/*    Caching sub-system error codes (specification only).                 */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the caching sub-system error enumeration  */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __FTCERROR_H__+#define __FTCERROR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  FTC_Err_+#define FT_ERR_BASE    FT_Mod_Err_Cache++#include FT_ERRORS_H++#endif /* __FTCERROR_H__ */++/* END */
+ src/cache/ftcglyph.c view
@@ -0,0 +1,209 @@+/***************************************************************************/+/*                                                                         */+/*  ftcglyph.c                                                             */+/*                                                                         */+/*    FreeType Glyph Image (FT_Glyph) cache (body).                        */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2004, 2006, 2009 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcglyph.h"+#include FT_ERRORS_H++#include "ftccback.h"+#include "ftcerror.h"+++  /* create a new chunk node, setting its cache index and ref count */+  FT_LOCAL_DEF( void )+  FTC_GNode_Init( FTC_GNode   gnode,+                  FT_UInt     gindex,+                  FTC_Family  family )+  {+    gnode->family = family;+    gnode->gindex = gindex;+    family->num_nodes++;+  }+++  FT_LOCAL_DEF( void )+  FTC_GNode_UnselectFamily( FTC_GNode  gnode,+                            FTC_Cache  cache )+  {+    FTC_Family  family = gnode->family;+++    gnode->family = NULL;+    if ( family && --family->num_nodes == 0 )+      FTC_FAMILY_FREE( family, cache );+  }+++  FT_LOCAL_DEF( void )+  FTC_GNode_Done( FTC_GNode  gnode,+                  FTC_Cache  cache )+  {+    /* finalize the node */+    gnode->gindex = 0;++    FTC_GNode_UnselectFamily( gnode, cache );+  }+++  FT_LOCAL_DEF( FT_Bool )+  ftc_gnode_compare( FTC_Node    ftcgnode,+                     FT_Pointer  ftcgquery,+                     FTC_Cache   cache )+  {+    FTC_GNode   gnode  = (FTC_GNode)ftcgnode;+    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;+    FT_UNUSED( cache );+++    return FT_BOOL( gnode->family == gquery->family &&+                    gnode->gindex == gquery->gindex );+  }+++  FT_LOCAL_DEF( FT_Bool )+  FTC_GNode_Compare( FTC_GNode   gnode,+                     FTC_GQuery  gquery )+  {+    return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      CHUNK SETS                               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  FTC_Family_Init( FTC_Family  family,+                   FTC_Cache   cache )+  {+    FTC_GCacheClass  clazz = FTC_CACHE__GCACHE_CLASS( cache );+++    family->clazz     = clazz->family_class;+    family->num_nodes = 0;+    family->cache     = cache;+  }+++  FT_LOCAL_DEF( FT_Error )+  ftc_gcache_init( FTC_Cache  ftccache )+  {+    FTC_GCache  cache = (FTC_GCache)ftccache;+    FT_Error    error;+++    error = FTC_Cache_Init( FTC_CACHE( cache ) );+    if ( !error )+    {+      FTC_GCacheClass   clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class;++      FTC_MruList_Init( &cache->families,+                        clazz->family_class,+                        0,  /* no maximum here! */+                        cache,+                        FTC_CACHE( cache )->memory );+    }++    return error;+  }+++#if 0++  FT_LOCAL_DEF( FT_Error )+  FTC_GCache_Init( FTC_GCache  cache )+  {+    return ftc_gcache_init( FTC_CACHE( cache ) );+  }++#endif /* 0 */+++  FT_LOCAL_DEF( void )+  ftc_gcache_done( FTC_Cache  ftccache )+  {+    FTC_GCache  cache = (FTC_GCache)ftccache;+++    FTC_Cache_Done( (FTC_Cache)cache );+    FTC_MruList_Done( &cache->families );+  }+++#if 0++  FT_LOCAL_DEF( void )+  FTC_GCache_Done( FTC_GCache  cache )+  {+    ftc_gcache_done( FTC_CACHE( cache ) );+  }++#endif /* 0 */+++  FT_LOCAL_DEF( FT_Error )+  FTC_GCache_New( FTC_Manager       manager,+                  FTC_GCacheClass   clazz,+                  FTC_GCache       *acache )+  {+    return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz,+                                      (FTC_Cache*)acache );+  }+++#ifndef FTC_INLINE++  FT_LOCAL_DEF( FT_Error )+  FTC_GCache_Lookup( FTC_GCache   cache,+                     FT_PtrDist   hash,+                     FT_UInt      gindex,+                     FTC_GQuery   query,+                     FTC_Node    *anode )+  {+    FT_Error  error;+++    query->gindex = gindex;++    FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error );+    if ( !error )+    {+      FTC_Family  family = query->family;+++      /* prevent the family from being destroyed too early when an        */+      /* out-of-memory condition occurs during glyph node initialization. */+      family->num_nodes++;++      error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode );++      if ( --family->num_nodes == 0 )+        FTC_FAMILY_FREE( family, cache );+    }+    return error;+  }++#endif /* !FTC_INLINE */+++/* END */
+ src/cache/ftcglyph.h view
@@ -0,0 +1,323 @@+/***************************************************************************/+/*                                                                         */+/*  ftcglyph.h                                                             */+/*                                                                         */+/*    FreeType abstract glyph cache (specification).                       */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2004, 2006, 2007 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*+   *+   *  FTC_GCache is an _abstract_ cache object optimized to store glyph+   *  data.  It works as follows:+   *+   *   - It manages FTC_GNode objects. Each one of them can hold one or more+   *     glyph `items'.  Item types are not specified in the FTC_GCache but+   *     in classes that extend it.+   *+   *   - Glyph attributes, like face ID, character size, render mode, etc.,+   *     can be grouped into abstract `glyph families'.  This avoids storing+   *     the attributes within the FTC_GCache, since it is likely that many+   *     FTC_GNodes will belong to the same family in typical uses.+   *+   *   - Each FTC_GNode is thus an FTC_Node with two additional fields:+   *+   *       * gindex: A glyph index, or the first index in a glyph range.+   *       * family: A pointer to a glyph `family'.+   *+   *   - Family types are not fully specific in the FTC_Family type, but+   *     by classes that extend it.+   *+   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.+   *  They share an FTC_Family sub-class called FTC_BasicFamily which is+   *  used to store the following data: face ID, pixel/point sizes, load+   *  flags.  For more details see the file `src/cache/ftcbasic.c'.+   *+   *  Client applications can extend FTC_GNode with their own FTC_GNode+   *  and FTC_Family sub-classes to implement more complex caches (e.g.,+   *  handling automatic synthesis, like obliquing & emboldening, colored+   *  glyphs, etc.).+   *+   *  See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and+   *  `ftcsbits.h', which both extend FTC_GCache with additional+   *  optimizations.+   *+   *  A typical FTC_GCache implementation must provide at least the+   *  following:+   *+   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods:+   *        my_node_new            (must call FTC_GNode_Init)+   *        my_node_free           (must call FTC_GNode_Done)+   *        my_node_compare        (must call FTC_GNode_Compare)+   *        my_node_remove_faceid  (must call ftc_gnode_unselect in case+   *                                of match)+   *+   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods:+   *        my_family_compare+   *        my_family_init+   *        my_family_reset (optional)+   *        my_family_done+   *+   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query+   *    data.+   *+   *  - Constant structures for a FTC_GNodeClass.+   *+   *  - MyCacheNew() can be implemented easily as a call to the convenience+   *    function FTC_GCache_New.+   *+   *  - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will+   *    automatically:+   *+   *    - Search for the corresponding family in the cache, or create+   *      a new one if necessary.  Put it in FTC_GQUERY(myquery).family+   *+   *    - Call FTC_Cache_Lookup.+   *+   *    If it returns NULL, you should create a new node, then call+   *    ftc_cache_add as usual.+   */+++  /*************************************************************************/+  /*                                                                       */+  /* Important: The functions defined in this file are only used to        */+  /*            implement an abstract glyph cache class.  You need to      */+  /*            provide additional logic to implement a complete cache.    */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*********                                                       *********/+  /*********             WARNING, THIS IS BETA CODE.               *********/+  /*********                                                       *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#ifndef __FTCGLYPH_H__+#define __FTCGLYPH_H__+++#include <ft2build.h>+#include "ftcmanag.h"+++FT_BEGIN_HEADER+++ /*+  *  We can group glyphs into `families'.  Each family correspond to a+  *  given face ID, character size, transform, etc.+  *+  *  Families are implemented as MRU list nodes.  They are+  *  reference-counted.+  */++  typedef struct  FTC_FamilyRec_+  {+    FTC_MruNodeRec    mrunode;+    FT_UInt           num_nodes; /* current number of nodes in this family */+    FTC_Cache         cache;+    FTC_MruListClass  clazz;++  } FTC_FamilyRec, *FTC_Family;++#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )+#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )+++  typedef struct  FTC_GNodeRec_+  {+    FTC_NodeRec      node;+    FTC_Family       family;+    FT_UInt          gindex;++  } FTC_GNodeRec, *FTC_GNode;++#define FTC_GNODE( x )    ( (FTC_GNode)(x) )+#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )+++  typedef struct  FTC_GQueryRec_+  {+    FT_UInt      gindex;+    FTC_Family   family;++  } FTC_GQueryRec, *FTC_GQuery;++#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )+++  /*************************************************************************/+  /*                                                                       */+  /* These functions are exported so that they can be called from          */+  /* user-provided cache classes; otherwise, they are really part of the   */+  /* cache sub-system internals.                                           */+  /*                                                                       */++  /* must be called by derived FTC_Node_InitFunc routines */+  FT_LOCAL( void )+  FTC_GNode_Init( FTC_GNode   node,+                  FT_UInt     gindex,  /* glyph index for node */+                  FTC_Family  family );++  /* returns TRUE iff the query's glyph index correspond to the node;  */+  /* this assumes that the `family' and `hash' fields of the query are */+  /* already correctly set                                             */+  FT_LOCAL( FT_Bool )+  FTC_GNode_Compare( FTC_GNode   gnode,+                     FTC_GQuery  gquery );++  /* call this function to clear a node's family -- this is necessary */+  /* to implement the `node_remove_faceid' cache method correctly     */+  FT_LOCAL( void )+  FTC_GNode_UnselectFamily( FTC_GNode  gnode,+                            FTC_Cache  cache );++  /* must be called by derived FTC_Node_DoneFunc routines */+  FT_LOCAL( void )+  FTC_GNode_Done( FTC_GNode  node,+                  FTC_Cache  cache );+++  FT_LOCAL( void )+  FTC_Family_Init( FTC_Family  family,+                   FTC_Cache   cache );++  typedef struct FTC_GCacheRec_+  {+    FTC_CacheRec    cache;+    FTC_MruListRec  families;++  } FTC_GCacheRec, *FTC_GCache;++#define FTC_GCACHE( x )  ((FTC_GCache)(x))+++#if 0+  /* can be used as @FTC_Cache_InitFunc */+  FT_LOCAL( FT_Error )+  FTC_GCache_Init( FTC_GCache  cache );+#endif+++#if 0+  /* can be used as @FTC_Cache_DoneFunc */+  FT_LOCAL( void )+  FTC_GCache_Done( FTC_GCache  cache );+#endif+++  /* the glyph cache class adds fields for the family implementation */+  typedef struct  FTC_GCacheClassRec_+  {+    FTC_CacheClassRec  clazz;+    FTC_MruListClass   family_class;++  } FTC_GCacheClassRec;++  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;++#define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))++#define FTC_CACHE__GCACHE_CLASS( x ) \+          FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )+#define FTC_CACHE__FAMILY_CLASS( x ) \+          ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class )+++  /* convenience function; use it instead of FTC_Manager_Register_Cache */+  FT_LOCAL( FT_Error )+  FTC_GCache_New( FTC_Manager       manager,+                  FTC_GCacheClass   clazz,+                  FTC_GCache       *acache );++#ifndef FTC_INLINE+  FT_LOCAL( FT_Error )+  FTC_GCache_Lookup( FTC_GCache   cache,+                     FT_PtrDist   hash,+                     FT_UInt      gindex,+                     FTC_GQuery   query,+                     FTC_Node    *anode );+#endif+++  /* */+++#define FTC_FAMILY_FREE( family, cache )                      \+          FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \+                              (FTC_MruNode)(family) )+++#ifdef FTC_INLINE++#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \+                               gindex, query, node, error )                 \+  FT_BEGIN_STMNT                                                            \+    FTC_GCache               _gcache   = FTC_GCACHE( cache );               \+    FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \+    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \+    FTC_MruNode              _mrunode;                                      \+                                                                            \+                                                                            \+    _gquery->gindex = (gindex);                                             \+                                                                            \+    FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \+                            _mrunode, error );                              \+    _gquery->family = FTC_FAMILY( _mrunode );                               \+    if ( !error )                                                           \+    {                                                                       \+      FTC_Family  _gqfamily = _gquery->family;                              \+                                                                            \+                                                                            \+      _gqfamily->num_nodes++;                                               \+                                                                            \+      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \+                                                                            \+      if ( --_gqfamily->num_nodes == 0 )                                    \+        FTC_FAMILY_FREE( _gqfamily, _gcache );                              \+    }                                                                       \+  FT_END_STMNT+  /* */++#else /* !FTC_INLINE */++#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,          \+                               gindex, query, node, error )           \+   FT_BEGIN_STMNT                                                     \+                                                                      \+     error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex,    \+                                FTC_GQUERY( query ), node );          \+                                                                      \+   FT_END_STMNT++#endif /* !FTC_INLINE */+++FT_END_HEADER+++#endif /* __FTCGLYPH_H__ */+++/* END */
+ src/cache/ftcimage.c view
@@ -0,0 +1,163 @@+/***************************************************************************/+/*                                                                         */+/*  ftcimage.c                                                             */+/*                                                                         */+/*    FreeType Image cache (body).                                         */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2004, 2006, 2010 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcimage.h"+#include FT_INTERNAL_MEMORY_H++#include "ftccback.h"+#include "ftcerror.h"+++  /* finalize a given glyph image node */+  FT_LOCAL_DEF( void )+  ftc_inode_free( FTC_Node   ftcinode,+                  FTC_Cache  cache )+  {+    FTC_INode  inode = (FTC_INode)ftcinode;+    FT_Memory  memory = cache->memory;+++    if ( inode->glyph )+    {+      FT_Done_Glyph( inode->glyph );+      inode->glyph = NULL;+    }++    FTC_GNode_Done( FTC_GNODE( inode ), cache );+    FT_FREE( inode );+  }+++  FT_LOCAL_DEF( void )+  FTC_INode_Free( FTC_INode  inode,+                  FTC_Cache  cache )+  {+    ftc_inode_free( FTC_NODE( inode ), cache );+  }+++  /* initialize a new glyph image node */+  FT_LOCAL_DEF( FT_Error )+  FTC_INode_New( FTC_INode   *pinode,+                 FTC_GQuery   gquery,+                 FTC_Cache    cache )+  {+    FT_Memory  memory = cache->memory;+    FT_Error   error;+    FTC_INode  inode  = NULL;+++    if ( !FT_NEW( inode ) )+    {+      FTC_GNode         gnode  = FTC_GNODE( inode );+      FTC_Family        family = gquery->family;+      FT_UInt           gindex = gquery->gindex;+      FTC_IFamilyClass  clazz  = FTC_CACHE__IFAMILY_CLASS( cache );+++      /* initialize its inner fields */+      FTC_GNode_Init( gnode, gindex, family );++      /* we will now load the glyph image */+      error = clazz->family_load_glyph( family, gindex, cache,+                                        &inode->glyph );+      if ( error )+      {+        FTC_INode_Free( inode, cache );+        inode = NULL;+      }+    }++    *pinode = inode;+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  ftc_inode_new( FTC_Node   *ftcpinode,+                 FT_Pointer  ftcgquery,+                 FTC_Cache   cache )+  {+    FTC_INode  *pinode = (FTC_INode*)ftcpinode;+    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;+++    return FTC_INode_New( pinode, gquery, cache );+  }+++  FT_LOCAL_DEF( FT_Offset )+  ftc_inode_weight( FTC_Node   ftcinode,+                    FTC_Cache  ftccache )+  {+    FTC_INode  inode = (FTC_INode)ftcinode;+    FT_Offset  size  = 0;+    FT_Glyph   glyph = inode->glyph;++    FT_UNUSED( ftccache );+++    switch ( glyph->format )+    {+    case FT_GLYPH_FORMAT_BITMAP:+      {+        FT_BitmapGlyph  bitg;+++        bitg = (FT_BitmapGlyph)glyph;+        size = bitg->bitmap.rows * ft_labs( bitg->bitmap.pitch ) ++               sizeof ( *bitg );+      }+      break;++    case FT_GLYPH_FORMAT_OUTLINE:+      {+        FT_OutlineGlyph  outg;+++        outg = (FT_OutlineGlyph)glyph;+        size = outg->outline.n_points *+                 ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) ++               outg->outline.n_contours * sizeof ( FT_Short ) ++               sizeof ( *outg );+      }+      break;++    default:+      ;+    }++    size += sizeof ( *inode );+    return size;+  }+++#if 0++  FT_LOCAL_DEF( FT_Offset )+  FTC_INode_Weight( FTC_INode  inode )+  {+    return ftc_inode_weight( FTC_NODE( inode ), NULL );+  }++#endif /* 0 */+++/* END */
+ src/cache/ftcimage.h view
@@ -0,0 +1,107 @@+/***************************************************************************/+/*                                                                         */+/*  ftcimage.h                                                             */+/*                                                                         */+/*    FreeType Generic Image cache (specification)                         */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++ /*+  *  FTC_ICache is an _abstract_ cache used to store a single FT_Glyph+  *  image per cache node.+  *+  *  FTC_ICache extends FTC_GCache.  For an implementation example,+  *  see FTC_ImageCache in `src/cache/ftbasic.c'.+  */+++  /*************************************************************************/+  /*                                                                       */+  /* Each image cache really manages FT_Glyph objects.                     */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTCIMAGE_H__+#define __FTCIMAGE_H__+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcglyph.h"++FT_BEGIN_HEADER+++  /* the FT_Glyph image node type - we store only 1 glyph per node */+  typedef struct  FTC_INodeRec_+  {+    FTC_GNodeRec  gnode;+    FT_Glyph      glyph;++  } FTC_INodeRec, *FTC_INode;++#define FTC_INODE( x )         ( (FTC_INode)( x ) )+#define FTC_INODE_GINDEX( x )  FTC_GNODE(x)->gindex+#define FTC_INODE_FAMILY( x )  FTC_GNODE(x)->family++  typedef FT_Error+  (*FTC_IFamily_LoadGlyphFunc)( FTC_Family  family,+                                FT_UInt     gindex,+                                FTC_Cache   cache,+                                FT_Glyph   *aglyph );++  typedef struct  FTC_IFamilyClassRec_+  {+    FTC_MruListClassRec        clazz;+    FTC_IFamily_LoadGlyphFunc  family_load_glyph;++  } FTC_IFamilyClassRec;++  typedef const FTC_IFamilyClassRec*  FTC_IFamilyClass;++#define FTC_IFAMILY_CLASS( x )  ((FTC_IFamilyClass)(x))++#define FTC_CACHE__IFAMILY_CLASS( x ) \+          FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class )+++  /* can be used as a @FTC_Node_FreeFunc */+  FT_LOCAL( void )+  FTC_INode_Free( FTC_INode  inode,+                  FTC_Cache  cache );++  /* Can be used as @FTC_Node_NewFunc.  `gquery.index' and `gquery.family'+   * must be set correctly.  This function will call the `family_load_glyph'+   * method to load the FT_Glyph into the cache node.+   */+  FT_LOCAL( FT_Error )+  FTC_INode_New( FTC_INode   *pinode,+                 FTC_GQuery   gquery,+                 FTC_Cache    cache );++#if 0+  /* can be used as @FTC_Node_WeightFunc */+  FT_LOCAL( FT_ULong )+  FTC_INode_Weight( FTC_INode  inode );+#endif+++ /* */++FT_END_HEADER++#endif /* __FTCIMAGE_H__ */+++/* END */
+ src/cache/ftcmanag.c view
@@ -0,0 +1,743 @@+/***************************************************************************/+/*                                                                         */+/*  ftcmanag.c                                                             */+/*                                                                         */+/*    FreeType Cache Manager (body).                                       */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcmanag.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_SIZES_H++#include "ftccback.h"+#include "ftcerror.h"++#ifdef FT_CONFIG_OPTION_PIC+#error "cache system does not support PIC yet"+#endif +++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cache++#define FTC_LRU_GET_MANAGER( lru )  ( (FTC_Manager)(lru)->user_data )+++  static FT_Error+  ftc_scaler_lookup_size( FTC_Manager  manager,+                          FTC_Scaler   scaler,+                          FT_Size     *asize )+  {+    FT_Face   face;+    FT_Size   size = NULL;+    FT_Error  error;+++    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );+    if ( error )+      goto Exit;++    error = FT_New_Size( face, &size );+    if ( error )+      goto Exit;++    FT_Activate_Size( size );++    if ( scaler->pixel )+      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );+    else+      error = FT_Set_Char_Size( face, scaler->width, scaler->height,+                                scaler->x_res, scaler->y_res );+    if ( error )+    {+      FT_Done_Size( size );+      size = NULL;+    }++  Exit:+    *asize = size;+    return error;+  }+++  typedef struct  FTC_SizeNodeRec_+  {+    FTC_MruNodeRec  node;+    FT_Size         size;+    FTC_ScalerRec   scaler;++  } FTC_SizeNodeRec, *FTC_SizeNode;++#define FTC_SIZE_NODE( x ) ( (FTC_SizeNode)( x ) )+++  FT_CALLBACK_DEF( void )+  ftc_size_node_done( FTC_MruNode  ftcnode,+                      FT_Pointer   data )+  {+    FTC_SizeNode  node = (FTC_SizeNode)ftcnode;+    FT_Size       size = node->size;+    FT_UNUSED( data );+++    if ( size )+      FT_Done_Size( size );+  }+++  FT_CALLBACK_DEF( FT_Bool )+  ftc_size_node_compare( FTC_MruNode  ftcnode,+                         FT_Pointer   ftcscaler )+  {+    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;+    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;+    FTC_Scaler    scaler0 = &node->scaler;+++    if ( FTC_SCALER_COMPARE( scaler0, scaler ) )+    {+      FT_Activate_Size( node->size );+      return 1;+    }+    return 0;+  }+++  FT_CALLBACK_DEF( FT_Error )+  ftc_size_node_init( FTC_MruNode  ftcnode,+                      FT_Pointer   ftcscaler,+                      FT_Pointer   ftcmanager )+  {+    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;+    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;+    FTC_Manager   manager = (FTC_Manager)ftcmanager;+++    node->scaler = scaler[0];++    return ftc_scaler_lookup_size( manager, scaler, &node->size );+  }+++  FT_CALLBACK_DEF( FT_Error )+  ftc_size_node_reset( FTC_MruNode  ftcnode,+                       FT_Pointer   ftcscaler,+                       FT_Pointer   ftcmanager )+  {+    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;+    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;+    FTC_Manager   manager = (FTC_Manager)ftcmanager;+++    FT_Done_Size( node->size );++    node->scaler = scaler[0];++    return ftc_scaler_lookup_size( manager, scaler, &node->size );+  }+++  FT_CALLBACK_TABLE_DEF+  const FTC_MruListClassRec  ftc_size_list_class =+  {+    sizeof ( FTC_SizeNodeRec ),+    ftc_size_node_compare,+    ftc_size_node_init,+    ftc_size_node_reset,+    ftc_size_node_done+  };+++  /* helper function used by ftc_face_node_done */+  static FT_Bool+  ftc_size_node_compare_faceid( FTC_MruNode  ftcnode,+                                FT_Pointer   ftcface_id )+  {+    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;+    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;+++    return FT_BOOL( node->scaler.face_id == face_id );+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_Manager_LookupSize( FTC_Manager  manager,+                          FTC_Scaler   scaler,+                          FT_Size     *asize )+  {+    FT_Error     error;+    FTC_MruNode  mrunode;+++    if ( asize == NULL )+      return FTC_Err_Invalid_Argument;++    *asize = NULL;++    if ( !manager )+      return FTC_Err_Invalid_Cache_Handle;++#ifdef FTC_INLINE++    FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare,+                            mrunode, error );++#else+    error = FTC_MruList_Lookup( &manager->sizes, scaler, &mrunode );+#endif++    if ( !error )+      *asize = FTC_SIZE_NODE( mrunode )->size;++    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    FACE MRU IMPLEMENTATION                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct  FTC_FaceNodeRec_+  {+    FTC_MruNodeRec  node;+    FTC_FaceID      face_id;+    FT_Face         face;++  } FTC_FaceNodeRec, *FTC_FaceNode;++#define FTC_FACE_NODE( x ) ( ( FTC_FaceNode )( x ) )+++  FT_CALLBACK_DEF( FT_Error )+  ftc_face_node_init( FTC_MruNode  ftcnode,+                      FT_Pointer   ftcface_id,+                      FT_Pointer   ftcmanager )+  {+    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;+    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;+    FTC_Manager   manager = (FTC_Manager)ftcmanager;+    FT_Error      error;+++    node->face_id = face_id;++    error = manager->request_face( face_id,+                                   manager->library,+                                   manager->request_data,+                                   &node->face );+    if ( !error )+    {+      /* destroy initial size object; it will be re-created later */+      if ( node->face->size )+        FT_Done_Size( node->face->size );+    }++    return error;+  }+++  FT_CALLBACK_DEF( void )+  ftc_face_node_done( FTC_MruNode  ftcnode,+                      FT_Pointer   ftcmanager )+  {+    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;+    FTC_Manager   manager = (FTC_Manager)ftcmanager;+++    /* we must begin by removing all scalers for the target face */+    /* from the manager's list                                   */+    FTC_MruList_RemoveSelection( &manager->sizes,+                                 ftc_size_node_compare_faceid,+                                 node->face_id );++    /* all right, we can discard the face now */+    FT_Done_Face( node->face );+    node->face    = NULL;+    node->face_id = NULL;+  }+++  FT_CALLBACK_DEF( FT_Bool )+  ftc_face_node_compare( FTC_MruNode  ftcnode,+                         FT_Pointer   ftcface_id )+  {+    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;+    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;+++    return FT_BOOL( node->face_id == face_id );+  }+++  FT_CALLBACK_TABLE_DEF+  const FTC_MruListClassRec  ftc_face_list_class =+  {+    sizeof ( FTC_FaceNodeRec),++    ftc_face_node_compare,+    ftc_face_node_init,+    0,                          /* FTC_MruNode_ResetFunc */+    ftc_face_node_done+  };+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_Manager_LookupFace( FTC_Manager  manager,+                          FTC_FaceID   face_id,+                          FT_Face     *aface )+  {+    FT_Error     error;+    FTC_MruNode  mrunode;+++    if ( aface == NULL )+      return FTC_Err_Invalid_Argument;++    *aface = NULL;++    if ( !manager )+      return FTC_Err_Invalid_Cache_Handle;++    /* we break encapsulation for the sake of speed */+#ifdef FTC_INLINE++    FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare,+                            mrunode, error );++#else+    error = FTC_MruList_Lookup( &manager->faces, face_id, &mrunode );+#endif++    if ( !error )+      *aface = FTC_FACE_NODE( mrunode )->face;++    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    CACHE MANAGER ROUTINES                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( FT_Error )+  FTC_Manager_New( FT_Library          library,+                   FT_UInt             max_faces,+                   FT_UInt             max_sizes,+                   FT_ULong            max_bytes,+                   FTC_Face_Requester  requester,+                   FT_Pointer          req_data,+                   FTC_Manager        *amanager )+  {+    FT_Error     error;+    FT_Memory    memory;+    FTC_Manager  manager = 0;+++    if ( !library )+      return FTC_Err_Invalid_Library_Handle;++    memory = library->memory;++    if ( FT_NEW( manager ) )+      goto Exit;++    if ( max_faces == 0 )+      max_faces = FTC_MAX_FACES_DEFAULT;++    if ( max_sizes == 0 )+      max_sizes = FTC_MAX_SIZES_DEFAULT;++    if ( max_bytes == 0 )+      max_bytes = FTC_MAX_BYTES_DEFAULT;++    manager->library      = library;+    manager->memory       = memory;+    manager->max_weight   = max_bytes;++    manager->request_face = requester;+    manager->request_data = req_data;++    FTC_MruList_Init( &manager->faces,+                      &ftc_face_list_class,+                      max_faces,+                      manager,+                      memory );++    FTC_MruList_Init( &manager->sizes,+                      &ftc_size_list_class,+                      max_sizes,+                      manager,+                      memory );++    *amanager = manager;++  Exit:+    return error;+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( void )+  FTC_Manager_Done( FTC_Manager  manager )+  {+    FT_Memory  memory;+    FT_UInt    idx;+++    if ( !manager || !manager->library )+      return;++    memory = manager->memory;++    /* now discard all caches */+    for (idx = manager->num_caches; idx-- > 0; )+    {+      FTC_Cache  cache = manager->caches[idx];+++      if ( cache )+      {+        cache->clazz.cache_done( cache );+        FT_FREE( cache );+        manager->caches[idx] = NULL;+      }+    }+    manager->num_caches = 0;++    /* discard faces and sizes */+    FTC_MruList_Done( &manager->sizes );+    FTC_MruList_Done( &manager->faces );++    manager->library = NULL;+    manager->memory  = NULL;++    FT_FREE( manager );+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( void )+  FTC_Manager_Reset( FTC_Manager  manager )+  {+    if ( manager )+    {+      FTC_MruList_Reset( &manager->sizes );+      FTC_MruList_Reset( &manager->faces );+    }+    /* XXX: FIXME: flush the caches? */+  }+++#ifdef FT_DEBUG_ERROR++  static void+  FTC_Manager_Check( FTC_Manager  manager )+  {+    FTC_Node  node, first;+++    first = manager->nodes_list;++    /* check node weights */+    if ( first )+    {+      FT_ULong  weight = 0;+++      node = first;++      do+      {+        FTC_Cache  cache = manager->caches[node->cache_index];+++        if ( (FT_UInt)node->cache_index >= manager->num_caches )+          FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n",+                      node->cache_index ));+        else+          weight += cache->clazz.node_weight( node, cache );++        node = FTC_NODE__NEXT( node );++      } while ( node != first );++      if ( weight != manager->cur_weight )+        FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n",+                    manager->cur_weight, weight ));+    }++    /* check circular list */+    if ( first )+    {+      FT_UFast  count = 0;+++      node = first;+      do+      {+        count++;+        node = FTC_NODE__NEXT( node );++      } while ( node != first );++      if ( count != manager->num_nodes )+        FT_TRACE0(( "FTC_Manager_Check:"+                    " invalid cache node count %d instead of %d\n",+                    manager->num_nodes, count ));+    }+  }++#endif /* FT_DEBUG_ERROR */+++  /* `Compress' the manager's data, i.e., get rid of old cache nodes */+  /* that are not referenced anymore in order to limit the total     */+  /* memory used by the cache.                                       */++  /* documentation is in ftcmanag.h */++  FT_LOCAL_DEF( void )+  FTC_Manager_Compress( FTC_Manager  manager )+  {+    FTC_Node   node, first;+++    if ( !manager )+      return;++    first = manager->nodes_list;++#ifdef FT_DEBUG_ERROR+    FTC_Manager_Check( manager );++    FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n",+                manager->cur_weight, manager->max_weight,+                manager->num_nodes ));+#endif++    if ( manager->cur_weight < manager->max_weight || first == NULL )+      return;++    /* go to last node -- it's a circular list */+    node = FTC_NODE__PREV( first );+    do+    {+      FTC_Node  prev;+++      prev = ( node == first ) ? NULL : FTC_NODE__PREV( node );++      if ( node->ref_count <= 0 )+        ftc_node_destroy( node, manager );++      node = prev;++    } while ( node && manager->cur_weight > manager->max_weight );+  }+++  /* documentation is in ftcmanag.h */++  FT_LOCAL_DEF( FT_Error )+  FTC_Manager_RegisterCache( FTC_Manager      manager,+                             FTC_CacheClass   clazz,+                             FTC_Cache       *acache )+  {+    FT_Error   error = FTC_Err_Invalid_Argument;+    FTC_Cache  cache = NULL;+++    if ( manager && clazz && acache )+    {+      FT_Memory  memory = manager->memory;+++      if ( manager->num_caches >= FTC_MAX_CACHES )+      {+        error = FTC_Err_Too_Many_Caches;+        FT_ERROR(( "FTC_Manager_RegisterCache:"+                   " too many registered caches\n" ));+        goto Exit;+      }++      if ( !FT_ALLOC( cache, clazz->cache_size ) )+      {+        cache->manager   = manager;+        cache->memory    = memory;+        cache->clazz     = clazz[0];+        cache->org_class = clazz;++        /* THIS IS VERY IMPORTANT!  IT WILL WRETCH THE MANAGER */+        /* IF IT IS NOT SET CORRECTLY                          */+        cache->index = manager->num_caches;++        error = clazz->cache_init( cache );+        if ( error )+        {+          clazz->cache_done( cache );+          FT_FREE( cache );+          goto Exit;+        }++        manager->caches[manager->num_caches++] = cache;+      }+    }++  Exit:+    if ( acache )+      *acache = cache;+    return error;+  }+++  FT_LOCAL_DEF( FT_UInt )+  FTC_Manager_FlushN( FTC_Manager  manager,+                      FT_UInt      count )+  {+    FTC_Node  first = manager->nodes_list;+    FTC_Node  node;+    FT_UInt   result;+++    /* try to remove `count' nodes from the list */+    if ( first == NULL )  /* empty list! */+      return 0;++    /* go to last node - it's a circular list */+    node = FTC_NODE__PREV(first);+    for ( result = 0; result < count; )+    {+      FTC_Node  prev = FTC_NODE__PREV( node );+++      /* don't touch locked nodes */+      if ( node->ref_count <= 0 )+      {+        ftc_node_destroy( node, manager );+        result++;+      }++      if ( node == first )+        break;++      node = prev;+    }+    return  result;+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( void )+  FTC_Manager_RemoveFaceID( FTC_Manager  manager,+                            FTC_FaceID   face_id )+  {+    FT_UInt  nn;++    /* this will remove all FTC_SizeNode that correspond to+     * the face_id as well+     */+    FTC_MruList_RemoveSelection( &manager->faces,+                                 ftc_face_node_compare,+                                 face_id );++    for ( nn = 0; nn < manager->num_caches; nn++ )+      FTC_Cache_RemoveFaceID( manager->caches[nn], face_id );+  }+++  /* documentation is in ftcache.h */++  FT_EXPORT_DEF( void )+  FTC_Node_Unref( FTC_Node     node,+                  FTC_Manager  manager )+  {+    if ( node && (FT_UInt)node->cache_index < manager->num_caches )+      node->ref_count--;+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_EXPORT_DEF( FT_Error )+  FTC_Manager_Lookup_Face( FTC_Manager  manager,+                           FTC_FaceID   face_id,+                           FT_Face     *aface )+  {+    return FTC_Manager_LookupFace( manager, face_id, aface );+  }+++  FT_EXPORT( FT_Error )+  FTC_Manager_Lookup_Size( FTC_Manager  manager,+                           FTC_Font     font,+                           FT_Face     *aface,+                           FT_Size     *asize )+  {+    FTC_ScalerRec  scaler;+    FT_Error       error;+    FT_Size        size;+    FT_Face        face;+++    scaler.face_id = font->face_id;+    scaler.width   = font->pix_width;+    scaler.height  = font->pix_height;+    scaler.pixel   = TRUE;+    scaler.x_res   = 0;+    scaler.y_res   = 0;++    error = FTC_Manager_LookupSize( manager, &scaler, &size );+    if ( error )+    {+      face = NULL;+      size = NULL;+    }+    else+      face = size->face;++    if ( aface )+      *aface = face;++    if ( asize )+      *asize = size;++    return error;+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++/* END */
+ src/cache/ftcmanag.h view
@@ -0,0 +1,175 @@+/***************************************************************************/+/*                                                                         */+/*  ftcmanag.h                                                             */+/*                                                                         */+/*    FreeType Cache Manager (specification).                              */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2004, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* A cache manager is in charge of the following:                        */+  /*                                                                       */+  /*  - Maintain a mapping between generic FTC_FaceIDs and live FT_Face    */+  /*    objects.  The mapping itself is performed through a user-provided  */+  /*    callback.  However, the manager maintains a small cache of FT_Face */+  /*    and FT_Size objects in order to speed up things considerably.      */+  /*                                                                       */+  /*  - Manage one or more cache objects.  Each cache is in charge of      */+  /*    holding a varying number of `cache nodes'.  Each cache node        */+  /*    represents a minimal amount of individually accessible cached      */+  /*    data.  For example, a cache node can be an FT_Glyph image          */+  /*    containing a vector outline, or some glyph metrics, or anything    */+  /*    else.                                                              */+  /*                                                                       */+  /*    Each cache node has a certain size in bytes that is added to the   */+  /*    total amount of `cache memory' within the manager.                 */+  /*                                                                       */+  /*    All cache nodes are located in a global LRU list, where the oldest */+  /*    node is at the tail of the list.                                   */+  /*                                                                       */+  /*    Each node belongs to a single cache, and includes a reference      */+  /*    count to avoid destroying it (due to caching).                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*********                                                       *********/+  /*********             WARNING, THIS IS BETA CODE.               *********/+  /*********                                                       *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#ifndef __FTCMANAG_H__+#define __FTCMANAG_H__+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcmru.h"+#include "ftccache.h"+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Section>                                                             */+  /*    cache_subsystem                                                    */+  /*                                                                       */+  /*************************************************************************/+++#define FTC_MAX_FACES_DEFAULT  2+#define FTC_MAX_SIZES_DEFAULT  4+#define FTC_MAX_BYTES_DEFAULT  200000L  /* ~200kByte by default */++  /* maximum number of caches registered in a single manager */+#define FTC_MAX_CACHES         16+++  typedef struct  FTC_ManagerRec_+  {+    FT_Library          library;+    FT_Memory           memory;++    FTC_Node            nodes_list;+    FT_ULong            max_weight;+    FT_ULong            cur_weight;+    FT_UInt             num_nodes;++    FTC_Cache           caches[FTC_MAX_CACHES];+    FT_UInt             num_caches;++    FTC_MruListRec      faces;+    FTC_MruListRec      sizes;++    FT_Pointer          request_data;+    FTC_Face_Requester  request_face;++  } FTC_ManagerRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FTC_Manager_Compress                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This function is used to check the state of the cache manager if   */+  /*    its `num_bytes' field is greater than its `max_bytes' field.  It   */+  /*    will flush as many old cache nodes as possible (ignoring cache     */+  /*    nodes with a non-zero reference count).                            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    manager :: A handle to the cache manager.                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Client applications should not call this function directly.  It is */+  /*    normally invoked by specific cache implementations.                */+  /*                                                                       */+  /*    The reason this function is exported is to allow client-specific   */+  /*    cache classes.                                                     */+  /*                                                                       */+  FT_LOCAL( void )+  FTC_Manager_Compress( FTC_Manager  manager );+++  /* try to flush `count' old nodes from the cache; return the number+   * of really flushed nodes+   */+  FT_LOCAL( FT_UInt )+  FTC_Manager_FlushN( FTC_Manager  manager,+                      FT_UInt      count );+++  /* this must be used internally for the moment */+  FT_LOCAL( FT_Error )+  FTC_Manager_RegisterCache( FTC_Manager      manager,+                             FTC_CacheClass   clazz,+                             FTC_Cache       *acache );++ /* */++#define FTC_SCALER_COMPARE( a, b )                \+    ( (a)->face_id      == (b)->face_id      &&   \+      (a)->width        == (b)->width        &&   \+      (a)->height       == (b)->height       &&   \+      ((a)->pixel != 0) == ((b)->pixel != 0) &&   \+      ( (a)->pixel ||                             \+        ( (a)->x_res == (b)->x_res &&             \+          (a)->y_res == (b)->y_res ) ) )++#define FTC_SCALER_HASH( q )                                 \+    ( _FTC_FACE_ID_HASH( (q)->face_id ) +                     \+      (q)->width + (q)->height*7 +                           \+      ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) )++ /* */++FT_END_HEADER++#endif /* __FTCMANAG_H__ */+++/* END */
+ src/cache/ftcmru.c view
@@ -0,0 +1,357 @@+/***************************************************************************/+/*                                                                         */+/*  ftcmru.c                                                               */+/*                                                                         */+/*    FreeType MRU support (body).                                         */+/*                                                                         */+/*  Copyright 2003, 2004, 2006, 2009 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcmru.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H++#include "ftcerror.h"+++  FT_LOCAL_DEF( void )+  FTC_MruNode_Prepend( FTC_MruNode  *plist,+                       FTC_MruNode   node )+  {+    FTC_MruNode  first = *plist;+++    if ( first )+    {+      FTC_MruNode  last = first->prev;+++#ifdef FT_DEBUG_ERROR+      {+        FTC_MruNode  cnode = first;+++        do+        {+          if ( cnode == node )+          {+            fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );+            exit( 2 );+          }+          cnode = cnode->next;++        } while ( cnode != first );+      }+#endif++      first->prev = node;+      last->next  = node;+      node->next  = first;+      node->prev  = last;+    }+    else+    {+      node->next = node;+      node->prev = node;+    }+    *plist = node;+  }+++  FT_LOCAL_DEF( void )+  FTC_MruNode_Up( FTC_MruNode  *plist,+                  FTC_MruNode   node )+  {+    FTC_MruNode  first = *plist;+++    FT_ASSERT( first != NULL );++    if ( first != node )+    {+      FTC_MruNode  prev, next, last;+++#ifdef FT_DEBUG_ERROR+      {+        FTC_MruNode  cnode = first;+        do+        {+          if ( cnode == node )+            goto Ok;+          cnode = cnode->next;++        } while ( cnode != first );++        fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );+        exit( 2 );+      Ok:+      }+#endif+      prev = node->prev;+      next = node->next;++      prev->next = next;+      next->prev = prev;++      last = first->prev;++      last->next  = node;+      first->prev = node;++      node->next = first;+      node->prev = last;++      *plist = node;+    }+  }+++  FT_LOCAL_DEF( void )+  FTC_MruNode_Remove( FTC_MruNode  *plist,+                      FTC_MruNode   node )+  {+    FTC_MruNode  first = *plist;+    FTC_MruNode  prev, next;+++    FT_ASSERT( first != NULL );++#ifdef FT_DEBUG_ERROR+      {+        FTC_MruNode  cnode = first;+++        do+        {+          if ( cnode == node )+            goto Ok;+          cnode = cnode->next;++        } while ( cnode != first );++        fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );+        exit( 2 );+      Ok:+      }+#endif++    prev = node->prev;+    next = node->next;++    prev->next = next;+    next->prev = prev;++    if ( node == next )+    {+      FT_ASSERT( first == node );+      FT_ASSERT( prev  == node );++      *plist = NULL;+    }+    else if ( node == first )+        *plist = next;+  }+++  FT_LOCAL_DEF( void )+  FTC_MruList_Init( FTC_MruList       list,+                    FTC_MruListClass  clazz,+                    FT_UInt           max_nodes,+                    FT_Pointer        data,+                    FT_Memory         memory )+  {+    list->num_nodes = 0;+    list->max_nodes = max_nodes;+    list->nodes     = NULL;+    list->clazz     = *clazz;+    list->data      = data;+    list->memory    = memory;+  }+++  FT_LOCAL_DEF( void )+  FTC_MruList_Reset( FTC_MruList  list )+  {+    while ( list->nodes )+      FTC_MruList_Remove( list, list->nodes );++    FT_ASSERT( list->num_nodes == 0 );+  }+++  FT_LOCAL_DEF( void )+  FTC_MruList_Done( FTC_MruList  list )+  {+    FTC_MruList_Reset( list );+  }+++#ifndef FTC_INLINE+  FT_LOCAL_DEF( FTC_MruNode )+  FTC_MruList_Find( FTC_MruList  list,+                    FT_Pointer   key )+  {+    FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;+    FTC_MruNode              first, node;+++    first = list->nodes;+    node  = NULL;++    if ( first )+    {+      node = first;+      do+      {+        if ( compare( node, key ) )+        {+          if ( node != first )+            FTC_MruNode_Up( &list->nodes, node );++          return node;+        }++        node = node->next;++      } while ( node != first);+    }++    return NULL;+  }+#endif++  FT_LOCAL_DEF( FT_Error )+  FTC_MruList_New( FTC_MruList   list,+                   FT_Pointer    key,+                   FTC_MruNode  *anode )+  {+    FT_Error     error;+    FTC_MruNode  node;+    FT_Memory    memory = list->memory;+++    if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )+    {+      node = list->nodes->prev;++      FT_ASSERT( node );++      if ( list->clazz.node_reset )+      {+        FTC_MruNode_Up( &list->nodes, node );++        error = list->clazz.node_reset( node, key, list->data );+        if ( !error )+          goto Exit;+      }++      FTC_MruNode_Remove( &list->nodes, node );+      list->num_nodes--;++      if ( list->clazz.node_done )+        list->clazz.node_done( node, list->data );+    }+    else if ( FT_ALLOC( node, list->clazz.node_size ) )+        goto Exit;++    error = list->clazz.node_init( node, key, list->data );+    if ( error )+      goto Fail;++      FTC_MruNode_Prepend( &list->nodes, node );+      list->num_nodes++;++  Exit:+    *anode = node;+    return error;++  Fail:+    if ( list->clazz.node_done )+      list->clazz.node_done( node, list->data );++    FT_FREE( node );+    goto Exit;+  }+++#ifndef FTC_INLINE+  FT_LOCAL_DEF( FT_Error )+  FTC_MruList_Lookup( FTC_MruList   list,+                      FT_Pointer    key,+                      FTC_MruNode  *anode )+  {+    FTC_MruNode  node;+++    node = FTC_MruList_Find( list, key );+    if ( node == NULL )+      return FTC_MruList_New( list, key, anode );++    *anode = node;+    return 0;+  }+#endif /* FTC_INLINE */++  FT_LOCAL_DEF( void )+  FTC_MruList_Remove( FTC_MruList  list,+                      FTC_MruNode  node )+  {+    FTC_MruNode_Remove( &list->nodes, node );+    list->num_nodes--;++    {+      FT_Memory  memory = list->memory;+++      if ( list->clazz.node_done )+       list->clazz.node_done( node, list->data );++      FT_FREE( node );+    }+  }+++  FT_LOCAL_DEF( void )+  FTC_MruList_RemoveSelection( FTC_MruList              list,+                               FTC_MruNode_CompareFunc  selection,+                               FT_Pointer               key )+  {+    FTC_MruNode  first, node, next;+++    first = list->nodes;+    while ( first && ( selection == NULL || selection( first, key ) ) )+    {+      FTC_MruList_Remove( list, first );+      first = list->nodes;+    }++    if ( first )+    {+      node = first->next;+      while ( node != first )+      {+        next = node->next;++        if ( selection( node, key ) )+          FTC_MruList_Remove( list, node );++        node = next;+      }+    }+  }+++/* END */
+ src/cache/ftcmru.h view
@@ -0,0 +1,246 @@+/***************************************************************************/+/*                                                                         */+/*  ftcmru.h                                                               */+/*                                                                         */+/*    Simple MRU list-cache (specification).                               */+/*                                                                         */+/*  Copyright 2000-2001, 2003, 2004, 2005, 2006, 2010 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* An MRU is a list that cannot hold more than a certain number of       */+  /* elements (`max_elements').  All elements in the list are sorted in    */+  /* least-recently-used order, i.e., the `oldest' element is at the tail  */+  /* of the list.                                                          */+  /*                                                                       */+  /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */+  /* the list is searched for an element with the corresponding key.  If   */+  /* it is found, the element is moved to the head of the list and is      */+  /* returned.                                                             */+  /*                                                                       */+  /* If no corresponding element is found, the lookup routine will try to  */+  /* obtain a new element with the relevant key.  If the list is already   */+  /* full, the oldest element from the list is discarded and replaced by a */+  /* new one; a new element is added to the list otherwise.                */+  /*                                                                       */+  /* Note that it is possible to pre-allocate the element list nodes.      */+  /* This is handy if `max_elements' is sufficiently small, as it saves    */+  /* allocations/releases during the lookup process.                       */+  /*                                                                       */+  /*************************************************************************/+++#ifndef __FTCMRU_H__+#define __FTCMRU_H__+++#include <ft2build.h>+#include FT_FREETYPE_H++#ifdef FREETYPE_H+#error "freetype.h of FreeType 1 has been loaded!"+#error "Please fix the directory search order for header files"+#error "so that freetype.h of FreeType 2 is found first."+#endif++#define  xxFT_DEBUG_ERROR+#define  FTC_INLINE++FT_BEGIN_HEADER++  typedef struct FTC_MruNodeRec_*  FTC_MruNode;++  typedef struct  FTC_MruNodeRec_+  {+    FTC_MruNode  next;+    FTC_MruNode  prev;++  } FTC_MruNodeRec;+++  FT_LOCAL( void )+  FTC_MruNode_Prepend( FTC_MruNode  *plist,+                       FTC_MruNode   node );++  FT_LOCAL( void )+  FTC_MruNode_Up( FTC_MruNode  *plist,+                  FTC_MruNode   node );++  FT_LOCAL( void )+  FTC_MruNode_Remove( FTC_MruNode  *plist,+                      FTC_MruNode   node );+++  typedef struct FTC_MruListRec_*              FTC_MruList;++  typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;+++  typedef FT_Bool+  (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,+                              FT_Pointer   key );++  typedef FT_Error+  (*FTC_MruNode_InitFunc)( FTC_MruNode  node,+                           FT_Pointer   key,+                           FT_Pointer   data );++  typedef FT_Error+  (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,+                            FT_Pointer   key,+                            FT_Pointer   data );++  typedef void+  (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,+                           FT_Pointer   data );+++  typedef struct  FTC_MruListClassRec_+  {+    FT_Offset                node_size;+    FTC_MruNode_CompareFunc  node_compare;+    FTC_MruNode_InitFunc     node_init;+    FTC_MruNode_ResetFunc    node_reset;+    FTC_MruNode_DoneFunc     node_done;++  } FTC_MruListClassRec;++  typedef struct  FTC_MruListRec_+  {+    FT_UInt              num_nodes;+    FT_UInt              max_nodes;+    FTC_MruNode          nodes;+    FT_Pointer           data;+    FTC_MruListClassRec  clazz;+    FT_Memory            memory;++  } FTC_MruListRec;+++  FT_LOCAL( void )+  FTC_MruList_Init( FTC_MruList       list,+                    FTC_MruListClass  clazz,+                    FT_UInt           max_nodes,+                    FT_Pointer        data,+                    FT_Memory         memory );++  FT_LOCAL( void )+  FTC_MruList_Reset( FTC_MruList  list );+++  FT_LOCAL( void )+  FTC_MruList_Done( FTC_MruList  list );+++  FT_LOCAL( FT_Error )+  FTC_MruList_New( FTC_MruList   list,+                   FT_Pointer    key,+                   FTC_MruNode  *anode );++  FT_LOCAL( void )+  FTC_MruList_Remove( FTC_MruList  list,+                      FTC_MruNode  node );++  FT_LOCAL( void )+  FTC_MruList_RemoveSelection( FTC_MruList              list,+                               FTC_MruNode_CompareFunc  selection,+                               FT_Pointer               key );+++#ifdef FTC_INLINE++#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error )           \+  FT_BEGIN_STMNT                                                            \+    FTC_MruNode*             _pfirst  = &(list)->nodes;                     \+    FTC_MruNode_CompareFunc  _compare = (FTC_MruNode_CompareFunc)(compare); \+    FTC_MruNode              _first, _node;                                 \+                                                                            \+                                                                            \+    error  = FTC_Err_Ok;                                                    \+    _first = *(_pfirst);                                                    \+    _node  = NULL;                                                          \+                                                                            \+    if ( _first )                                                           \+    {                                                                       \+      _node = _first;                                                       \+      do                                                                    \+      {                                                                     \+        if ( _compare( _node, (key) ) )                                     \+        {                                                                   \+          if ( _node != _first )                                            \+            FTC_MruNode_Up( _pfirst, _node );                               \+                                                                            \+          node = _node;                                                     \+          goto _MruOk;                                                      \+        }                                                                   \+        _node = _node->next;                                                \+                                                                            \+      } while ( _node != _first) ;                                          \+    }                                                                       \+                                                                            \+    error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \+  _MruOk:                                                                   \+    ;                                                                       \+  FT_END_STMNT++#define FTC_MRULIST_LOOKUP( list, key, node, error ) \+  FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )++#else  /* !FTC_INLINE */++  FT_LOCAL( FTC_MruNode )+  FTC_MruList_Find( FTC_MruList  list,+                    FT_Pointer   key );++  FT_LOCAL( FT_Error )+  FTC_MruList_Lookup( FTC_MruList   list,+                      FT_Pointer    key,+                      FTC_MruNode  *pnode );++#define FTC_MRULIST_LOOKUP( list, key, node, error ) \+  error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) )++#endif /* !FTC_INLINE */+++#define FTC_MRULIST_LOOP( list, node )        \+  FT_BEGIN_STMNT                              \+    FTC_MruNode  _first = (list)->nodes;      \+                                              \+                                              \+    if ( _first )                             \+    {                                         \+      FTC_MruNode  _node = _first;            \+                                              \+                                              \+      do                                      \+      {                                       \+        *(FTC_MruNode*)&(node) = _node;+++#define FTC_MRULIST_LOOP_END()               \+        _node = _node->next;                 \+                                             \+      } while ( _node != _first );           \+    }                                        \+  FT_END_STMNT++ /* */++FT_END_HEADER+++#endif /* __FTCMRU_H__ */+++/* END */
+ src/cache/ftcsbits.c view
@@ -0,0 +1,408 @@+/***************************************************************************/+/*                                                                         */+/*  ftcsbits.c                                                             */+/*                                                                         */+/*    FreeType sbits manager (body).                                       */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcsbits.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_ERRORS_H++#include "ftccback.h"+#include "ftcerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cache+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     SBIT CACHE NODES                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  static FT_Error+  ftc_sbit_copy_bitmap( FTC_SBit    sbit,+                        FT_Bitmap*  bitmap,+                        FT_Memory   memory )+  {+    FT_Error  error;+    FT_Int    pitch = bitmap->pitch;+    FT_ULong  size;+++    if ( pitch < 0 )+      pitch = -pitch;++    size = (FT_ULong)( pitch * bitmap->rows );++    if ( !FT_ALLOC( sbit->buffer, size ) )+      FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );++    return error;+  }+++  FT_LOCAL_DEF( void )+  ftc_snode_free( FTC_Node   ftcsnode,+                  FTC_Cache  cache )+  {+    FTC_SNode  snode  = (FTC_SNode)ftcsnode;+    FTC_SBit   sbit   = snode->sbits;+    FT_UInt    count  = snode->count;+    FT_Memory  memory = cache->memory;+++    for ( ; count > 0; sbit++, count-- )+      FT_FREE( sbit->buffer );++    FTC_GNode_Done( FTC_GNODE( snode ), cache );++    FT_FREE( snode );+  }+++  FT_LOCAL_DEF( void )+  FTC_SNode_Free( FTC_SNode  snode,+                  FTC_Cache  cache )+  {+    ftc_snode_free( FTC_NODE( snode ), cache );+  }+++  /*+   *  This function tries to load a small bitmap within a given FTC_SNode.+   *  Note that it returns a non-zero error code _only_ in the case of+   *  out-of-memory condition.  For all other errors (e.g., corresponding+   *  to a bad font file), this function will mark the sbit as `unavailable'+   *  and return a value of 0.+   *+   *  You should also read the comment within the @ftc_snode_compare+   *  function below to see how out-of-memory is handled during a lookup.+   */+  static FT_Error+  ftc_snode_load( FTC_SNode    snode,+                  FTC_Manager  manager,+                  FT_UInt      gindex,+                  FT_ULong    *asize )+  {+    FT_Error          error;+    FTC_GNode         gnode  = FTC_GNODE( snode );+    FTC_Family        family = gnode->family;+    FT_Memory         memory = manager->memory;+    FT_Face           face;+    FTC_SBit          sbit;+    FTC_SFamilyClass  clazz;+++    if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count )+    {+      FT_ERROR(( "ftc_snode_load: invalid glyph index" ));+      return FTC_Err_Invalid_Argument;+    }++    sbit  = snode->sbits + ( gindex - gnode->gindex );+    clazz = (FTC_SFamilyClass)family->clazz;++    sbit->buffer = 0;++    error = clazz->family_load_glyph( family, gindex, manager, &face );+    if ( error )+      goto BadGlyph;++    {+      FT_Int        temp;+      FT_GlyphSlot  slot   = face->glyph;+      FT_Bitmap*    bitmap = &slot->bitmap;+      FT_Pos        xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */+++      if ( slot->format != FT_GLYPH_FORMAT_BITMAP )+      {+        FT_TRACE0(( "ftc_snode_load:"+                    " glyph loaded didn't return a bitmap\n" ));+        goto BadGlyph;+      }++      /* Check that our values fit into 8-bit containers!       */+      /* If this is not the case, our bitmap is too large       */+      /* and we will leave it as `missing' with sbit.buffer = 0 */++#define CHECK_CHAR( d )  ( temp = (FT_Char)d, temp == d )+#define CHECK_BYTE( d )  ( temp = (FT_Byte)d, temp == d )++      /* horizontal advance in pixels */+      xadvance = ( slot->advance.x + 32 ) >> 6;+      yadvance = ( slot->advance.y + 32 ) >> 6;++      if ( !CHECK_BYTE( bitmap->rows  )     ||+           !CHECK_BYTE( bitmap->width )     ||+           !CHECK_CHAR( bitmap->pitch )     ||+           !CHECK_CHAR( slot->bitmap_left ) ||+           !CHECK_CHAR( slot->bitmap_top  ) ||+           !CHECK_CHAR( xadvance )          ||+           !CHECK_CHAR( yadvance )          )+      {+        FT_TRACE2(( "ftc_snode_load:"+                    " glyph too large for small bitmap cache\n"));+        goto BadGlyph;+      }++      sbit->width     = (FT_Byte)bitmap->width;+      sbit->height    = (FT_Byte)bitmap->rows;+      sbit->pitch     = (FT_Char)bitmap->pitch;+      sbit->left      = (FT_Char)slot->bitmap_left;+      sbit->top       = (FT_Char)slot->bitmap_top;+      sbit->xadvance  = (FT_Char)xadvance;+      sbit->yadvance  = (FT_Char)yadvance;+      sbit->format    = (FT_Byte)bitmap->pixel_mode;+      sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);++      /* copy the bitmap into a new buffer -- ignore error */+      error = ftc_sbit_copy_bitmap( sbit, bitmap, memory );++      /* now, compute size */+      if ( asize )+        *asize = FT_ABS( sbit->pitch ) * sbit->height;++    } /* glyph loading successful */++    /* ignore the errors that might have occurred --   */+    /* we mark unloaded glyphs with `sbit.buffer == 0' */+    /* and `width == 255', `height == 0'               */+    /*                                                 */+    if ( error && error != FTC_Err_Out_Of_Memory )+    {+    BadGlyph:+      sbit->width  = 255;+      sbit->height = 0;+      sbit->buffer = NULL;+      error        = FTC_Err_Ok;+      if ( asize )+        *asize = 0;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  FTC_SNode_New( FTC_SNode  *psnode,+                 FTC_GQuery  gquery,+                 FTC_Cache   cache )+  {+    FT_Memory   memory = cache->memory;+    FT_Error    error;+    FTC_SNode   snode  = NULL;+    FT_UInt     gindex = gquery->gindex;+    FTC_Family  family = gquery->family;++    FTC_SFamilyClass  clazz = FTC_CACHE__SFAMILY_CLASS( cache );+    FT_UInt           total;+++    total = clazz->family_get_count( family, cache->manager );+    if ( total == 0 || gindex >= total )+    {+      error = FTC_Err_Invalid_Argument;+      goto Exit;+    }++    if ( !FT_NEW( snode ) )+    {+      FT_UInt  count, start;+++      start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );+      count = total - start;+      if ( count > FTC_SBIT_ITEMS_PER_NODE )+        count = FTC_SBIT_ITEMS_PER_NODE;++      FTC_GNode_Init( FTC_GNODE( snode ), start, family );++      snode->count = count;++      error = ftc_snode_load( snode,+                              cache->manager,+                              gindex,+                              NULL );+      if ( error )+      {+        FTC_SNode_Free( snode, cache );+        snode = NULL;+      }+    }++  Exit:+    *psnode = snode;+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  ftc_snode_new( FTC_Node   *ftcpsnode,+                 FT_Pointer  ftcgquery,+                 FTC_Cache   cache )+  {+    FTC_SNode  *psnode = (FTC_SNode*)ftcpsnode;+    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;+++    return FTC_SNode_New( psnode, gquery, cache );+  }+++  FT_LOCAL_DEF( FT_Offset )+  ftc_snode_weight( FTC_Node   ftcsnode,+                    FTC_Cache  cache )+  {+    FTC_SNode  snode = (FTC_SNode)ftcsnode;+    FT_UInt    count = snode->count;+    FTC_SBit   sbit  = snode->sbits;+    FT_Int     pitch;+    FT_Offset  size;++    FT_UNUSED( cache );+++    FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE );++    /* the node itself */+    size = sizeof ( *snode );++    for ( ; count > 0; count--, sbit++ )+    {+      if ( sbit->buffer )+      {+        pitch = sbit->pitch;+        if ( pitch < 0 )+          pitch = -pitch;++        /* add the size of a given glyph image */+        size += pitch * sbit->height;+      }+    }++    return size;+  }+++#if 0++  FT_LOCAL_DEF( FT_Offset )+  FTC_SNode_Weight( FTC_SNode  snode )+  {+    return ftc_snode_weight( FTC_NODE( snode ), NULL );+  }++#endif /* 0 */+++  FT_LOCAL_DEF( FT_Bool )+  ftc_snode_compare( FTC_Node    ftcsnode,+                     FT_Pointer  ftcgquery,+                     FTC_Cache   cache )+  {+    FTC_SNode   snode  = (FTC_SNode)ftcsnode;+    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;+    FTC_GNode   gnode  = FTC_GNODE( snode );+    FT_UInt     gindex = gquery->gindex;+    FT_Bool     result;+++    result = FT_BOOL( gnode->family == gquery->family                    &&+                      (FT_UInt)( gindex - gnode->gindex ) < snode->count );+    if ( result )+    {+      /* check if we need to load the glyph bitmap now */+      FTC_SBit  sbit = snode->sbits + ( gindex - gnode->gindex );+++      /*+       *  The following code illustrates what to do when you want to+       *  perform operations that may fail within a lookup function.+       *+       *  Here, we want to load a small bitmap on-demand; we thus+       *  need to call the `ftc_snode_load' function which may return+       *  a non-zero error code only when we are out of memory (OOM).+       *+       *  The correct thing to do is to use @FTC_CACHE_TRYLOOP and+       *  @FTC_CACHE_TRYLOOP_END in order to implement a retry loop+       *  that is capable of flushing the cache incrementally when+       *  an OOM errors occur.+       *+       *  However, we need to `lock' the node before this operation to+       *  prevent it from being flushed within the loop.+       *+       *  When we exit the loop, we unlock the node, then check the `error'+       *  variable.  If it is non-zero, this means that the cache was+       *  completely flushed and that no usable memory was found to load+       *  the bitmap.+       *+       *  We then prefer to return a value of 0 (i.e., NO MATCH).  This+       *  ensures that the caller will try to allocate a new node.+       *  This operation consequently _fail_ and the lookup function+       *  returns the appropriate OOM error code.+       *+       *  Note that `buffer == NULL && width == 255' is a hack used to+       *  tag `unavailable' bitmaps in the array.  We should never try+       *  to load these.+       *+       */++      if ( sbit->buffer == NULL && sbit->width != 255 )+      {+        FT_ULong  size;+        FT_Error  error;+++        ftcsnode->ref_count++;  /* lock node to prevent flushing */+                                /* in retry loop                 */++        FTC_CACHE_TRYLOOP( cache )+        {+          error = ftc_snode_load( snode, cache->manager, gindex, &size );+        }+        FTC_CACHE_TRYLOOP_END();++        ftcsnode->ref_count--;  /* unlock the node */++        if ( error )+          result = 0;+        else+          cache->manager->cur_weight += size;+      }+    }++    return result;+  }+++  FT_LOCAL_DEF( FT_Bool )+  FTC_SNode_Compare( FTC_SNode   snode,+                     FTC_GQuery  gquery,+                     FTC_Cache   cache )+  {+    return ftc_snode_compare( FTC_NODE( snode ), gquery, cache );+  }+++/* END */
+ src/cache/ftcsbits.h view
@@ -0,0 +1,98 @@+/***************************************************************************/+/*                                                                         */+/*  ftcsbits.h                                                             */+/*                                                                         */+/*    A small-bitmap cache (specification).                                */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTCSBITS_H__+#define __FTCSBITS_H__+++#include <ft2build.h>+#include FT_CACHE_H+#include "ftcglyph.h"+++FT_BEGIN_HEADER++#define FTC_SBIT_ITEMS_PER_NODE  16++  typedef struct  FTC_SNodeRec_+  {+    FTC_GNodeRec  gnode;+    FT_UInt       count;+    FTC_SBitRec   sbits[FTC_SBIT_ITEMS_PER_NODE];++  } FTC_SNodeRec, *FTC_SNode;+++#define FTC_SNODE( x )         ( (FTC_SNode)( x ) )+#define FTC_SNODE_GINDEX( x )  FTC_GNODE( x )->gindex+#define FTC_SNODE_FAMILY( x )  FTC_GNODE( x )->family++  typedef FT_UInt+  (*FTC_SFamily_GetCountFunc)( FTC_Family   family,+                               FTC_Manager  manager );++  typedef FT_Error+  (*FTC_SFamily_LoadGlyphFunc)( FTC_Family   family,+                                FT_UInt      gindex,+                                FTC_Manager  manager,+                                FT_Face     *aface );++  typedef struct  FTC_SFamilyClassRec_+  {+    FTC_MruListClassRec        clazz;+    FTC_SFamily_GetCountFunc   family_get_count;+    FTC_SFamily_LoadGlyphFunc  family_load_glyph;++  } FTC_SFamilyClassRec;++  typedef const FTC_SFamilyClassRec*  FTC_SFamilyClass;++#define FTC_SFAMILY_CLASS( x )  ((FTC_SFamilyClass)(x))++#define FTC_CACHE__SFAMILY_CLASS( x )  \+          FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class )+++  FT_LOCAL( void )+  FTC_SNode_Free( FTC_SNode  snode,+                  FTC_Cache  cache );++  FT_LOCAL( FT_Error )+  FTC_SNode_New( FTC_SNode   *psnode,+                 FTC_GQuery   gquery,+                 FTC_Cache    cache );++#if 0+  FT_LOCAL( FT_ULong )+  FTC_SNode_Weight( FTC_SNode  inode );+#endif+++  FT_LOCAL( FT_Bool )+  FTC_SNode_Compare( FTC_SNode   snode,+                     FTC_GQuery  gquery,+                     FTC_Cache   cache );++  /* */++FT_END_HEADER++#endif /* __FTCSBITS_H__ */+++/* END */
+ src/cff/cff.c view
@@ -0,0 +1,30 @@+/***************************************************************************/+/*                                                                         */+/*  cff.c                                                                  */+/*                                                                         */+/*    FreeType OpenType driver component (body only).                      */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "cffpic.c"+#include "cffdrivr.c"+#include "cffparse.c"+#include "cffload.c"+#include "cffobjs.c"+#include "cffgload.c"+#include "cffcmap.c"++/* END */
+ src/cff/cffcmap.c view
@@ -0,0 +1,208 @@+/***************************************************************************/+/*                                                                         */+/*  cffcmap.c                                                              */+/*                                                                         */+/*    CFF character mapping table (cmap) support (body).                   */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "cffcmap.h"+#include "cffload.h"++#include "cfferrs.h"+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****           CFF STANDARD (AND EXPERT) ENCODING CMAPS            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_CALLBACK_DEF( FT_Error )+  cff_cmap_encoding_init( CFF_CMapStd  cmap )+  {+    TT_Face       face     = (TT_Face)FT_CMAP_FACE( cmap );+    CFF_Font      cff      = (CFF_Font)face->extra.data;+    CFF_Encoding  encoding = &cff->encoding;+++    cmap->gids  = encoding->codes;++    return 0;+  }+++  FT_CALLBACK_DEF( void )+  cff_cmap_encoding_done( CFF_CMapStd  cmap )+  {+    cmap->gids  = NULL;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  cff_cmap_encoding_char_index( CFF_CMapStd  cmap,+                                FT_UInt32    char_code )+  {+    FT_UInt  result = 0;+++    if ( char_code < 256 )+      result = cmap->gids[char_code];++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  cff_cmap_encoding_char_next( CFF_CMapStd   cmap,+                               FT_UInt32    *pchar_code )+  {+    FT_UInt    result    = 0;+    FT_UInt32  char_code = *pchar_code;+++    *pchar_code = 0;++    if ( char_code < 255 )+    {+      FT_UInt  code = (FT_UInt)(char_code + 1);+++      for (;;)+      {+        if ( code >= 256 )+          break;++        result = cmap->gids[code];+        if ( result != 0 )+        {+          *pchar_code = code;+          break;+        }++        code++;+      }+    }+    return result;+  }+++  FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec,+    sizeof ( CFF_CMapStdRec ),++    (FT_CMap_InitFunc)     cff_cmap_encoding_init,+    (FT_CMap_DoneFunc)     cff_cmap_encoding_done,+    (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,+    (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,++    NULL, NULL, NULL, NULL, NULL+  )+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****              CFF SYNTHETIC UNICODE ENCODING CMAP              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_CALLBACK_DEF( const char* )+  cff_sid_to_glyph_name( TT_Face  face,+                         FT_UInt  idx )+  {+    CFF_Font     cff     = (CFF_Font)face->extra.data;+    CFF_Charset  charset = &cff->charset;+    FT_UInt      sid     = charset->sids[idx];+++    return cff_index_get_sid_string( cff, sid );+  }+++  FT_CALLBACK_DEF( FT_Error )+  cff_cmap_unicode_init( PS_Unicodes  unicodes )+  {+    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );+    FT_Memory           memory  = FT_FACE_MEMORY( face );+    CFF_Font            cff     = (CFF_Font)face->extra.data;+    CFF_Charset         charset = &cff->charset;+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;+++    /* can't build Unicode map for CID-keyed font */+    /* because we don't know glyph names.         */+    if ( !charset->sids )+      return CFF_Err_No_Unicode_Glyph_Name;++    return psnames->unicodes_init( memory,+                                   unicodes,+                                   cff->num_glyphs,+                                   (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,+                                   (PS_FreeGlyphNameFunc)NULL,+                                   (FT_Pointer)face );+  }+++  FT_CALLBACK_DEF( void )+  cff_cmap_unicode_done( PS_Unicodes  unicodes )+  {+    FT_Face    face   = FT_CMAP_FACE( unicodes );+    FT_Memory  memory = FT_FACE_MEMORY( face );+++    FT_FREE( unicodes->maps );+    unicodes->num_maps = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  cff_cmap_unicode_char_index( PS_Unicodes  unicodes,+                               FT_UInt32    char_code )+  {+    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );+    CFF_Font            cff     = (CFF_Font)face->extra.data;+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;+++    return psnames->unicodes_char_index( unicodes, char_code );+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  cff_cmap_unicode_char_next( PS_Unicodes  unicodes,+                              FT_UInt32   *pchar_code )+  {+    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );+    CFF_Font            cff     = (CFF_Font)face->extra.data;+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;+++    return psnames->unicodes_char_next( unicodes, pchar_code );+  }+++  FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec,+    sizeof ( PS_UnicodesRec ),++    (FT_CMap_InitFunc)     cff_cmap_unicode_init,+    (FT_CMap_DoneFunc)     cff_cmap_unicode_done,+    (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,+    (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,++    NULL, NULL, NULL, NULL, NULL+  )++/* END */
+ src/cff/cffcmap.h view
@@ -0,0 +1,67 @@+/***************************************************************************/+/*                                                                         */+/*  cffcmap.h                                                              */+/*                                                                         */+/*    CFF character mapping table (cmap) support (specification).          */+/*                                                                         */+/*  Copyright 2002, 2003, 2006 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFCMAP_H__+#define __CFFCMAP_H__++#include "cffobjs.h"++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* standard (and expert) encoding cmaps */+  typedef struct CFF_CMapStdRec_*  CFF_CMapStd;++  typedef struct  CFF_CMapStdRec_+  {+    FT_CMapRec  cmap;+    FT_UShort*  gids;   /* up to 256 elements */++  } CFF_CMapStdRec;+++  FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec)+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****               CFF SYNTHETIC UNICODE ENCODING CMAP             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* unicode (synthetic) cmaps */++  FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec)+++FT_END_HEADER++#endif /* __CFFCMAP_H__ */+++/* END */
+ src/cff/cffdrivr.c view
@@ -0,0 +1,671 @@+/***************************************************************************/+/*                                                                         */+/*  cffdrivr.c                                                             */+/*                                                                         */+/*    OpenType font driver implementation (body).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include FT_SERVICE_CID_H+#include FT_SERVICE_POSTSCRIPT_INFO_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_TT_CMAP_H++#include "cffdrivr.h"+#include "cffgload.h"+#include "cffload.h"+#include "cffcmap.h"+#include "cffparse.h"++#include "cfferrs.h"+#include "cffpic.h"++#include FT_SERVICE_XFREE86_NAME_H+#include FT_SERVICE_GLYPH_DICT_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cffdriver+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                          F A C E S                              ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#undef  PAIR_TAG+#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \+                                     (FT_ULong)right        )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_get_kerning                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A driver method used to return the kerning vector between two      */+  /*    glyphs of the same face.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to the source face object.                 */+  /*                                                                       */+  /*    left_glyph  :: The index of the left glyph in the kern pair.       */+  /*                                                                       */+  /*    right_glyph :: The index of the right glyph in the kern pair.      */+  /*                                                                       */+  /* <Output>                                                              */+  /*    kerning     :: The kerning vector.  This is in font units for      */+  /*                   scalable formats, and in pixels for fixed-sizes     */+  /*                   formats.                                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only horizontal layouts (left-to-right & right-to-left) are        */+  /*    supported by this function.  Other layouts, or more sophisticated  */+  /*    kernings, are out of scope of this method (the basic driver        */+  /*    interface is meant to be simple).                                  */+  /*                                                                       */+  /*    They can be implemented by format-specific interfaces.             */+  /*                                                                       */+  FT_CALLBACK_DEF( FT_Error )+  cff_get_kerning( FT_Face     ttface,          /* TT_Face */+                   FT_UInt     left_glyph,+                   FT_UInt     right_glyph,+                   FT_Vector*  kerning )+  {+    TT_Face       face = (TT_Face)ttface;+    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;+++    kerning->x = 0;+    kerning->y = 0;++    if ( sfnt )+      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );++    return CFF_Err_Ok;+  }+++#undef PAIR_TAG+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Load_Glyph                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A driver method used to load a glyph within a given glyph slot.    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    slot        :: A handle to the target slot object where the glyph  */+  /*                   will be loaded.                                     */+  /*                                                                       */+  /*    size        :: A handle to the source face size at which the glyph */+  /*                   must be scaled, loaded, etc.                        */+  /*                                                                       */+  /*    glyph_index :: The index of the glyph in the font file.            */+  /*                                                                       */+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */+  /*                   FT_LOAD_??? constants can be used to control the    */+  /*                   glyph loading process (e.g., whether the outline    */+  /*                   should be scaled, whether to load bitmaps or not,   */+  /*                   whether to hint the outline, etc).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_CALLBACK_DEF( FT_Error )+  Load_Glyph( FT_GlyphSlot  cffslot,        /* CFF_GlyphSlot */+              FT_Size       cffsize,        /* CFF_Size      */+              FT_UInt       glyph_index,+              FT_Int32      load_flags )+  {+    FT_Error       error;+    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;+    CFF_Size       size = (CFF_Size)cffsize;+++    if ( !slot )+      return CFF_Err_Invalid_Slot_Handle;++    /* check whether we want a scaled outline or bitmap */+    if ( !size )+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;++    /* reset the size object if necessary */+    if ( load_flags & FT_LOAD_NO_SCALE )+      size = NULL;++    if ( size )+    {+      /* these two objects must have the same parent */+      if ( cffsize->face != cffslot->face )+        return CFF_Err_Invalid_Face_Handle;+    }++    /* now load the glyph outline if necessary */+    error = cff_slot_load( slot, size, glyph_index, load_flags );++    /* force drop-out mode to 2 - irrelevant now */+    /* slot->outline.dropout_mode = 2; */++    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  cff_get_advances( FT_Face    face,+                    FT_UInt    start,+                    FT_UInt    count,+                    FT_Int32   flags,+                    FT_Fixed*  advances )+  {+    FT_UInt       nn;+    FT_Error      error = CFF_Err_Ok;+    FT_GlyphSlot  slot  = face->glyph;+++    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;++    for ( nn = 0; nn < count; nn++ )+    {+      error = Load_Glyph( slot, face->size, start + nn, flags );+      if ( error )+        break;++      advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )+                     ? slot->linearVertAdvance+                     : slot->linearHoriAdvance;+    }++    return error;+  }+++  /*+   *  GLYPH DICT SERVICE+   *+   */++  static FT_Error+  cff_get_glyph_name( CFF_Face    face,+                      FT_UInt     glyph_index,+                      FT_Pointer  buffer,+                      FT_UInt     buffer_max )+  {+    CFF_Font    font   = (CFF_Font)face->extra.data;+    FT_String*  gname;+    FT_UShort   sid;+    FT_Error    error;+++    if ( !font->psnames )+    {+      FT_ERROR(( "cff_get_glyph_name:"+                 " cannot get glyph name from CFF & CEF fonts\n"+                 "                   "+                 " without the `PSNames' module\n" ));+      error = CFF_Err_Unknown_File_Format;+      goto Exit;+    }++    /* first, locate the sid in the charset table */+    sid = font->charset.sids[glyph_index];++    /* now, lookup the name itself */+    gname = cff_index_get_sid_string( font, sid );++    if ( gname )+      FT_STRCPYN( buffer, gname, buffer_max );++    error = CFF_Err_Ok;++  Exit:+    return error;+  }+++  static FT_UInt+  cff_get_name_index( CFF_Face    face,+                      FT_String*  glyph_name )+  {+    CFF_Font            cff;+    CFF_Charset         charset;+    FT_Service_PsCMaps  psnames;+    FT_String*          name;+    FT_UShort           sid;+    FT_UInt             i;+++    cff     = (CFF_FontRec *)face->extra.data;+    charset = &cff->charset;++    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );+    if ( !psnames )+      return 0;++    for ( i = 0; i < cff->num_glyphs; i++ )+    {+      sid = charset->sids[i];++      if ( sid > 390 )+        name = cff_index_get_string( cff, sid - 391 );+      else+        name = (FT_String *)psnames->adobe_std_strings( sid );++      if ( !name )+        continue;++      if ( !ft_strcmp( glyph_name, name ) )+        return i;+    }++    return 0;+  }+++  FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,+    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,+    (FT_GlyphDict_NameIndexFunc)cff_get_name_index+  )+++  /*+   *  POSTSCRIPT INFO SERVICE+   *+   */++  static FT_Int+  cff_ps_has_glyph_names( FT_Face  face )+  {+    return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;+  }+++  static FT_Error+  cff_ps_get_font_info( CFF_Face         face,+                        PS_FontInfoRec*  afont_info )+  {+    CFF_Font  cff   = (CFF_Font)face->extra.data;+    FT_Error  error = CFF_Err_Ok;+++    if ( cff && cff->font_info == NULL )+    {+      CFF_FontRecDict  dict   = &cff->top_font.font_dict;+      PS_FontInfoRec  *font_info;+      FT_Memory        memory = face->root.memory;+++      if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )+        goto Fail;++      font_info->version     = cff_index_get_sid_string( cff,+                                                         dict->version );+      font_info->notice      = cff_index_get_sid_string( cff,+                                                         dict->notice );+      font_info->full_name   = cff_index_get_sid_string( cff,+                                                         dict->full_name );+      font_info->family_name = cff_index_get_sid_string( cff,+                                                         dict->family_name );+      font_info->weight      = cff_index_get_sid_string( cff,+                                                         dict->weight );+      font_info->italic_angle        = dict->italic_angle;+      font_info->is_fixed_pitch      = dict->is_fixed_pitch;+      font_info->underline_position  = (FT_Short)dict->underline_position;+      font_info->underline_thickness = (FT_Short)dict->underline_thickness;++      cff->font_info = font_info;+    }++    if ( cff )+      *afont_info = *cff->font_info;++  Fail:+    return error;+  }+++  FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,+    (PS_GetFontInfoFunc)   cff_ps_get_font_info,+    (PS_GetFontExtraFunc)  NULL,+    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,+    (PS_GetFontPrivateFunc)NULL         /* unsupported with CFF fonts */+  )+++  /*+   *  POSTSCRIPT NAME SERVICE+   *+   */++  static const char*+  cff_get_ps_name( CFF_Face  face )+  {+    CFF_Font  cff = (CFF_Font)face->extra.data;+++    return (const char*)cff->font_name;+  }+++  FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,+    (FT_PsName_GetFunc)cff_get_ps_name+  )+++  /*+   * TT CMAP INFO+   *+   * If the charmap is a synthetic Unicode encoding cmap or+   * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO+   * service defined in SFNT module.+   *+   * Otherwise call the service function in the sfnt module.+   *+   */+  static FT_Error+  cff_get_cmap_info( FT_CharMap    charmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_CMap   cmap  = FT_CMAP( charmap );+    FT_Error  error = CFF_Err_Ok;+    FT_Face    face    = FT_CMAP_FACE( cmap );+    FT_Library library = FT_FACE_LIBRARY( face );+++    cmap_info->language = 0;+    cmap_info->format   = 0;++    if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&+         cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET  )+    {+      FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );+      FT_Service_TTCMaps  service =+        (FT_Service_TTCMaps)ft_module_get_service( sfnt,+                                                   FT_SERVICE_ID_TT_CMAP );+++      if ( service && service->get_cmap_info )+        error = service->get_cmap_info( charmap, cmap_info );+    }++    return error;+  }+++  FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,+    (TT_CMap_Info_GetFunc)cff_get_cmap_info+  )+++  /*+   *  CID INFO SERVICE+   *+   */+  static FT_Error+  cff_get_ros( CFF_Face      face,+               const char*  *registry,+               const char*  *ordering,+               FT_Int       *supplement )+  {+    FT_Error  error = CFF_Err_Ok;+    CFF_Font  cff   = (CFF_Font)face->extra.data;+++    if ( cff )+    {+      CFF_FontRecDict  dict = &cff->top_font.font_dict;+++      if ( dict->cid_registry == 0xFFFFU )+      {+        error = CFF_Err_Invalid_Argument;+        goto Fail;+      }++      if ( registry )+      {+        if ( cff->registry == NULL )+          cff->registry = cff_index_get_sid_string( cff,+                                                    dict->cid_registry );+        *registry = cff->registry;+      }+      +      if ( ordering )+      {+        if ( cff->ordering == NULL )+          cff->ordering = cff_index_get_sid_string( cff,+                                                    dict->cid_ordering );+        *ordering = cff->ordering;+      }++      /*+       * XXX: According to Adobe TechNote #5176, the supplement in CFF+       *      can be a real number. We truncate it to fit public API+       *      since freetype-2.3.6.+       */+      if ( supplement )+      {+        if ( dict->cid_supplement < FT_INT_MIN ||+             dict->cid_supplement > FT_INT_MAX )+          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",+                      dict->cid_supplement ));+        *supplement = (FT_Int)dict->cid_supplement;+      }+    }+      +  Fail:+    return error;+  }+++  static FT_Error+  cff_get_is_cid( CFF_Face  face,+                  FT_Bool  *is_cid )+  {+    FT_Error  error = CFF_Err_Ok;+    CFF_Font  cff   = (CFF_Font)face->extra.data;+++    *is_cid = 0;++    if ( cff )+    {+      CFF_FontRecDict  dict = &cff->top_font.font_dict;+++      if ( dict->cid_registry != 0xFFFFU )+        *is_cid = 1;+    }++    return error;+  }+++  static FT_Error+  cff_get_cid_from_glyph_index( CFF_Face  face,+                                FT_UInt   glyph_index,+                                FT_UInt  *cid )+  {+    FT_Error  error = CFF_Err_Ok;+    CFF_Font  cff;+++    cff = (CFF_Font)face->extra.data;++    if ( cff )+    {+      FT_UInt          c;+      CFF_FontRecDict  dict = &cff->top_font.font_dict;+++      if ( dict->cid_registry == 0xFFFFU )+      {+        error = CFF_Err_Invalid_Argument;+        goto Fail;+      }++      if ( glyph_index > cff->num_glyphs )+      {+        error = CFF_Err_Invalid_Argument;+        goto Fail;+      }++      c = cff->charset.sids[glyph_index];++      if ( cid )+        *cid = c;+    }++  Fail:+    return error;+  }+++  FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,+    (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,+    (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,+    (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index+  )+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                D R I V E R  I N T E R F A C E                   ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES+  FT_DEFINE_SERVICEDESCREC6(cff_services,+    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_GLYPH_DICT,           &FT_CFF_SERVICE_GLYPH_DICT_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,+    FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET+  )+#else+  FT_DEFINE_SERVICEDESCREC5(cff_services,+    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,+    FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET+  )+#endif++  FT_CALLBACK_DEF( FT_Module_Interface )+  cff_get_interface( FT_Module    driver,       /* CFF_Driver */+                     const char*  module_interface )+  {+    FT_Module            sfnt;+    FT_Module_Interface  result;+++    result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );+    if ( result != NULL )+      return  result;++    if ( !driver )+      return NULL;++    /* we pass our request to the `sfnt' module */+    sfnt = FT_Get_Module( driver->library, "sfnt" );++    return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;+  }+++  /* The FT_DriverInterface structure is defined in ftdriver.h. */++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+#define CFF_SIZE_SELECT cff_size_select+#else+#define CFF_SIZE_SELECT 0+#endif++  FT_DEFINE_DRIVER(cff_driver_class,+      FT_MODULE_FONT_DRIVER       |+      FT_MODULE_DRIVER_SCALABLE   |+      FT_MODULE_DRIVER_HAS_HINTER,++      sizeof( CFF_DriverRec ),+      "cff",+      0x10000L,+      0x20000L,++      0,   /* module-specific interface */++      cff_driver_init,+      cff_driver_done,+      cff_get_interface,++    /* now the specific driver fields */+    sizeof( TT_FaceRec ),+    sizeof( CFF_SizeRec ),+    sizeof( CFF_GlyphSlotRec ),++    cff_face_init,+    cff_face_done,+    cff_size_init,+    cff_size_done,+    cff_slot_init,+    cff_slot_done,++    ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    Load_Glyph,++    cff_get_kerning,+    0,                      /* FT_Face_AttachFunc      */+    cff_get_advances,       /* FT_Face_GetAdvancesFunc */++    cff_size_request,++    CFF_SIZE_SELECT+  )+++/* END */
+ src/cff/cffdrivr.h view
@@ -0,0 +1,38 @@+/***************************************************************************/+/*                                                                         */+/*  cffdrivr.h                                                             */+/*                                                                         */+/*    High-level OpenType driver interface (specification).                */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFDRIVER_H__+#define __CFFDRIVER_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER+++  FT_DECLARE_DRIVER( cff_driver_class )+++FT_END_HEADER++#endif /* __CFFDRIVER_H__ */+++/* END */
+ src/cff/cfferrs.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  cfferrs.h                                                              */+/*                                                                         */+/*    CFF error codes (specification only).                                */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the CFF error enumeration constants.      */+  /*                                                                       */+  /*************************************************************************/++#ifndef __CFFERRS_H__+#define __CFFERRS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  CFF_Err_+#define FT_ERR_BASE    FT_Mod_Err_CFF+++#include FT_ERRORS_H++#endif /* __CFFERRS_H__ */+++/* END */
+ src/cff/cffgload.c view
@@ -0,0 +1,2972 @@+/***************************************************************************/+/*                                                                         */+/*  cffgload.c                                                             */+/*                                                                         */+/*    OpenType Glyph Loader (body).                                        */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include FT_OUTLINE_H++#include "cffobjs.h"+#include "cffload.h"+#include "cffgload.h"++#include "cfferrs.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cffgload+++  typedef enum  CFF_Operator_+  {+    cff_op_unknown = 0,++    cff_op_rmoveto,+    cff_op_hmoveto,+    cff_op_vmoveto,++    cff_op_rlineto,+    cff_op_hlineto,+    cff_op_vlineto,++    cff_op_rrcurveto,+    cff_op_hhcurveto,+    cff_op_hvcurveto,+    cff_op_rcurveline,+    cff_op_rlinecurve,+    cff_op_vhcurveto,+    cff_op_vvcurveto,++    cff_op_flex,+    cff_op_hflex,+    cff_op_hflex1,+    cff_op_flex1,++    cff_op_endchar,++    cff_op_hstem,+    cff_op_vstem,+    cff_op_hstemhm,+    cff_op_vstemhm,++    cff_op_hintmask,+    cff_op_cntrmask,+    cff_op_dotsection,  /* deprecated, acts as no-op */++    cff_op_abs,+    cff_op_add,+    cff_op_sub,+    cff_op_div,+    cff_op_neg,+    cff_op_random,+    cff_op_mul,+    cff_op_sqrt,++    cff_op_blend,++    cff_op_drop,+    cff_op_exch,+    cff_op_index,+    cff_op_roll,+    cff_op_dup,++    cff_op_put,+    cff_op_get,+    cff_op_store,+    cff_op_load,++    cff_op_and,+    cff_op_or,+    cff_op_not,+    cff_op_eq,+    cff_op_ifelse,++    cff_op_callsubr,+    cff_op_callgsubr,+    cff_op_return,++    /* Type 1 opcodes: invalid but seen in real life */+    cff_op_hsbw,+    cff_op_closepath,+    cff_op_callothersubr,+    cff_op_pop,+    cff_op_seac,+    cff_op_sbw,+    cff_op_setcurrentpoint,++    /* do not remove */+    cff_op_max++  } CFF_Operator;+++#define CFF_COUNT_CHECK_WIDTH  0x80+#define CFF_COUNT_EXACT        0x40+#define CFF_COUNT_CLEAR_STACK  0x20++  /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are  */+  /* used for checking the width and requested numbers of arguments    */+  /* only; they are set to zero afterwards                             */++  /* the other two flags are informative only and unused currently     */++  static const FT_Byte  cff_argument_counts[] =+  {+    0,  /* unknown */++    2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */+    1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,+    1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,++    0 | CFF_COUNT_CLEAR_STACK, /* rlineto */+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,++    0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,+    0 | CFF_COUNT_CLEAR_STACK,++    13, /* flex */+    7,+    9,+    11,++    0 | CFF_COUNT_CHECK_WIDTH, /* endchar */++    2 | CFF_COUNT_CHECK_WIDTH, /* hstem */+    2 | CFF_COUNT_CHECK_WIDTH,+    2 | CFF_COUNT_CHECK_WIDTH,+    2 | CFF_COUNT_CHECK_WIDTH,++    0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */+    0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */+    0, /* dotsection */++    1, /* abs */+    2,+    2,+    2,+    1,+    0,+    2,+    1,++    1, /* blend */++    1, /* drop */+    2,+    1,+    2,+    1,++    2, /* put */+    1,+    4,+    3,++    2, /* and */+    2,+    1,+    2,+    4,++    1, /* callsubr */+    1,+    0,++    2, /* hsbw */+    0,+    0,+    0,+    5, /* seac */+    4, /* sbw */+    2  /* setcurrentpoint */+  };+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /**********                                                      *********/+  /**********                                                      *********/+  /**********             GENERIC CHARSTRING PARSING               *********/+  /**********                                                      *********/+  /**********                                                      *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_builder_init                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given glyph builder.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    builder :: A pointer to the glyph builder to initialize.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face    :: The current face object.                                */+  /*                                                                       */+  /*    size    :: The current size object.                                */+  /*                                                                       */+  /*    glyph   :: The current glyph object.                               */+  /*                                                                       */+  /*    hinting :: Whether hinting is active.                              */+  /*                                                                       */+  static void+  cff_builder_init( CFF_Builder*   builder,+                    TT_Face        face,+                    CFF_Size       size,+                    CFF_GlyphSlot  glyph,+                    FT_Bool        hinting )+  {+    builder->path_begun  = 0;+    builder->load_points = 1;++    builder->face   = face;+    builder->glyph  = glyph;+    builder->memory = face->root.memory;++    if ( glyph )+    {+      FT_GlyphLoader  loader = glyph->root.internal->loader;+++      builder->loader  = loader;+      builder->base    = &loader->base.outline;+      builder->current = &loader->current.outline;+      FT_GlyphLoader_Rewind( loader );++      builder->hints_globals = 0;+      builder->hints_funcs   = 0;++      if ( hinting && size )+      {+        CFF_Internal  internal = (CFF_Internal)size->root.internal;+++        builder->hints_globals = (void *)internal->topfont;+        builder->hints_funcs   = glyph->root.internal->glyph_hints;+      }+    }++    builder->pos_x = 0;+    builder->pos_y = 0;++    builder->left_bearing.x = 0;+    builder->left_bearing.y = 0;+    builder->advance.x      = 0;+    builder->advance.y      = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_builder_done                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a given glyph builder.  Its contents can still be used   */+  /*    after the call, but the function saves important information       */+  /*    within the corresponding glyph slot.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    builder :: A pointer to the glyph builder to finalize.             */+  /*                                                                       */+  static void+  cff_builder_done( CFF_Builder*  builder )+  {+    CFF_GlyphSlot  glyph = builder->glyph;+++    if ( glyph )+      glyph->root.outline = *builder->base;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_compute_bias                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the bias value in dependence of the number of glyph       */+  /*    subroutines.                                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    in_charstring_type :: The `CharstringType' value of the top DICT   */+  /*                          dictionary.                                  */+  /*                                                                       */+  /*    num_subrs          :: The number of glyph subroutines.             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The bias value.                                                    */+  static FT_Int+  cff_compute_bias( FT_Int   in_charstring_type,+                    FT_UInt  num_subrs )+  {+    FT_Int  result;+++    if ( in_charstring_type == 1 )+      result = 0;+    else if ( num_subrs < 1240 )+      result = 107;+    else if ( num_subrs < 33900U )+      result = 1131;+    else+      result = 32768U;++    return result;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_decoder_init                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given glyph decoder.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    decoder :: A pointer to the glyph builder to initialize.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face      :: The current face object.                              */+  /*                                                                       */+  /*    size      :: The current size object.                              */+  /*                                                                       */+  /*    slot      :: The current glyph object.                             */+  /*                                                                       */+  /*    hinting   :: Whether hinting is active.                            */+  /*                                                                       */+  /*    hint_mode :: The hinting mode.                                     */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  cff_decoder_init( CFF_Decoder*    decoder,+                    TT_Face         face,+                    CFF_Size        size,+                    CFF_GlyphSlot   slot,+                    FT_Bool         hinting,+                    FT_Render_Mode  hint_mode )+  {+    CFF_Font  cff = (CFF_Font)face->extra.data;+++    /* clear everything */+    FT_MEM_ZERO( decoder, sizeof ( *decoder ) );++    /* initialize builder */+    cff_builder_init( &decoder->builder, face, size, slot, hinting );++    /* initialize Type2 decoder */+    decoder->cff          = cff;+    decoder->num_globals  = cff->global_subrs_index.count;+    decoder->globals      = cff->global_subrs;+    decoder->globals_bias = cff_compute_bias(+                              cff->top_font.font_dict.charstring_type,+                              decoder->num_globals );++    decoder->hint_mode    = hint_mode;+  }+++  /* this function is used to select the subfont */+  /* and the locals subrs array                  */+  FT_LOCAL_DEF( FT_Error )+  cff_decoder_prepare( CFF_Decoder*  decoder,+                       CFF_Size      size,+                       FT_UInt       glyph_index )+  {+    CFF_Builder  *builder = &decoder->builder;+    CFF_Font      cff     = (CFF_Font)builder->face->extra.data;+    CFF_SubFont   sub     = &cff->top_font;+    FT_Error      error   = CFF_Err_Ok;+++    /* manage CID fonts */+    if ( cff->num_subfonts )+    {+      FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );+++      if ( fd_index >= cff->num_subfonts )+      {+        FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));+        error = CFF_Err_Invalid_File_Format;+        goto Exit;+      }++      FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));++      sub = cff->subfonts[fd_index];++      if ( builder->hints_funcs && size )+      {+        CFF_Internal  internal = (CFF_Internal)size->root.internal;+++        /* for CFFs without subfonts, this value has already been set */+        builder->hints_globals = (void *)internal->subfonts[fd_index];+      }+    }+#ifdef FT_DEBUG_LEVEL_TRACE+    else+      FT_TRACE3(( "glyph index %d:\n", glyph_index ));+#endif++    decoder->num_locals    = sub->local_subrs_index.count;+    decoder->locals        = sub->local_subrs;+    decoder->locals_bias   = cff_compute_bias(+                               decoder->cff->top_font.font_dict.charstring_type,+                               decoder->num_locals );++    decoder->glyph_width   = sub->private_dict.default_width;+    decoder->nominal_width = sub->private_dict.nominal_width;++  Exit:+    return error;+  }+++  /* check that there is enough space for `count' more points */+  static FT_Error+  check_points( CFF_Builder*  builder,+                FT_Int        count )+  {+    return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );+  }+++  /* add a new point, do not check space */+  static void+  cff_builder_add_point( CFF_Builder*  builder,+                         FT_Pos        x,+                         FT_Pos        y,+                         FT_Byte       flag )+  {+    FT_Outline*  outline = builder->current;+++    if ( builder->load_points )+    {+      FT_Vector*  point   = outline->points + outline->n_points;+      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;+++      point->x = x >> 16;+      point->y = y >> 16;+      *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );+    }++    outline->n_points++;+  }+++  /* check space for a new on-curve point, then add it */+  static FT_Error+  cff_builder_add_point1( CFF_Builder*  builder,+                          FT_Pos        x,+                          FT_Pos        y )+  {+    FT_Error  error;+++    error = check_points( builder, 1 );+    if ( !error )+      cff_builder_add_point( builder, x, y, 1 );++    return error;+  }+++  /* check space for a new contour, then add it */+  static FT_Error+  cff_builder_add_contour( CFF_Builder*  builder )+  {+    FT_Outline*  outline = builder->current;+    FT_Error     error;+++    if ( !builder->load_points )+    {+      outline->n_contours++;+      return CFF_Err_Ok;+    }++    error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );+    if ( !error )+    {+      if ( outline->n_contours > 0 )+        outline->contours[outline->n_contours - 1] =+          (short)( outline->n_points - 1 );++      outline->n_contours++;+    }++    return error;+  }+++  /* if a path was begun, add its first on-curve point */+  static FT_Error+  cff_builder_start_point( CFF_Builder*  builder,+                           FT_Pos        x,+                           FT_Pos        y )+  {+    FT_Error  error = CFF_Err_Ok;+++    /* test whether we are building a new contour */+    if ( !builder->path_begun )+    {+      builder->path_begun = 1;+      error = cff_builder_add_contour( builder );+      if ( !error )+        error = cff_builder_add_point1( builder, x, y );+    }++    return error;+  }+++  /* close the current contour */+  static void+  cff_builder_close_contour( CFF_Builder*  builder )+  {+    FT_Outline*  outline = builder->current;+    FT_Int       first;+++    if ( !outline )+      return;++    first = outline->n_contours <= 1+            ? 0 : outline->contours[outline->n_contours - 2] + 1;++    /* We must not include the last point in the path if it */+    /* is located on the first point.                       */+    if ( outline->n_points > 1 )+    {+      FT_Vector*  p1      = outline->points + first;+      FT_Vector*  p2      = outline->points + outline->n_points - 1;+      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;+++      /* `delete' last point only if it coincides with the first    */+      /* point and if it is not a control point (which can happen). */+      if ( p1->x == p2->x && p1->y == p2->y )+        if ( *control == FT_CURVE_TAG_ON )+          outline->n_points--;+    }++    if ( outline->n_contours > 0 )+    {+      /* Don't add contours only consisting of one point, i.e., */+      /* check whether begin point and last point are the same. */+      if ( first == outline->n_points - 1 )+      {+        outline->n_contours--;+        outline->n_points--;+      }+      else+        outline->contours[outline->n_contours - 1] =+          (short)( outline->n_points - 1 );+    }+  }+++  static FT_Int+  cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,+                                   FT_Int    charcode )+  {+    FT_UInt    n;+    FT_UShort  glyph_sid;+++    /* CID-keyed fonts don't have glyph names */+    if ( !cff->charset.sids )+      return -1;++    /* check range of standard char code */+    if ( charcode < 0 || charcode > 255 )+      return -1;++    /* Get code to SID mapping from `cff_standard_encoding'. */+    glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );++    for ( n = 0; n < cff->num_glyphs; n++ )+    {+      if ( cff->charset.sids[n] == glyph_sid )+        return n;+    }++    return -1;+  }+++  static FT_Error+  cff_get_glyph_data( TT_Face    face,+                      FT_UInt    glyph_index,+                      FT_Byte**  pointer,+                      FT_ULong*  length )+  {+#ifdef FT_CONFIG_OPTION_INCREMENTAL+    /* For incremental fonts get the character data using the */+    /* callback function.                                     */+    if ( face->root.internal->incremental_interface )+    {+      FT_Data   data;+      FT_Error  error =+                  face->root.internal->incremental_interface->funcs->get_glyph_data(+                    face->root.internal->incremental_interface->object,+                    glyph_index, &data );+++      *pointer = (FT_Byte*)data.pointer;+      *length = data.length;++      return error;+    }+    else+#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    {+      CFF_Font  cff  = (CFF_Font)(face->extra.data);+++      return cff_index_access_element( &cff->charstrings_index, glyph_index,+                                       pointer, length );+    }+  }+++  static void+  cff_free_glyph_data( TT_Face    face,+                       FT_Byte**  pointer,+                       FT_ULong   length )+  {+#ifndef FT_CONFIG_OPTION_INCREMENTAL+    FT_UNUSED( length );+#endif++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    /* For incremental fonts get the character data using the */+    /* callback function.                                     */+    if ( face->root.internal->incremental_interface )+    {+      FT_Data data;+++      data.pointer = *pointer;+      data.length  = length;++      face->root.internal->incremental_interface->funcs->free_glyph_data(+        face->root.internal->incremental_interface->object, &data );+    }+    else+#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    {+      CFF_Font  cff = (CFF_Font)(face->extra.data);+++      cff_index_forget_element( &cff->charstrings_index, pointer );+    }+  }+++  static FT_Error+  cff_operator_seac( CFF_Decoder*  decoder,+                     FT_Pos        asb,+                     FT_Pos        adx,+                     FT_Pos        ady,+                     FT_Int        bchar,+                     FT_Int        achar )+  {+    FT_Error      error;+    CFF_Builder*  builder = &decoder->builder;+    FT_Int        bchar_index, achar_index;+    TT_Face       face = decoder->builder.face;+    FT_Vector     left_bearing, advance;+    FT_Byte*      charstring;+    FT_ULong      charstring_len;+    FT_Pos        glyph_width;+++    if ( decoder->seac )+    {+      FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));+      return CFF_Err_Syntax_Error;+    }++    adx += decoder->builder.left_bearing.x;+    ady += decoder->builder.left_bearing.y;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    /* Incremental fonts don't necessarily have valid charsets.        */+    /* They use the character code, not the glyph index, in this case. */+    if ( face->root.internal->incremental_interface )+    {+      bchar_index = bchar;+      achar_index = achar;+    }+    else+#endif /* FT_CONFIG_OPTION_INCREMENTAL */+    {+      CFF_Font cff = (CFF_Font)(face->extra.data);+++      bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );+      achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );+    }++    if ( bchar_index < 0 || achar_index < 0 )+    {+      FT_ERROR(( "cff_operator_seac:"+                 " invalid seac character code arguments\n" ));+      return CFF_Err_Syntax_Error;+    }++    /* If we are trying to load a composite glyph, do not load the */+    /* accent character and return the array of subglyphs.         */+    if ( builder->no_recurse )+    {+      FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;+      FT_GlyphLoader  loader = glyph->internal->loader;+      FT_SubGlyph     subg;+++      /* reallocate subglyph array if necessary */+      error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );+      if ( error )+        goto Exit;++      subg = loader->current.subglyphs;++      /* subglyph 0 = base character */+      subg->index = bchar_index;+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |+                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;+      subg->arg1  = 0;+      subg->arg2  = 0;+      subg++;++      /* subglyph 1 = accent character */+      subg->index = achar_index;+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;+      subg->arg1  = (FT_Int)( adx >> 16 );+      subg->arg2  = (FT_Int)( ady >> 16 );++      /* set up remaining glyph fields */+      glyph->num_subglyphs = 2;+      glyph->subglyphs     = loader->base.subglyphs;+      glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;++      loader->current.num_subglyphs = 2;+    }++    FT_GlyphLoader_Prepare( builder->loader );++    /* First load `bchar' in builder */+    error = cff_get_glyph_data( face, bchar_index,+                                &charstring, &charstring_len );+    if ( !error )+    {+      /* the seac operator must not be nested */+      decoder->seac = TRUE;+      error = cff_decoder_parse_charstrings( decoder, charstring,+                                             charstring_len );+      decoder->seac = FALSE;++      cff_free_glyph_data( face, &charstring, charstring_len );++      if ( error )+        goto Exit;+    }++    /* Save the left bearing, advance and glyph width of the base */+    /* character as they will be erased by the next load.         */++    left_bearing = builder->left_bearing;+    advance      = builder->advance;+    glyph_width  = decoder->glyph_width;++    builder->left_bearing.x = 0;+    builder->left_bearing.y = 0;++    builder->pos_x = adx - asb;+    builder->pos_y = ady;++    /* Now load `achar' on top of the base outline. */+    error = cff_get_glyph_data( face, achar_index,+                                &charstring, &charstring_len );+    if ( !error )+    {+      /* the seac operator must not be nested */+      decoder->seac = TRUE;+      error = cff_decoder_parse_charstrings( decoder, charstring,+                                             charstring_len );+      decoder->seac = FALSE;++      cff_free_glyph_data( face, &charstring, charstring_len );++      if ( error )+        goto Exit;+    }++    /* Restore the left side bearing, advance and glyph width */+    /* of the base character.                                 */+    builder->left_bearing = left_bearing;+    builder->advance      = advance;+    decoder->glyph_width  = glyph_width;++    builder->pos_x = 0;+    builder->pos_y = 0;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cff_decoder_parse_charstrings                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parses a given Type 2 charstrings program.                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    decoder         :: The current Type 1 decoder.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    charstring_base :: The base of the charstring stream.              */+  /*                                                                       */+  /*    charstring_len  :: The length in bytes of the charstring stream.   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  cff_decoder_parse_charstrings( CFF_Decoder*  decoder,+                                 FT_Byte*      charstring_base,+                                 FT_ULong      charstring_len )+  {+    FT_Error           error;+    CFF_Decoder_Zone*  zone;+    FT_Byte*           ip;+    FT_Byte*           limit;+    CFF_Builder*       builder = &decoder->builder;+    FT_Pos             x, y;+    FT_Fixed           seed;+    FT_Fixed*          stack;+    FT_Int             charstring_type =+                         decoder->cff->top_font.font_dict.charstring_type;++    T2_Hints_Funcs     hinter;+++    /* set default width */+    decoder->num_hints  = 0;+    decoder->read_width = 1;++    /* compute random seed from stack address of parameter */+    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^+                         (FT_PtrDist)(char*)&decoder           ^+                         (FT_PtrDist)(char*)&charstring_base ) &+                         FT_ULONG_MAX ) ;+    seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;+    if ( seed == 0 )+      seed = 0x7384;++    /* initialize the decoder */+    decoder->top  = decoder->stack;+    decoder->zone = decoder->zones;+    zone          = decoder->zones;+    stack         = decoder->top;++    hinter = (T2_Hints_Funcs)builder->hints_funcs;++    builder->path_begun = 0;++    zone->base           = charstring_base;+    limit = zone->limit  = charstring_base + charstring_len;+    ip    = zone->cursor = zone->base;++    error = CFF_Err_Ok;++    x = builder->pos_x;+    y = builder->pos_y;++    /* begin hints recording session, if any */+    if ( hinter )+      hinter->open( hinter->hints );++    /* now execute loop */+    while ( ip < limit )+    {+      CFF_Operator  op;+      FT_Byte       v;+++      /********************************************************************/+      /*                                                                  */+      /* Decode operator or operand                                       */+      /*                                                                  */+      v = *ip++;+      if ( v >= 32 || v == 28 )+      {+        FT_Int    shift = 16;+        FT_Int32  val;+++        /* this is an operand, push it on the stack */+        if ( v == 28 )+        {+          if ( ip + 1 >= limit )+            goto Syntax_Error;+          val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );+          ip += 2;+        }+        else if ( v < 247 )+          val = (FT_Int32)v - 139;+        else if ( v < 251 )+        {+          if ( ip >= limit )+            goto Syntax_Error;+          val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;+        }+        else if ( v < 255 )+        {+          if ( ip >= limit )+            goto Syntax_Error;+          val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;+        }+        else+        {+          if ( ip + 3 >= limit )+            goto Syntax_Error;+          val = ( (FT_Int32)ip[0] << 24 ) |+                ( (FT_Int32)ip[1] << 16 ) |+                ( (FT_Int32)ip[2] <<  8 ) |+                            ip[3];+          ip    += 4;+          if ( charstring_type == 2 )+            shift = 0;+        }+        if ( decoder->top - stack >= CFF_MAX_OPERANDS )+          goto Stack_Overflow;++        val           <<= shift;+        *decoder->top++ = val;++#ifdef FT_DEBUG_LEVEL_TRACE+        if ( !( val & 0xFFFFL ) )+          FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));+        else+          FT_TRACE4(( " %.2f", val / 65536.0 ));+#endif++      }+      else+      {+        /* The specification says that normally arguments are to be taken */+        /* from the bottom of the stack.  However, this seems not to be   */+        /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */+        /* arguments similar to a PS interpreter.                         */++        FT_Fixed*  args     = decoder->top;+        FT_Int     num_args = (FT_Int)( args - decoder->stack );+        FT_Int     req_args;+++        /* find operator */+        op = cff_op_unknown;++        switch ( v )+        {+        case 1:+          op = cff_op_hstem;+          break;+        case 3:+          op = cff_op_vstem;+          break;+        case 4:+          op = cff_op_vmoveto;+          break;+        case 5:+          op = cff_op_rlineto;+          break;+        case 6:+          op = cff_op_hlineto;+          break;+        case 7:+          op = cff_op_vlineto;+          break;+        case 8:+          op = cff_op_rrcurveto;+          break;+        case 9:+          op = cff_op_closepath;+          break;+        case 10:+          op = cff_op_callsubr;+          break;+        case 11:+          op = cff_op_return;+          break;+        case 12:+          {+            if ( ip >= limit )+              goto Syntax_Error;+            v = *ip++;++            switch ( v )+            {+            case 0:+              op = cff_op_dotsection;+              break;+            case 1: /* this is actually the Type1 vstem3 operator */+              op = cff_op_vstem;+              break;+            case 2: /* this is actually the Type1 hstem3 operator */+              op = cff_op_hstem;+              break;+            case 3:+              op = cff_op_and;+              break;+            case 4:+              op = cff_op_or;+              break;+            case 5:+              op = cff_op_not;+              break;+            case 6:+              op = cff_op_seac;+              break;+            case 7:+              op = cff_op_sbw;+              break;+            case 8:+              op = cff_op_store;+              break;+            case 9:+              op = cff_op_abs;+              break;+            case 10:+              op = cff_op_add;+              break;+            case 11:+              op = cff_op_sub;+              break;+            case 12:+              op = cff_op_div;+              break;+            case 13:+              op = cff_op_load;+              break;+            case 14:+              op = cff_op_neg;+              break;+            case 15:+              op = cff_op_eq;+              break;+            case 16:+              op = cff_op_callothersubr;+              break;+            case 17:+              op = cff_op_pop;+              break;+            case 18:+              op = cff_op_drop;+              break;+            case 20:+              op = cff_op_put;+              break;+            case 21:+              op = cff_op_get;+              break;+            case 22:+              op = cff_op_ifelse;+              break;+            case 23:+              op = cff_op_random;+              break;+            case 24:+              op = cff_op_mul;+              break;+            case 26:+              op = cff_op_sqrt;+              break;+            case 27:+              op = cff_op_dup;+              break;+            case 28:+              op = cff_op_exch;+              break;+            case 29:+              op = cff_op_index;+              break;+            case 30:+              op = cff_op_roll;+              break;+            case 33:+              op = cff_op_setcurrentpoint;+              break;+            case 34:+              op = cff_op_hflex;+              break;+            case 35:+              op = cff_op_flex;+              break;+            case 36:+              op = cff_op_hflex1;+              break;+            case 37:+              op = cff_op_flex1;+              break;+            default:+              /* decrement ip for syntax error message */+              ip--;+            }+          }+          break;+        case 13:+          op = cff_op_hsbw;+          break;+        case 14:+          op = cff_op_endchar;+          break;+        case 16:+          op = cff_op_blend;+          break;+        case 18:+          op = cff_op_hstemhm;+          break;+        case 19:+          op = cff_op_hintmask;+          break;+        case 20:+          op = cff_op_cntrmask;+          break;+        case 21:+          op = cff_op_rmoveto;+          break;+        case 22:+          op = cff_op_hmoveto;+          break;+        case 23:+          op = cff_op_vstemhm;+          break;+        case 24:+          op = cff_op_rcurveline;+          break;+        case 25:+          op = cff_op_rlinecurve;+          break;+        case 26:+          op = cff_op_vvcurveto;+          break;+        case 27:+          op = cff_op_hhcurveto;+          break;+        case 29:+          op = cff_op_callgsubr;+          break;+        case 30:+          op = cff_op_vhcurveto;+          break;+        case 31:+          op = cff_op_hvcurveto;+          break;+        default:+          break;+        }++        if ( op == cff_op_unknown )+          goto Syntax_Error;++        /* check arguments */+        req_args = cff_argument_counts[op];+        if ( req_args & CFF_COUNT_CHECK_WIDTH )+        {+          if ( num_args > 0 && decoder->read_width )+          {+            /* If `nominal_width' is non-zero, the number is really a      */+            /* difference against `nominal_width'.  Else, the number here  */+            /* is truly a width, not a difference against `nominal_width'. */+            /* If the font does not set `nominal_width', then              */+            /* `nominal_width' defaults to zero, and so we can set         */+            /* `glyph_width' to `nominal_width' plus number on the stack   */+            /* -- for either case.                                         */++            FT_Int  set_width_ok;+++            switch ( op )+            {+            case cff_op_hmoveto:+            case cff_op_vmoveto:+              set_width_ok = num_args & 2;+              break;++            case cff_op_hstem:+            case cff_op_vstem:+            case cff_op_hstemhm:+            case cff_op_vstemhm:+            case cff_op_rmoveto:+            case cff_op_hintmask:+            case cff_op_cntrmask:+              set_width_ok = num_args & 1;+              break;++            case cff_op_endchar:+              /* If there is a width specified for endchar, we either have */+              /* 1 argument or 5 arguments.  We like to argue.             */+              set_width_ok = ( num_args == 5 ) || ( num_args == 1 );+              break;++            default:+              set_width_ok = 0;+              break;+            }++            if ( set_width_ok )+            {+              decoder->glyph_width = decoder->nominal_width ++                                       ( stack[0] >> 16 );++              if ( decoder->width_only )+              {+                /* we only want the advance width; stop here */+                break;+              }++              /* Consumed an argument. */+              num_args--;+            }+          }++          decoder->read_width = 0;+          req_args            = 0;+        }++        req_args &= 0x000F;+        if ( num_args < req_args )+          goto Stack_Underflow;+        args     -= req_args;+        num_args -= req_args;++        /* At this point, `args' points to the first argument of the  */+        /* operand in case `req_args' isn't zero.  Otherwise, we have */+        /* to adjust `args' manually.                                 */++        /* Note that we only pop arguments from the stack which we    */+        /* really need and can digest so that we can continue in case */+        /* of superfluous stack elements.                             */++        switch ( op )+        {+        case cff_op_hstem:+        case cff_op_vstem:+        case cff_op_hstemhm:+        case cff_op_vstemhm:+          /* the number of arguments is always even here */+          FT_TRACE4((+              op == cff_op_hstem   ? " hstem\n"   :+            ( op == cff_op_vstem   ? " vstem\n"   :+            ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));++          if ( hinter )+            hinter->stems( hinter->hints,+                           ( op == cff_op_hstem || op == cff_op_hstemhm ),+                           num_args / 2,+                           args - ( num_args & ~1 ) );++          decoder->num_hints += num_args / 2;+          args = stack;+          break;++        case cff_op_hintmask:+        case cff_op_cntrmask:+          FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));++          /* implement vstem when needed --                        */+          /* the specification doesn't say it, but this also works */+          /* with the 'cntrmask' operator                          */+          /*                                                       */+          if ( num_args > 0 )+          {+            if ( hinter )+              hinter->stems( hinter->hints,+                             0,+                             num_args / 2,+                             args - ( num_args & ~1 ) );++            decoder->num_hints += num_args / 2;+          }++          /* In a valid charstring there must be at least one byte */+          /* after `hintmask' or `cntrmask' (e.g., for a `return'  */+          /* instruction).  Additionally, there must be space for  */+          /* `num_hints' bits.                                     */++          if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )+            goto Syntax_Error;++          if ( hinter )+          {+            if ( op == cff_op_hintmask )+              hinter->hintmask( hinter->hints,+                                builder->current->n_points,+                                decoder->num_hints,+                                ip );+            else+              hinter->counter( hinter->hints,+                               decoder->num_hints,+                               ip );+          }++#ifdef FT_DEBUG_LEVEL_TRACE+          {+            FT_UInt maskbyte;+++            FT_TRACE4(( " (maskbytes:" ));++            for ( maskbyte = 0;+                  maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );+                  maskbyte++, ip++ )+              FT_TRACE4(( " 0x%02X", *ip ));++            FT_TRACE4(( ")\n" ));+          }+#else+          ip += ( decoder->num_hints + 7 ) >> 3;+#endif+          args = stack;+          break;++        case cff_op_rmoveto:+          FT_TRACE4(( " rmoveto\n" ));++          cff_builder_close_contour( builder );+          builder->path_begun = 0;+          x   += args[-2];+          y   += args[-1];+          args = stack;+          break;++        case cff_op_vmoveto:+          FT_TRACE4(( " vmoveto\n" ));++          cff_builder_close_contour( builder );+          builder->path_begun = 0;+          y   += args[-1];+          args = stack;+          break;++        case cff_op_hmoveto:+          FT_TRACE4(( " hmoveto\n" ));++          cff_builder_close_contour( builder );+          builder->path_begun = 0;+          x   += args[-1];+          args = stack;+          break;++        case cff_op_rlineto:+          FT_TRACE4(( " rlineto\n" ));++          if ( cff_builder_start_point ( builder, x, y ) ||+               check_points( builder, num_args / 2 )     )+            goto Fail;++          if ( num_args < 2 )+            goto Stack_Underflow;++          args -= num_args & ~1;+          while ( args < decoder->top )+          {+            x += args[0];+            y += args[1];+            cff_builder_add_point( builder, x, y, 1 );+            args += 2;+          }+          args = stack;+          break;++        case cff_op_hlineto:+        case cff_op_vlineto:+          {+            FT_Int  phase = ( op == cff_op_hlineto );+++            FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"+                                             : " vlineto\n" ));++            if ( num_args < 1 )+              goto Stack_Underflow;++            if ( cff_builder_start_point ( builder, x, y ) ||+                 check_points( builder, num_args )         )+              goto Fail;++            args = stack;+            while ( args < decoder->top )+            {+              if ( phase )+                x += args[0];+              else+                y += args[0];++              if ( cff_builder_add_point1( builder, x, y ) )+                goto Fail;++              args++;+              phase ^= 1;+            }+            args = stack;+          }+          break;++        case cff_op_rrcurveto:+          {+            FT_Int  nargs;+++            FT_TRACE4(( " rrcurveto\n" ));++            if ( num_args < 6 )+              goto Stack_Underflow;++            nargs = num_args - num_args % 6;++            if ( cff_builder_start_point ( builder, x, y ) ||+                 check_points( builder, nargs / 2 )     )+              goto Fail;++            args -= nargs;+            while ( args < decoder->top )+            {+              x += args[0];+              y += args[1];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[2];+              y += args[3];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[4];+              y += args[5];+              cff_builder_add_point( builder, x, y, 1 );+              args += 6;+            }+            args = stack;+          }+          break;++        case cff_op_vvcurveto:+          {+            FT_Int  nargs;+++            FT_TRACE4(( " vvcurveto\n" ));++            if ( num_args < 4 )+              goto Stack_Underflow;++            /* if num_args isn't of the form 4n or 4n+1, */+            /* we reduce it to 4n+1                      */++            nargs = num_args - num_args % 4;+            if ( num_args - nargs > 0 )+              nargs += 1;++            if ( cff_builder_start_point( builder, x, y ) )+              goto Fail;++            args -= nargs;++            if ( nargs & 1 )+            {+              x += args[0];+              args++;+              nargs--;+            }++            if ( check_points( builder, 3 * ( nargs / 4 ) ) )+              goto Fail;++            while ( args < decoder->top )+            {+              y += args[0];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[1];+              y += args[2];+              cff_builder_add_point( builder, x, y, 0 );+              y += args[3];+              cff_builder_add_point( builder, x, y, 1 );+              args += 4;+            }+            args = stack;+          }+          break;++        case cff_op_hhcurveto:+          {+            FT_Int  nargs;+++            FT_TRACE4(( " hhcurveto\n" ));++            if ( num_args < 4 )+              goto Stack_Underflow;++            /* if num_args isn't of the form 4n or 4n+1, */+            /* we reduce it to 4n+1                      */++            nargs = num_args - num_args % 4;+            if ( num_args - nargs > 0 )+              nargs += 1;++            if ( cff_builder_start_point( builder, x, y ) )+              goto Fail;++            args -= nargs;+            if ( nargs & 1 )+            {+              y += args[0];+              args++;+              nargs--;+            }++            if ( check_points( builder, 3 * ( nargs / 4 ) ) )+              goto Fail;++            while ( args < decoder->top )+            {+              x += args[0];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[1];+              y += args[2];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[3];+              cff_builder_add_point( builder, x, y, 1 );+              args += 4;+            }+            args = stack;+          }+          break;++        case cff_op_vhcurveto:+        case cff_op_hvcurveto:+          {+            FT_Int  phase;+            FT_Int  nargs;+++            FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"+                                               : " hvcurveto\n" ));++            if ( cff_builder_start_point( builder, x, y ) )+              goto Fail;++            if ( num_args < 4 )+              goto Stack_Underflow;++            /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */+            /* we reduce it to the largest one which fits             */++            nargs = num_args - num_args % 4;+            if ( num_args - nargs > 0 )+              nargs += 1;++            args -= nargs;+            if ( check_points( builder, ( nargs / 4 ) * 3 ) )+              goto Stack_Underflow;++            phase = ( op == cff_op_hvcurveto );++            while ( nargs >= 4 )+            {+              nargs -= 4;+              if ( phase )+              {+                x += args[0];+                cff_builder_add_point( builder, x, y, 0 );+                x += args[1];+                y += args[2];+                cff_builder_add_point( builder, x, y, 0 );+                y += args[3];+                if ( nargs == 1 )+                  x += args[4];+                cff_builder_add_point( builder, x, y, 1 );+              }+              else+              {+                y += args[0];+                cff_builder_add_point( builder, x, y, 0 );+                x += args[1];+                y += args[2];+                cff_builder_add_point( builder, x, y, 0 );+                x += args[3];+                if ( nargs == 1 )+                  y += args[4];+                cff_builder_add_point( builder, x, y, 1 );+              }+              args  += 4;+              phase ^= 1;+            }+            args = stack;+          }+          break;++        case cff_op_rlinecurve:+          {+            FT_Int  num_lines;+            FT_Int  nargs;+++            FT_TRACE4(( " rlinecurve\n" ));++            if ( num_args < 8 )+              goto Stack_Underflow;++            nargs     = num_args & ~1;+            num_lines = ( nargs - 6 ) / 2;++            if ( cff_builder_start_point( builder, x, y ) ||+                 check_points( builder, num_lines + 3 )   )+              goto Fail;++            args -= nargs;++            /* first, add the line segments */+            while ( num_lines > 0 )+            {+              x += args[0];+              y += args[1];+              cff_builder_add_point( builder, x, y, 1 );+              args += 2;+              num_lines--;+            }++            /* then the curve */+            x += args[0];+            y += args[1];+            cff_builder_add_point( builder, x, y, 0 );+            x += args[2];+            y += args[3];+            cff_builder_add_point( builder, x, y, 0 );+            x += args[4];+            y += args[5];+            cff_builder_add_point( builder, x, y, 1 );+            args = stack;+          }+          break;++        case cff_op_rcurveline:+          {+            FT_Int  num_curves;+            FT_Int  nargs;+++            FT_TRACE4(( " rcurveline\n" ));++            if ( num_args < 8 )+              goto Stack_Underflow;++            nargs      = num_args - 2;+            nargs      = nargs - nargs % 6 + 2;+            num_curves = ( nargs - 2 ) / 6;++            if ( cff_builder_start_point ( builder, x, y ) ||+                 check_points( builder, num_curves * 3 + 2 ) )+              goto Fail;++            args -= nargs;++            /* first, add the curves */+            while ( num_curves > 0 )+            {+              x += args[0];+              y += args[1];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[2];+              y += args[3];+              cff_builder_add_point( builder, x, y, 0 );+              x += args[4];+              y += args[5];+              cff_builder_add_point( builder, x, y, 1 );+              args += 6;+              num_curves--;+            }++            /* then the final line */+            x += args[0];+            y += args[1];+            cff_builder_add_point( builder, x, y, 1 );+            args = stack;+          }+          break;++        case cff_op_hflex1:+          {+            FT_Pos start_y;+++            FT_TRACE4(( " hflex1\n" ));++            /* adding five more points: 4 control points, 1 on-curve point */+            /* -- make sure we have enough space for the start point if it */+            /* needs to be added                                           */+            if ( cff_builder_start_point( builder, x, y ) ||+                 check_points( builder, 6 )               )+              goto Fail;++            /* record the starting point's y position for later use */+            start_y = y;++            /* first control point */+            x += args[0];+            y += args[1];+            cff_builder_add_point( builder, x, y, 0 );++            /* second control point */+            x += args[2];+            y += args[3];+            cff_builder_add_point( builder, x, y, 0 );++            /* join point; on curve, with y-value the same as the last */+            /* control point's y-value                                 */+            x += args[4];+            cff_builder_add_point( builder, x, y, 1 );++            /* third control point, with y-value the same as the join */+            /* point's y-value                                        */+            x += args[5];+            cff_builder_add_point( builder, x, y, 0 );++            /* fourth control point */+            x += args[6];+            y += args[7];+            cff_builder_add_point( builder, x, y, 0 );++            /* ending point, with y-value the same as the start   */+            x += args[8];+            y  = start_y;+            cff_builder_add_point( builder, x, y, 1 );++            args = stack;+            break;+          }++        case cff_op_hflex:+          {+            FT_Pos start_y;+++            FT_TRACE4(( " hflex\n" ));++            /* adding six more points; 4 control points, 2 on-curve points */+            if ( cff_builder_start_point( builder, x, y ) ||+                 check_points( builder, 6 )               )+              goto Fail;++            /* record the starting point's y-position for later use */+            start_y = y;++            /* first control point */+            x += args[0];+            cff_builder_add_point( builder, x, y, 0 );++            /* second control point */+            x += args[1];+            y += args[2];+            cff_builder_add_point( builder, x, y, 0 );++            /* join point; on curve, with y-value the same as the last */+            /* control point's y-value                                 */+            x += args[3];+            cff_builder_add_point( builder, x, y, 1 );++            /* third control point, with y-value the same as the join */+            /* point's y-value                                        */+            x += args[4];+            cff_builder_add_point( builder, x, y, 0 );++            /* fourth control point */+            x += args[5];+            y  = start_y;+            cff_builder_add_point( builder, x, y, 0 );++            /* ending point, with y-value the same as the start point's */+            /* y-value -- we don't add this point, though               */+            x += args[6];+            cff_builder_add_point( builder, x, y, 1 );++            args = stack;+            break;+          }++        case cff_op_flex1:+          {+            FT_Pos     start_x, start_y; /* record start x, y values for */+                                         /* alter use                    */+            FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */+                                         /* algorithm below              */+            FT_Int     horizontal, count;+            FT_Fixed*  temp;+++            FT_TRACE4(( " flex1\n" ));++            /* adding six more points; 4 control points, 2 on-curve points */+            if ( cff_builder_start_point( builder, x, y ) ||+                 check_points( builder, 6 )               )+              goto Fail;++            /* record the starting point's x, y position for later use */+            start_x = x;+            start_y = y;++            /* XXX: figure out whether this is supposed to be a horizontal */+            /*      or vertical flex; the Type 2 specification is vague... */++            temp = args;++            /* grab up to the last argument */+            for ( count = 5; count > 0; count-- )+            {+              dx += temp[0];+              dy += temp[1];+              temp += 2;+            }++            if ( dx < 0 )+              dx = -dx;+            if ( dy < 0 )+              dy = -dy;++            /* strange test, but here it is... */+            horizontal = ( dx > dy );++            for ( count = 5; count > 0; count-- )+            {+              x += args[0];+              y += args[1];+              cff_builder_add_point( builder, x, y,+                                     (FT_Bool)( count == 3 ) );+              args += 2;+            }++            /* is last operand an x- or y-delta? */+            if ( horizontal )+            {+              x += args[0];+              y  = start_y;+            }+            else+            {+              x  = start_x;+              y += args[0];+            }++            cff_builder_add_point( builder, x, y, 1 );++            args = stack;+            break;+           }++        case cff_op_flex:+          {+            FT_UInt  count;+++            FT_TRACE4(( " flex\n" ));++            if ( cff_builder_start_point( builder, x, y ) ||+                 check_points( builder, 6 )               )+              goto Fail;++            for ( count = 6; count > 0; count-- )+            {+              x += args[0];+              y += args[1];+              cff_builder_add_point( builder, x, y,+                                     (FT_Bool)( count == 4 || count == 1 ) );+              args += 2;+            }++            args = stack;+          }+          break;++        case cff_op_seac:+            FT_TRACE4(( " seac\n" ));++            error = cff_operator_seac( decoder,+                                       args[0], args[1], args[2],+                                       (FT_Int)( args[3] >> 16 ),+                                       (FT_Int)( args[4] >> 16 ) );++            /* add current outline to the glyph slot */+            FT_GlyphLoader_Add( builder->loader );++            /* return now! */+            FT_TRACE4(( "\n" ));+            return error;++        case cff_op_endchar:+          FT_TRACE4(( " endchar\n" ));++          /* We are going to emulate the seac operator. */+          if ( num_args >= 4 )+          {+            /* Save glyph width so that the subglyphs don't overwrite it. */+            FT_Pos  glyph_width = decoder->glyph_width;++            error = cff_operator_seac( decoder,+                                       0L, args[-4], args[-3],+                                       (FT_Int)( args[-2] >> 16 ),+                                       (FT_Int)( args[-1] >> 16 ) );++            decoder->glyph_width = glyph_width;+          }+          else+          {+            if ( !error )+              error = CFF_Err_Ok;++            cff_builder_close_contour( builder );++            /* close hints recording session */+            if ( hinter )+            {+              if ( hinter->close( hinter->hints,+                                  builder->current->n_points ) )+                goto Syntax_Error;++              /* apply hints to the loaded glyph outline now */+              hinter->apply( hinter->hints,+                             builder->current,+                             (PSH_Globals)builder->hints_globals,+                             decoder->hint_mode );+            }++            /* add current outline to the glyph slot */+            FT_GlyphLoader_Add( builder->loader );+          }++          /* return now! */+          FT_TRACE4(( "\n" ));+          return error;++        case cff_op_abs:+          FT_TRACE4(( " abs\n" ));++          if ( args[0] < 0 )+            args[0] = -args[0];+          args++;+          break;++        case cff_op_add:+          FT_TRACE4(( " add\n" ));++          args[0] += args[1];+          args++;+          break;++        case cff_op_sub:+          FT_TRACE4(( " sub\n" ));++          args[0] -= args[1];+          args++;+          break;++        case cff_op_div:+          FT_TRACE4(( " div\n" ));++          args[0] = FT_DivFix( args[0], args[1] );+          args++;+          break;++        case cff_op_neg:+          FT_TRACE4(( " neg\n" ));++          args[0] = -args[0];+          args++;+          break;++        case cff_op_random:+          {+            FT_Fixed  Rand;+++            FT_TRACE4(( " rand\n" ));++            Rand = seed;+            if ( Rand >= 0x8000L )+              Rand++;++            args[0] = Rand;+            seed    = FT_MulFix( seed, 0x10000L - seed );+            if ( seed == 0 )+              seed += 0x2873;+            args++;+          }+          break;++        case cff_op_mul:+          FT_TRACE4(( " mul\n" ));++          args[0] = FT_MulFix( args[0], args[1] );+          args++;+          break;++        case cff_op_sqrt:+          FT_TRACE4(( " sqrt\n" ));++          if ( args[0] > 0 )+          {+            FT_Int    count = 9;+            FT_Fixed  root  = args[0];+            FT_Fixed  new_root;+++            for (;;)+            {+              new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;+              if ( new_root == root || count <= 0 )+                break;+              root = new_root;+            }+            args[0] = new_root;+          }+          else+            args[0] = 0;+          args++;+          break;++        case cff_op_drop:+          /* nothing */+          FT_TRACE4(( " drop\n" ));++          break;++        case cff_op_exch:+          {+            FT_Fixed  tmp;+++            FT_TRACE4(( " exch\n" ));++            tmp     = args[0];+            args[0] = args[1];+            args[1] = tmp;+            args   += 2;+          }+          break;++        case cff_op_index:+          {+            FT_Int  idx = (FT_Int)( args[0] >> 16 );+++            FT_TRACE4(( " index\n" ));++            if ( idx < 0 )+              idx = 0;+            else if ( idx > num_args - 2 )+              idx = num_args - 2;+            args[0] = args[-( idx + 1 )];+            args++;+          }+          break;++        case cff_op_roll:+          {+            FT_Int  count = (FT_Int)( args[0] >> 16 );+            FT_Int  idx   = (FT_Int)( args[1] >> 16 );+++            FT_TRACE4(( " roll\n" ));++            if ( count <= 0 )+              count = 1;++            args -= count;+            if ( args < stack )+              goto Stack_Underflow;++            if ( idx >= 0 )+            {+              while ( idx > 0 )+              {+                FT_Fixed  tmp = args[count - 1];+                FT_Int    i;+++                for ( i = count - 2; i >= 0; i-- )+                  args[i + 1] = args[i];+                args[0] = tmp;+                idx--;+              }+            }+            else+            {+              while ( idx < 0 )+              {+                FT_Fixed  tmp = args[0];+                FT_Int    i;+++                for ( i = 0; i < count - 1; i++ )+                  args[i] = args[i + 1];+                args[count - 1] = tmp;+                idx++;+              }+            }+            args += count;+          }+          break;++        case cff_op_dup:+          FT_TRACE4(( " dup\n" ));++          args[1] = args[0];+          args += 2;+          break;++        case cff_op_put:+          {+            FT_Fixed  val = args[0];+            FT_Int    idx = (FT_Int)( args[1] >> 16 );+++            FT_TRACE4(( " put\n" ));++            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )+              decoder->buildchar[idx] = val;+          }+          break;++        case cff_op_get:+          {+            FT_Int    idx = (FT_Int)( args[0] >> 16 );+            FT_Fixed  val = 0;+++            FT_TRACE4(( " get\n" ));++            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )+              val = decoder->buildchar[idx];++            args[0] = val;+            args++;+          }+          break;++        case cff_op_store:+          FT_TRACE4(( " store\n"));++          goto Unimplemented;++        case cff_op_load:+          FT_TRACE4(( " load\n" ));++          goto Unimplemented;++        case cff_op_dotsection:+          /* this operator is deprecated and ignored by the parser */+          FT_TRACE4(( " dotsection\n" ));+          break;++        case cff_op_closepath:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " closepath (invalid op)\n" ));++          args = stack;+          break;++        case cff_op_hsbw:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " hsbw (invalid op)\n" ));++          decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );++          decoder->builder.left_bearing.x = args[0];+          decoder->builder.left_bearing.y = 0;++          x    = decoder->builder.pos_x + args[0];+          y    = decoder->builder.pos_y;+          args = stack;+          break;++        case cff_op_sbw:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " sbw (invalid op)\n" ));++          decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );++          decoder->builder.left_bearing.x = args[0];+          decoder->builder.left_bearing.y = args[1];++          x    = decoder->builder.pos_x + args[0];+          y    = decoder->builder.pos_y + args[1];+          args = stack;+          break;++        case cff_op_setcurrentpoint:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));++          x    = decoder->builder.pos_x + args[0];+          y    = decoder->builder.pos_y + args[1];+          args = stack;+          break;++        case cff_op_callothersubr:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " callothersubr (invalid op)\n" ));++          /* subsequent `pop' operands should add the arguments,       */+          /* this is the implementation described for `unknown' other  */+          /* subroutines in the Type1 spec.                            */+          /*                                                           */+          /* XXX Fix return arguments (see discussion below).          */+          args -= 2 + ( args[-2] >> 16 );+          if ( args < stack )+            goto Stack_Underflow;+          break;++        case cff_op_pop:+          /* this is an invalid Type 2 operator; however, there        */+          /* exist fonts which are incorrectly converted from probably */+          /* Type 1 to CFF, and some parsers seem to accept it         */++          FT_TRACE4(( " pop (invalid op)\n" ));++          /* XXX Increasing `args' is wrong: After a certain number of */+          /* `pop's we get a stack overflow.  Reason for doing it is   */+          /* code like this (actually found in a CFF font):            */+          /*                                                           */+          /*   17 1 3 callothersubr                                    */+          /*   pop                                                     */+          /*   callsubr                                                */+          /*                                                           */+          /* Since we handle `callothersubr' as a no-op, and           */+          /* `callsubr' needs at least one argument, `pop' can't be a  */+          /* no-op too as it basically should be.                      */+          /*                                                           */+          /* The right solution would be to provide real support for   */+          /* `callothersubr' as done in `t1decode.c', however, given   */+          /* the fact that CFF fonts with `pop' are invalid, it is     */+          /* questionable whether it is worth the time.                */+          args++;+          break;++        case cff_op_and:+          {+            FT_Fixed  cond = args[0] && args[1];+++            FT_TRACE4(( " and\n" ));++            args[0] = cond ? 0x10000L : 0;+            args++;+          }+          break;++        case cff_op_or:+          {+            FT_Fixed  cond = args[0] || args[1];+++            FT_TRACE4(( " or\n" ));++            args[0] = cond ? 0x10000L : 0;+            args++;+          }+          break;++        case cff_op_eq:+          {+            FT_Fixed  cond = !args[0];+++            FT_TRACE4(( " eq\n" ));++            args[0] = cond ? 0x10000L : 0;+            args++;+          }+          break;++        case cff_op_ifelse:+          {+            FT_Fixed  cond = ( args[2] <= args[3] );+++            FT_TRACE4(( " ifelse\n" ));++            if ( !cond )+              args[0] = args[1];+            args++;+          }+          break;++        case cff_op_callsubr:+          {+            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) ++                                      decoder->locals_bias );+++            FT_TRACE4(( " callsubr(%d)\n", idx ));++            if ( idx >= decoder->num_locals )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " invalid local subr index\n" ));+              goto Syntax_Error;+            }++            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " too many nested subrs\n" ));+              goto Syntax_Error;+            }++            zone->cursor = ip;  /* save current instruction pointer */++            zone++;+            zone->base   = decoder->locals[idx];+            zone->limit  = decoder->locals[idx + 1];+            zone->cursor = zone->base;++            if ( !zone->base || zone->limit == zone->base )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " invoking empty subrs\n" ));+              goto Syntax_Error;+            }++            decoder->zone = zone;+            ip            = zone->base;+            limit         = zone->limit;+          }+          break;++        case cff_op_callgsubr:+          {+            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) ++                                      decoder->globals_bias );+++            FT_TRACE4(( " callgsubr(%d)\n", idx ));++            if ( idx >= decoder->num_globals )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " invalid global subr index\n" ));+              goto Syntax_Error;+            }++            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " too many nested subrs\n" ));+              goto Syntax_Error;+            }++            zone->cursor = ip;  /* save current instruction pointer */++            zone++;+            zone->base   = decoder->globals[idx];+            zone->limit  = decoder->globals[idx + 1];+            zone->cursor = zone->base;++            if ( !zone->base || zone->limit == zone->base )+            {+              FT_ERROR(( "cff_decoder_parse_charstrings:"+                         " invoking empty subrs\n" ));+              goto Syntax_Error;+            }++            decoder->zone = zone;+            ip            = zone->base;+            limit         = zone->limit;+          }+          break;++        case cff_op_return:+          FT_TRACE4(( " return\n" ));++          if ( decoder->zone <= decoder->zones )+          {+            FT_ERROR(( "cff_decoder_parse_charstrings:"+                       " unexpected return\n" ));+            goto Syntax_Error;+          }++          decoder->zone--;+          zone  = decoder->zone;+          ip    = zone->cursor;+          limit = zone->limit;+          break;++        default:+        Unimplemented:+          FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));++          if ( ip[-1] == 12 )+            FT_ERROR(( " %d", ip[0] ));+          FT_ERROR(( "\n" ));++          return CFF_Err_Unimplemented_Feature;+        }++        decoder->top = args;++        if ( decoder->top - stack >= CFF_MAX_OPERANDS )+          goto Stack_Overflow;++      } /* general operator processing */++    } /* while ip < limit */++    FT_TRACE4(( "..end..\n\n" ));++  Fail:+    return error;++  Syntax_Error:+    FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));+    return CFF_Err_Invalid_File_Format;++  Stack_Underflow:+    FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));+    return CFF_Err_Too_Few_Arguments;++  Stack_Overflow:+    FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));+    return CFF_Err_Stack_Overflow;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /**********                                                      *********/+  /**********                                                      *********/+  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/+  /**********                                                      *********/+  /**********    The following code is in charge of computing      *********/+  /**********    the maximum advance width of the font.  It        *********/+  /**********    quickly processes each glyph charstring to        *********/+  /**********    extract the value from either a `sbw' or `seac'   *********/+  /**********    operator.                                         *********/+  /**********                                                      *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#if 0 /* unused until we support pure CFF fonts */+++  FT_LOCAL_DEF( FT_Error )+  cff_compute_max_advance( TT_Face  face,+                           FT_Int*  max_advance )+  {+    FT_Error     error = CFF_Err_Ok;+    CFF_Decoder  decoder;+    FT_Int       glyph_index;+    CFF_Font     cff = (CFF_Font)face->other;+++    *max_advance = 0;++    /* Initialize load decoder */+    cff_decoder_init( &decoder, face, 0, 0, 0, 0 );++    decoder.builder.metrics_only = 1;+    decoder.builder.load_points  = 0;++    /* For each glyph, parse the glyph charstring and extract */+    /* the advance width.                                     */+    for ( glyph_index = 0; glyph_index < face->root.num_glyphs;+          glyph_index++ )+    {+      FT_Byte*  charstring;+      FT_ULong  charstring_len;+++      /* now get load the unscaled outline */+      error = cff_get_glyph_data( face, glyph_index,+                                  &charstring, &charstring_len );+      if ( !error )+      {+        error = cff_decoder_prepare( &decoder, size, glyph_index );+        if ( !error )+          error = cff_decoder_parse_charstrings( &decoder,+                                                 charstring,+                                                 charstring_len );++        cff_free_glyph_data( face, &charstring, &charstring_len );+      }++      /* ignore the error if one has occurred -- skip to next glyph */+      error = CFF_Err_Ok;+    }++    *max_advance = decoder.builder.advance.x;++    return CFF_Err_Ok;+  }+++#endif /* 0 */+++  FT_LOCAL_DEF( FT_Error )+  cff_slot_load( CFF_GlyphSlot  glyph,+                 CFF_Size       size,+                 FT_UInt        glyph_index,+                 FT_Int32       load_flags )+  {+    FT_Error     error;+    CFF_Decoder  decoder;+    TT_Face      face = (TT_Face)glyph->root.face;+    FT_Bool      hinting, force_scaling;+    CFF_Font     cff  = (CFF_Font)face->extra.data;++    FT_Matrix    font_matrix;+    FT_Vector    font_offset;+++    force_scaling = FALSE;++    /* in a CID-keyed font, consider `glyph_index' as a CID and map */+    /* it immediately to the real glyph_index -- if it isn't a      */+    /* subsetted font, glyph_indices and CIDs are identical, though */+    if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&+         cff->charset.cids                               )+    {+      /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */+      if ( glyph_index != 0 )+      {+        glyph_index = cff_charset_cid_to_gindex( &cff->charset,+                                                 glyph_index );+        if ( glyph_index == 0 )+          return CFF_Err_Invalid_Argument;+      }+    }+    else if ( glyph_index >= cff->num_glyphs )+      return CFF_Err_Invalid_Argument;++    if ( load_flags & FT_LOAD_NO_RECURSE )+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;++    glyph->x_scale = 0x10000L;+    glyph->y_scale = 0x10000L;+    if ( size )+    {+      glyph->x_scale = size->root.metrics.x_scale;+      glyph->y_scale = size->root.metrics.y_scale;+    }++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++    /* try to load embedded bitmap if any              */+    /*                                                 */+    /* XXX: The convention should be emphasized in     */+    /*      the documents because it can be confusing. */+    if ( size )+    {+      CFF_Face      cff_face = (CFF_Face)size->root.face;+      SFNT_Service  sfnt     = (SFNT_Service)cff_face->sfnt;+      FT_Stream     stream   = cff_face->root.stream;+++      if ( size->strike_index != 0xFFFFFFFFUL      &&+           sfnt->load_eblc                         &&+           ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )+      {+        TT_SBit_MetricsRec  metrics;+++        error = sfnt->load_sbit_image( face,+                                       size->strike_index,+                                       glyph_index,+                                       (FT_Int)load_flags,+                                       stream,+                                       &glyph->root.bitmap,+                                       &metrics );++        if ( !error )+        {+          glyph->root.outline.n_points   = 0;+          glyph->root.outline.n_contours = 0;++          glyph->root.metrics.width  = (FT_Pos)metrics.width  << 6;+          glyph->root.metrics.height = (FT_Pos)metrics.height << 6;++          glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;+          glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;+          glyph->root.metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;++          glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;+          glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;+          glyph->root.metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;++          glyph->root.format = FT_GLYPH_FORMAT_BITMAP;++          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )+          {+            glyph->root.bitmap_left = metrics.vertBearingX;+            glyph->root.bitmap_top  = metrics.vertBearingY;+          }+          else+          {+            glyph->root.bitmap_left = metrics.horiBearingX;+            glyph->root.bitmap_top  = metrics.horiBearingY;+          }+          return error;+        }+      }+    }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */++    /* return immediately if we only want the embedded bitmaps */+    if ( load_flags & FT_LOAD_SBITS_ONLY )+      return CFF_Err_Invalid_Argument;++    /* if we have a CID subfont, use its matrix (which has already */+    /* been multiplied with the root matrix)                       */++    /* this scaling is only relevant if the PS hinter isn't active */+    if ( cff->num_subfonts )+    {+      FT_ULong  top_upm, sub_upm;+      FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,+                                              glyph_index );++      if ( fd_index >= cff->num_subfonts ) +        fd_index = cff->num_subfonts - 1;++      top_upm = cff->top_font.font_dict.units_per_em;+      sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;+++      font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;+      font_offset = cff->subfonts[fd_index]->font_dict.font_offset;++      if ( top_upm != sub_upm )+      {+        glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );+        glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );++        force_scaling = TRUE;+      }+    }+    else+    {+      font_matrix = cff->top_font.font_dict.font_matrix;+      font_offset = cff->top_font.font_dict.font_offset;+    }++    glyph->root.outline.n_points   = 0;+    glyph->root.outline.n_contours = 0;++    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&+                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );++    glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;  /* by default */++    {+      FT_Byte*  charstring;+      FT_ULong  charstring_len;+++      cff_decoder_init( &decoder, face, size, glyph, hinting,+                        FT_LOAD_TARGET_MODE( load_flags ) );++      if ( load_flags & FT_LOAD_ADVANCE_ONLY )+        decoder.width_only = TRUE;++      decoder.builder.no_recurse =+        (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );++      /* now load the unscaled outline */+      error = cff_get_glyph_data( face, glyph_index,+                                  &charstring, &charstring_len );+      if ( error )+        goto Glyph_Build_Finished;++      error = cff_decoder_prepare( &decoder, size, glyph_index );+      if ( error )+        goto Glyph_Build_Finished;++      error = cff_decoder_parse_charstrings( &decoder,+                                             charstring,+                                             charstring_len );++      cff_free_glyph_data( face, &charstring, charstring_len );++      if ( error )+        goto Glyph_Build_Finished;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+      /* Control data and length may not be available for incremental */+      /* fonts.                                                       */+      if ( face->root.internal->incremental_interface )+      {+        glyph->root.control_data = 0;+        glyph->root.control_len = 0;+      }+      else+#endif /* FT_CONFIG_OPTION_INCREMENTAL */++      /* We set control_data and control_len if charstrings is loaded. */+      /* See how charstring loads at cff_index_access_element() in     */+      /* cffload.c.                                                    */+      {+        CFF_Index  csindex = &cff->charstrings_index;+++        if ( csindex->offsets )+        {+          glyph->root.control_data = csindex->bytes ++                                     csindex->offsets[glyph_index] - 1;+          glyph->root.control_len  = charstring_len;+        }+      }++  Glyph_Build_Finished:+      /* save new glyph tables, if no error */+      if ( !error )+        cff_builder_done( &decoder.builder );+      /* XXX: anything to do for broken glyph entry? */+    }++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* Incremental fonts can optionally override the metrics. */+    if ( !error                                                               &&+         face->root.internal->incremental_interface                           &&+         face->root.internal->incremental_interface->funcs->get_glyph_metrics )+    {+      FT_Incremental_MetricsRec  metrics;+++      metrics.bearing_x = decoder.builder.left_bearing.x;+      metrics.bearing_y = 0;+      metrics.advance   = decoder.builder.advance.x;+      metrics.advance_v = decoder.builder.advance.y;++      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(+                face->root.internal->incremental_interface->object,+                glyph_index, FALSE, &metrics );++      decoder.builder.left_bearing.x = metrics.bearing_x;+      decoder.builder.advance.x      = metrics.advance;+      decoder.builder.advance.y      = metrics.advance_v;+    }++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    if ( !error )+    {+      /* Now, set the metrics -- this is rather simple, as   */+      /* the left side bearing is the xMin, and the top side */+      /* bearing the yMax.                                   */++      /* For composite glyphs, return only left side bearing and */+      /* advance width.                                          */+      if ( load_flags & FT_LOAD_NO_RECURSE )+      {+        FT_Slot_Internal  internal = glyph->root.internal;+++        glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;+        glyph->root.metrics.horiAdvance  = decoder.glyph_width;+        internal->glyph_matrix           = font_matrix;+        internal->glyph_delta            = font_offset;+        internal->glyph_transformed      = 1;+      }+      else+      {+        FT_BBox            cbox;+        FT_Glyph_Metrics*  metrics = &glyph->root.metrics;+        FT_Vector          advance;+        FT_Bool            has_vertical_info;+++        /* copy the _unscaled_ advance width */+        metrics->horiAdvance                    = decoder.glyph_width;+        glyph->root.linearHoriAdvance           = decoder.glyph_width;+        glyph->root.internal->glyph_transformed = 0;++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+        has_vertical_info = FT_BOOL( face->vertical_info                   &&+                                     face->vertical.number_Of_VMetrics > 0 &&+                                     face->vertical.long_metrics           );+#else+        has_vertical_info = FT_BOOL( face->vertical_info                   &&+                                     face->vertical.number_Of_VMetrics > 0 );+#endif++        /* get the vertical metrics from the vtmx table if we have one */+        if ( has_vertical_info )+        {+          FT_Short   vertBearingY = 0;+          FT_UShort  vertAdvance  = 0;+++          ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,+                                                     glyph_index,+                                                     &vertBearingY,+                                                     &vertAdvance );+          metrics->vertBearingY = vertBearingY;+          metrics->vertAdvance  = vertAdvance;+        }+        else+        {+          /* make up vertical ones */+          if ( face->os2.version != 0xFFFFU )+            metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -+                                             face->os2.sTypoDescender );+          else+            metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -+                                             face->horizontal.Descender );+        }++        glyph->root.linearVertAdvance = metrics->vertAdvance;++        glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;++        glyph->root.outline.flags = 0;+        if ( size && size->root.metrics.y_ppem < 24 )+          glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;++        glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;++        if ( !( font_matrix.xx == 0x10000L &&+                font_matrix.yy == 0x10000L &&+                font_matrix.xy == 0        &&+                font_matrix.yx == 0        ) )+          FT_Outline_Transform( &glyph->root.outline, &font_matrix );++        if ( !( font_offset.x == 0 &&+                font_offset.y == 0 ) )+          FT_Outline_Translate( &glyph->root.outline,+                                font_offset.x, font_offset.y );++        advance.x = metrics->horiAdvance;+        advance.y = 0;+        FT_Vector_Transform( &advance, &font_matrix );+        metrics->horiAdvance = advance.x + font_offset.x;++        advance.x = 0;+        advance.y = metrics->vertAdvance;+        FT_Vector_Transform( &advance, &font_matrix );+        metrics->vertAdvance = advance.y + font_offset.y;++        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )+        {+          /* scale the outline and the metrics */+          FT_Int       n;+          FT_Outline*  cur     = &glyph->root.outline;+          FT_Vector*   vec     = cur->points;+          FT_Fixed     x_scale = glyph->x_scale;+          FT_Fixed     y_scale = glyph->y_scale;+++          /* First of all, scale the points */+          if ( !hinting || !decoder.builder.hints_funcs )+            for ( n = cur->n_points; n > 0; n--, vec++ )+            {+              vec->x = FT_MulFix( vec->x, x_scale );+              vec->y = FT_MulFix( vec->y, y_scale );+            }++          /* Then scale the metrics */+          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );+          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );+        }++        /* compute the other metrics */+        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );++        metrics->width  = cbox.xMax - cbox.xMin;+        metrics->height = cbox.yMax - cbox.yMin;++        metrics->horiBearingX = cbox.xMin;+        metrics->horiBearingY = cbox.yMax;++        if ( has_vertical_info )+          metrics->vertBearingX = metrics->horiBearingX -+                                    metrics->horiAdvance / 2;+        else +        {+          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )+            ft_synthesize_vertical_metrics( metrics,+                                            metrics->vertAdvance );+        }+      }+    }++    return error;+  }+++/* END */
+ src/cff/cffgload.h view
@@ -0,0 +1,201 @@+/***************************************************************************/+/*                                                                         */+/*  cffgload.h                                                             */+/*                                                                         */+/*    OpenType Glyph Loader (specification).                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFGLOAD_H__+#define __CFFGLOAD_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+#include "cffobjs.h"+++FT_BEGIN_HEADER+++#define CFF_MAX_OPERANDS        48+#define CFF_MAX_SUBRS_CALLS     32+#define CFF_MAX_TRANS_ELEMENTS  32+++  /*************************************************************************/+  /*                                                                       */+  /* <Structure>                                                           */+  /*    CFF_Builder                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*     A structure used during glyph loading to store its outline.       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    memory        :: The current memory object.                        */+  /*                                                                       */+  /*    face          :: The current face object.                          */+  /*                                                                       */+  /*    glyph         :: The current glyph slot.                           */+  /*                                                                       */+  /*    loader        :: The current glyph loader.                         */+  /*                                                                       */+  /*    base          :: The base glyph outline.                           */+  /*                                                                       */+  /*    current       :: The current glyph outline.                        */+  /*                                                                       */+  /*    pos_x         :: The horizontal translation (if composite glyph).  */+  /*                                                                       */+  /*    pos_y         :: The vertical translation (if composite glyph).    */+  /*                                                                       */+  /*    left_bearing  :: The left side bearing point.                      */+  /*                                                                       */+  /*    advance       :: The horizontal advance vector.                    */+  /*                                                                       */+  /*    bbox          :: Unused.                                           */+  /*                                                                       */+  /*    path_begun    :: A flag which indicates that a new path has begun. */+  /*                                                                       */+  /*    load_points   :: If this flag is not set, no points are loaded.    */+  /*                                                                       */+  /*    no_recurse    :: Set but not used.                                 */+  /*                                                                       */+  /*    metrics_only  :: A boolean indicating that we only want to compute */+  /*                     the metrics of a given glyph, not load all of its */+  /*                     points.                                           */+  /*                                                                       */+  /*    hints_funcs   :: Auxiliary pointer for hinting.                    */+  /*                                                                       */+  /*    hints_globals :: Auxiliary pointer for hinting.                    */+  /*                                                                       */+  typedef struct  CFF_Builder_+  {+    FT_Memory       memory;+    TT_Face         face;+    CFF_GlyphSlot   glyph;+    FT_GlyphLoader  loader;+    FT_Outline*     base;+    FT_Outline*     current;++    FT_Pos          pos_x;+    FT_Pos          pos_y;++    FT_Vector       left_bearing;+    FT_Vector       advance;++    FT_BBox         bbox;          /* bounding box */+    FT_Bool         path_begun;+    FT_Bool         load_points;+    FT_Bool         no_recurse;++    FT_Bool         metrics_only;++    void*           hints_funcs;    /* hinter-specific */+    void*           hints_globals;  /* hinter-specific */++  } CFF_Builder;+++  /* execution context charstring zone */++  typedef struct  CFF_Decoder_Zone_+  {+    FT_Byte*  base;+    FT_Byte*  limit;+    FT_Byte*  cursor;++  } CFF_Decoder_Zone;+++  typedef struct  CFF_Decoder_+  {+    CFF_Builder        builder;+    CFF_Font           cff;++    FT_Fixed           stack[CFF_MAX_OPERANDS + 1];+    FT_Fixed*          top;++    CFF_Decoder_Zone   zones[CFF_MAX_SUBRS_CALLS + 1];+    CFF_Decoder_Zone*  zone;++    FT_Int             flex_state;+    FT_Int             num_flex_vectors;+    FT_Vector          flex_vectors[7];++    FT_Pos             glyph_width;+    FT_Pos             nominal_width;++    FT_Bool            read_width;+    FT_Bool            width_only;+    FT_Int             num_hints;+    FT_Fixed           buildchar[CFF_MAX_TRANS_ELEMENTS];++    FT_UInt            num_locals;+    FT_UInt            num_globals;++    FT_Int             locals_bias;+    FT_Int             globals_bias;++    FT_Byte**          locals;+    FT_Byte**          globals;++    FT_Byte**          glyph_names;   /* for pure CFF fonts only  */+    FT_UInt            num_glyphs;    /* number of glyphs in font */++    FT_Render_Mode     hint_mode;++    FT_Bool            seac;++  } CFF_Decoder;+++  FT_LOCAL( void )+  cff_decoder_init( CFF_Decoder*    decoder,+                    TT_Face         face,+                    CFF_Size        size,+                    CFF_GlyphSlot   slot,+                    FT_Bool         hinting,+                    FT_Render_Mode  hint_mode );++  FT_LOCAL( FT_Error )+  cff_decoder_prepare( CFF_Decoder*  decoder,+                       CFF_Size      size,+                       FT_UInt       glyph_index );++#if 0  /* unused until we support pure CFF fonts */++  /* Compute the maximum advance width of a font through quick parsing */+  FT_LOCAL( FT_Error )+  cff_compute_max_advance( TT_Face  face,+                           FT_Int*  max_advance );++#endif /* 0 */++  FT_LOCAL( FT_Error )+  cff_decoder_parse_charstrings( CFF_Decoder*  decoder,+                                 FT_Byte*      charstring_base,+                                 FT_ULong      charstring_len );++  FT_LOCAL( FT_Error )+  cff_slot_load( CFF_GlyphSlot  glyph,+                 CFF_Size       size,+                 FT_UInt        glyph_index,+                 FT_Int32       load_flags );+++FT_END_HEADER++#endif /* __CFFGLOAD_H__ */+++/* END */
+ src/cff/cffload.c view
@@ -0,0 +1,1661 @@+/***************************************************************************/+/*                                                                         */+/*  cffload.c                                                              */+/*                                                                         */+/*    OpenType and CFF data/program tables loader (body).                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include FT_TYPE1_TABLES_H++#include "cffload.h"+#include "cffparse.h"++#include "cfferrs.h"+++#if 1++  static const FT_UShort  cff_isoadobe_charset[229] =+  {+      0,   1,   2,   3,   4,   5,   6,   7,+      8,   9,  10,  11,  12,  13,  14,  15,+     16,  17,  18,  19,  20,  21,  22,  23,+     24,  25,  26,  27,  28,  29,  30,  31,+     32,  33,  34,  35,  36,  37,  38,  39,+     40,  41,  42,  43,  44,  45,  46,  47,+     48,  49,  50,  51,  52,  53,  54,  55,+     56,  57,  58,  59,  60,  61,  62,  63,+     64,  65,  66,  67,  68,  69,  70,  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, 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, 157, 158, 159,+    160, 161, 162, 163, 164, 165, 166, 167,+    168, 169, 170, 171, 172, 173, 174, 175,+    176, 177, 178, 179, 180, 181, 182, 183,+    184, 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,+    216, 217, 218, 219, 220, 221, 222, 223,+    224, 225, 226, 227, 228+  };++  static const FT_UShort  cff_expert_charset[166] =+  {+      0,   1, 229, 230, 231, 232, 233, 234,+    235, 236, 237, 238,  13,  14,  15,  99,+    239, 240, 241, 242, 243, 244, 245, 246,+    247, 248,  27,  28, 249, 250, 251, 252,+    253, 254, 255, 256, 257, 258, 259, 260,+    261, 262, 263, 264, 265, 266, 109, 110,+    267, 268, 269, 270, 271, 272, 273, 274,+    275, 276, 277, 278, 279, 280, 281, 282,+    283, 284, 285, 286, 287, 288, 289, 290,+    291, 292, 293, 294, 295, 296, 297, 298,+    299, 300, 301, 302, 303, 304, 305, 306,+    307, 308, 309, 310, 311, 312, 313, 314,+    315, 316, 317, 318, 158, 155, 163, 319,+    320, 321, 322, 323, 324, 325, 326, 150,+    164, 169, 327, 328, 329, 330, 331, 332,+    333, 334, 335, 336, 337, 338, 339, 340,+    341, 342, 343, 344, 345, 346, 347, 348,+    349, 350, 351, 352, 353, 354, 355, 356,+    357, 358, 359, 360, 361, 362, 363, 364,+    365, 366, 367, 368, 369, 370, 371, 372,+    373, 374, 375, 376, 377, 378+  };++  static const FT_UShort  cff_expertsubset_charset[87] =+  {+      0,   1, 231, 232, 235, 236, 237, 238,+     13,  14,  15,  99, 239, 240, 241, 242,+    243, 244, 245, 246, 247, 248,  27,  28,+    249, 250, 251, 253, 254, 255, 256, 257,+    258, 259, 260, 261, 262, 263, 264, 265,+    266, 109, 110, 267, 268, 269, 270, 272,+    300, 301, 302, 305, 314, 315, 158, 155,+    163, 320, 321, 322, 323, 324, 325, 326,+    150, 164, 169, 327, 328, 329, 330, 331,+    332, 333, 334, 335, 336, 337, 338, 339,+    340, 341, 342, 343, 344, 345, 346+  };++  static const FT_UShort  cff_standard_encoding[256] =+  {+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      1,   2,   3,   4,   5,   6,   7,   8,+      9,  10,  11,  12,  13,  14,  15,  16,+     17,  18,  19,  20,  21,  22,  23,  24,+     25,  26,  27,  28,  29,  30,  31,  32,+     33,  34,  35,  36,  37,  38,  39,  40,+     41,  42,  43,  44,  45,  46,  47,  48,+     49,  50,  51,  52,  53,  54,  55,  56,+     57,  58,  59,  60,  61,  62,  63,  64,+     65,  66,  67,  68,  69,  70,  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,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,  96,  97,  98,  99, 100, 101, 102,+    103, 104, 105, 106, 107, 108, 109, 110,+      0, 111, 112, 113, 114,   0, 115, 116,+    117, 118, 119, 120, 121, 122,   0, 123,+      0, 124, 125, 126, 127, 128, 129, 130,+    131,   0, 132, 133,   0, 134, 135, 136,+    137,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0, 138,   0, 139,   0,   0,   0,   0,+    140, 141, 142, 143,   0,   0,   0,   0,+      0, 144,   0,   0,   0, 145,   0,   0,+    146, 147, 148, 149,   0,   0,   0,   0+  };++  static const FT_UShort  cff_expert_encoding[256] =+  {+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      1, 229, 230,   0, 231, 232, 233, 234,+    235, 236, 237, 238,  13,  14,  15,  99,+    239, 240, 241, 242, 243, 244, 245, 246,+    247, 248,  27,  28, 249, 250, 251, 252,+      0, 253, 254, 255, 256, 257,   0,   0,+      0, 258,   0,   0, 259, 260, 261, 262,+      0,   0, 263, 264, 265,   0, 266, 109,+    110, 267, 268, 269,   0, 270, 271, 272,+    273, 274, 275, 276, 277, 278, 279, 280,+    281, 282, 283, 284, 285, 286, 287, 288,+    289, 290, 291, 292, 293, 294, 295, 296,+    297, 298, 299, 300, 301, 302, 303,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0,   0,   0,   0,   0,   0,   0,   0,+      0, 304, 305, 306,   0,   0, 307, 308,+    309, 310, 311,   0, 312,   0,   0, 312,+      0,   0, 314, 315,   0,   0, 316, 317,+    318,   0,   0,   0, 158, 155, 163, 319,+    320, 321, 322, 323, 324, 325,   0,   0,+    326, 150, 164, 169, 327, 328, 329, 330,+    331, 332, 333, 334, 335, 336, 337, 338,+    339, 340, 341, 342, 343, 344, 345, 346,+    347, 348, 349, 350, 351, 352, 353, 354,+    355, 356, 357, 358, 359, 360, 361, 362,+    363, 364, 365, 366, 367, 368, 369, 370,+    371, 372, 373, 374, 375, 376, 377, 378+  };++#endif /* 1 */+++  FT_LOCAL_DEF( FT_UShort )+  cff_get_standard_encoding( FT_UInt  charcode )+  {+    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]+                                       : 0 );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cffload+++  /* read an offset from the index's stream current position */+  static FT_ULong+  cff_index_read_offset( CFF_Index  idx,+                         FT_Error  *errorp )+  {+    FT_Error   error;+    FT_Stream  stream = idx->stream;+    FT_Byte    tmp[4];+    FT_ULong   result = 0;+++    if ( !FT_STREAM_READ( tmp, idx->off_size ) )+    {+      FT_Int  nn;+++      for ( nn = 0; nn < idx->off_size; nn++ )+        result = ( result << 8 ) | tmp[nn];+    }++    *errorp = error;+    return result;+  }+++  static FT_Error+  cff_index_init( CFF_Index  idx,+                  FT_Stream  stream,+                  FT_Bool    load )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;+    FT_UShort  count;+++    FT_MEM_ZERO( idx, sizeof ( *idx ) );++    idx->stream = stream;+    idx->start  = FT_STREAM_POS();+    if ( !FT_READ_USHORT( count ) &&+         count > 0                )+    {+      FT_Byte   offsize;+      FT_ULong  size;+++      /* there is at least one element; read the offset size,           */+      /* then access the offset table to compute the index's total size */+      if ( FT_READ_BYTE( offsize ) )+        goto Exit;++      if ( offsize < 1 || offsize > 4 )+      {+        error = CFF_Err_Invalid_Table;+        goto Exit;+      }++      idx->count    = count;+      idx->off_size = offsize;+      size          = (FT_ULong)( count + 1 ) * offsize;++      idx->data_offset = idx->start + 3 + size;++      if ( FT_STREAM_SKIP( size - offsize ) )+        goto Exit;++      size = cff_index_read_offset( idx, &error );+      if ( error )+        goto Exit;++      if ( size == 0 )+      {+        error = CFF_Err_Invalid_Table;+        goto Exit;+      }++      idx->data_size = --size;++      if ( load )+      {+        /* load the data */+        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )+          goto Exit;+      }+      else+      {+        /* skip the data */+        if ( FT_STREAM_SKIP( size ) )+          goto Exit;+      }+    }++  Exit:+    if ( error )+      FT_FREE( idx->offsets );++    return error;+  }+++  static void+  cff_index_done( CFF_Index  idx )+  {+    if ( idx->stream )+    {+      FT_Stream  stream = idx->stream;+      FT_Memory  memory = stream->memory;+++      if ( idx->bytes )+        FT_FRAME_RELEASE( idx->bytes );++      FT_FREE( idx->offsets );+      FT_MEM_ZERO( idx, sizeof ( *idx ) );+    }+  }+++  static FT_Error+  cff_index_load_offsets( CFF_Index  idx )+  {+    FT_Error   error  = CFF_Err_Ok;+    FT_Stream  stream = idx->stream;+    FT_Memory  memory = stream->memory;+++    if ( idx->count > 0 && idx->offsets == NULL )+    {+      FT_Byte    offsize = idx->off_size;+      FT_ULong   data_size;+      FT_Byte*   p;+      FT_Byte*   p_end;+      FT_ULong*  poff;+++      data_size = (FT_ULong)( idx->count + 1 ) * offsize;++      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||+           FT_STREAM_SEEK( idx->start + 3 )             ||+           FT_FRAME_ENTER( data_size )                  )+        goto Exit;++      poff   = idx->offsets;+      p      = (FT_Byte*)stream->cursor;+      p_end  = p + data_size;++      switch ( offsize )+      {+      case 1:+        for ( ; p < p_end; p++, poff++ )+          poff[0] = p[0];+        break;++      case 2:+        for ( ; p < p_end; p += 2, poff++ )+          poff[0] = FT_PEEK_USHORT( p );+        break;++      case 3:+        for ( ; p < p_end; p += 3, poff++ )+          poff[0] = FT_PEEK_OFF3( p );+        break;++      default:+        for ( ; p < p_end; p += 4, poff++ )+          poff[0] = FT_PEEK_ULONG( p );+      }++      FT_FRAME_EXIT();+    }++  Exit:+    if ( error )+      FT_FREE( idx->offsets );++    return error;+  }+++  /* Allocate a table containing pointers to an index's elements. */+  /* The `pool' argument makes this function convert the index    */+  /* entries to C-style strings (this is, NULL-terminated).       */+  static FT_Error+  cff_index_get_pointers( CFF_Index   idx,+                          FT_Byte***  table,+                          FT_Byte**   pool )+  {+    FT_Error   error     = CFF_Err_Ok;+    FT_Memory  memory    = idx->stream->memory;+    FT_Byte**  t;+    FT_Byte*   new_bytes = NULL;+++    *table = NULL;++    if ( idx->offsets == NULL )+    {+      error = cff_index_load_offsets( idx );+      if ( error )+        goto Exit;+    }++    if ( idx->count > 0                                        &&+         !FT_NEW_ARRAY( t, idx->count + 1 )                    &&+         ( !pool || !FT_ALLOC( new_bytes,+                               idx->data_size + idx->count ) ) )+    {+      FT_ULong  n, cur_offset;+      FT_ULong  extra = 0;+      FT_Byte*  org_bytes = idx->bytes;+++      /* at this point, `idx->offsets' can't be NULL */+      cur_offset = idx->offsets[0] - 1;++      /* sanity check */+      if ( cur_offset >= idx->data_size )+      {+        FT_TRACE0(( "cff_index_get_pointers:"+                    " invalid first offset value %d set to zero\n",+                    cur_offset ));+        cur_offset = 0;+      }++      if ( !pool )+        t[0] = org_bytes + cur_offset;+      else+        t[0] = new_bytes + cur_offset;++      for ( n = 1; n <= idx->count; n++ )+      {+        FT_ULong  next_offset = idx->offsets[n] - 1;+++        /* empty slot + two sanity checks for invalid offset tables */+        if ( next_offset == 0                                    ||+             next_offset < cur_offset                            ||+             ( next_offset >= idx->data_size && n < idx->count ) )+          next_offset = cur_offset;++        if ( !pool )+          t[n] = org_bytes + next_offset;+        else+        {+          t[n] = new_bytes + next_offset + extra;++          if ( next_offset != cur_offset )+          {+            FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );+            t[n][0] = '\0';+            t[n]   += 1;+            extra++;+          }+        }++        cur_offset = next_offset;+      }+      *table = t;++      if ( pool )+        *pool = new_bytes;+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_index_access_element( CFF_Index  idx,+                            FT_UInt    element,+                            FT_Byte**  pbytes,+                            FT_ULong*  pbyte_len )+  {+    FT_Error  error = CFF_Err_Ok;+++    if ( idx && idx->count > element )+    {+      /* compute start and end offsets */+      FT_Stream  stream = idx->stream;+      FT_ULong   off1, off2 = 0;+++      /* load offsets from file or the offset table */+      if ( !idx->offsets )+      {+        FT_ULong  pos = element * idx->off_size;+++        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )+          goto Exit;++        off1 = cff_index_read_offset( idx, &error );+        if ( error )+          goto Exit;++        if ( off1 != 0 )+        {+          do+          {+            element++;+            off2 = cff_index_read_offset( idx, &error );+          }+          while ( off2 == 0 && element < idx->count );+        }+      }+      else   /* use offsets table */+      {+        off1 = idx->offsets[element];+        if ( off1 )+        {+          do+          {+            element++;+            off2 = idx->offsets[element];++          } while ( off2 == 0 && element < idx->count );+        }+      }++      /* XXX: should check off2 does not exceed the end of this entry; */+      /*      at present, only truncate off2 at the end of this stream */+      if ( off2 > stream->size + 1                    ||+           idx->data_offset > stream->size - off2 + 1 )+      {+        FT_ERROR(( "cff_index_access_element:"+                   " offset to next entry (%d)"+                   " exceeds the end of stream (%d)\n",+                   off2, stream->size - idx->data_offset + 1 ));+        off2 = stream->size - idx->data_offset + 1;+      }++      /* access element */+      if ( off1 && off2 > off1 )+      {+        *pbyte_len = off2 - off1;++        if ( idx->bytes )+        {+          /* this index was completely loaded in memory, that's easy */+          *pbytes = idx->bytes + off1 - 1;+        }+        else+        {+          /* this index is still on disk/file, access it through a frame */+          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||+               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )+            goto Exit;+        }+      }+      else+      {+        /* empty index element */+        *pbytes    = 0;+        *pbyte_len = 0;+      }+    }+    else+      error = CFF_Err_Invalid_Argument;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  cff_index_forget_element( CFF_Index  idx,+                            FT_Byte**  pbytes )+  {+    if ( idx->bytes == 0 )+    {+      FT_Stream  stream = idx->stream;+++      FT_FRAME_RELEASE( *pbytes );+    }+  }+++  /* get an entry from Name INDEX */+  FT_LOCAL_DEF( FT_String* )+  cff_index_get_name( CFF_Font  font,+                      FT_UInt   element )+  {+    CFF_Index   idx = &font->name_index;+    FT_Memory   memory = idx->stream->memory;+    FT_Byte*    bytes;+    FT_ULong    byte_len;+    FT_Error    error;+    FT_String*  name = 0;+++    error = cff_index_access_element( idx, element, &bytes, &byte_len );+    if ( error )+      goto Exit;++    if ( !FT_ALLOC( name, byte_len + 1 ) )+    {+      FT_MEM_COPY( name, bytes, byte_len );+      name[byte_len] = 0;+    }+    cff_index_forget_element( idx, &bytes );++  Exit:+    return name;+  }+++  /* get an entry from String INDEX */+  FT_LOCAL_DEF( FT_String* )+  cff_index_get_string( CFF_Font  font,+                        FT_UInt   element )+  {+    return ( element < font->num_strings )+             ? (FT_String*)font->strings[element]+             : NULL;+  }+++  FT_LOCAL_DEF( FT_String* )+  cff_index_get_sid_string( CFF_Font  font,+                            FT_UInt   sid )+  {+    /* value 0xFFFFU indicates a missing dictionary entry */+    if ( sid == 0xFFFFU )+      return NULL;++    /* if it is not a standard string, return it */+    if ( sid > 390 )+      return cff_index_get_string( font, sid - 391 );++    /* CID-keyed CFF fonts don't have glyph names */+    if ( !font->psnames )+      return NULL;++    /* this is a standard string */+    return (FT_String *)font->psnames->adobe_std_strings( sid );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***   FD Select table support                                         ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/+++  static void+  CFF_Done_FD_Select( CFF_FDSelect  fdselect,+                      FT_Stream     stream )+  {+    if ( fdselect->data )+      FT_FRAME_RELEASE( fdselect->data );++    fdselect->data_size   = 0;+    fdselect->format      = 0;+    fdselect->range_count = 0;+  }+++  static FT_Error+  CFF_Load_FD_Select( CFF_FDSelect  fdselect,+                      FT_UInt       num_glyphs,+                      FT_Stream     stream,+                      FT_ULong      offset )+  {+    FT_Error  error;+    FT_Byte   format;+    FT_UInt   num_ranges;+++    /* read format */+    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )+      goto Exit;++    fdselect->format      = format;+    fdselect->cache_count = 0;   /* clear cache */++    switch ( format )+    {+    case 0:     /* format 0, that's simple */+      fdselect->data_size = num_glyphs;+      goto Load_Data;++    case 3:     /* format 3, a tad more complex */+      if ( FT_READ_USHORT( num_ranges ) )+        goto Exit;++      fdselect->data_size = num_ranges * 3 + 2;++    Load_Data:+      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )+        goto Exit;+      break;++    default:    /* hmm... that's wrong */+      error = CFF_Err_Invalid_File_Format;+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Byte )+  cff_fd_select_get( CFF_FDSelect  fdselect,+                     FT_UInt       glyph_index )+  {+    FT_Byte  fd = 0;+++    switch ( fdselect->format )+    {+    case 0:+      fd = fdselect->data[glyph_index];+      break;++    case 3:+      /* first, compare to cache */+      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <+                        fdselect->cache_count )+      {+        fd = fdselect->cache_fd;+        break;+      }++      /* then, lookup the ranges array */+      {+        FT_Byte*  p       = fdselect->data;+        FT_Byte*  p_limit = p + fdselect->data_size;+        FT_Byte   fd2;+        FT_UInt   first, limit;+++        first = FT_NEXT_USHORT( p );+        do+        {+          if ( glyph_index < first )+            break;++          fd2   = *p++;+          limit = FT_NEXT_USHORT( p );++          if ( glyph_index < limit )+          {+            fd = fd2;++            /* update cache */+            fdselect->cache_first = first;+            fdselect->cache_count = limit-first;+            fdselect->cache_fd    = fd2;+            break;+          }+          first = limit;++        } while ( p < p_limit );+      }+      break;++    default:+      ;+    }++    return fd;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /***                                                                   ***/+  /***   CFF font support                                                ***/+  /***                                                                   ***/+  /*************************************************************************/+  /*************************************************************************/++  static FT_Error+  cff_charset_compute_cids( CFF_Charset  charset,+                            FT_UInt      num_glyphs,+                            FT_Memory    memory )+  {+    FT_Error   error   = CFF_Err_Ok;+    FT_UInt    i;+    FT_Long    j;+    FT_UShort  max_cid = 0;+++    if ( charset->max_cid > 0 )+      goto Exit;++    for ( i = 0; i < num_glyphs; i++ )+    {+      if ( charset->sids[i] > max_cid )+        max_cid = charset->sids[i];+    }++    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )+      goto Exit;++    /* When multiple GIDs map to the same CID, we choose the lowest */+    /* GID.  This is not described in any spec, but it matches the  */+    /* behaviour of recent Acroread versions.                       */+    for ( j = num_glyphs - 1; j >= 0 ; j-- )+      charset->cids[charset->sids[j]] = (FT_UShort)j;++    charset->max_cid    = max_cid;+    charset->num_glyphs = num_glyphs;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_UInt )+  cff_charset_cid_to_gindex( CFF_Charset  charset,+                             FT_UInt      cid )+  {+    FT_UInt  result = 0;+++    if ( cid <= charset->max_cid )+      result = charset->cids[cid];++    return result;+  }+++  static void+  cff_charset_free_cids( CFF_Charset  charset,+                         FT_Memory    memory )+  {+    FT_FREE( charset->cids );+    charset->max_cid = 0;+  }+++  static void+  cff_charset_done( CFF_Charset  charset,+                    FT_Stream    stream )+  {+    FT_Memory  memory = stream->memory;+++    cff_charset_free_cids( charset, memory );++    FT_FREE( charset->sids );+    charset->format = 0;+    charset->offset = 0;+  }+++  static FT_Error+  cff_charset_load( CFF_Charset  charset,+                    FT_UInt      num_glyphs,+                    FT_Stream    stream,+                    FT_ULong     base_offset,+                    FT_ULong     offset,+                    FT_Bool      invert )+  {+    FT_Memory  memory = stream->memory;+    FT_Error   error  = CFF_Err_Ok;+    FT_UShort  glyph_sid;+++    /* If the the offset is greater than 2, we have to parse the */+    /* charset table.                                            */+    if ( offset > 2 )+    {+      FT_UInt  j;+++      charset->offset = base_offset + offset;++      /* Get the format of the table. */+      if ( FT_STREAM_SEEK( charset->offset ) ||+           FT_READ_BYTE( charset->format )   )+        goto Exit;++      /* Allocate memory for sids. */+      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )+        goto Exit;++      /* assign the .notdef glyph */+      charset->sids[0] = 0;++      switch ( charset->format )+      {+      case 0:+        if ( num_glyphs > 0 )+        {+          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )+            goto Exit;++          for ( j = 1; j < num_glyphs; j++ )+            charset->sids[j] = FT_GET_USHORT();++          FT_FRAME_EXIT();+        }+        break;++      case 1:+      case 2:+        {+          FT_UInt  nleft;+          FT_UInt  i;+++          j = 1;++          while ( j < num_glyphs )+          {+            /* Read the first glyph sid of the range. */+            if ( FT_READ_USHORT( glyph_sid ) )+              goto Exit;++            /* Read the number of glyphs in the range.  */+            if ( charset->format == 2 )+            {+              if ( FT_READ_USHORT( nleft ) )+                goto Exit;+            }+            else+            {+              if ( FT_READ_BYTE( nleft ) )+                goto Exit;+            }++            /* try to rescue some of the SIDs if `nleft' is too large */+            if ( glyph_sid > 0xFFFFL - nleft )+            {+              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"+                         " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));+              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );+            }++            /* Fill in the range of sids -- `nleft + 1' glyphs. */+            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )+              charset->sids[j] = glyph_sid;+          }+        }+        break;++      default:+        FT_ERROR(( "cff_charset_load: invalid table format\n" ));+        error = CFF_Err_Invalid_File_Format;+        goto Exit;+      }+    }+    else+    {+      /* Parse default tables corresponding to offset == 0, 1, or 2.  */+      /* CFF specification intimates the following:                   */+      /*                                                              */+      /* In order to use a predefined charset, the following must be  */+      /* true: The charset constructed for the glyphs in the font's   */+      /* charstrings dictionary must match the predefined charset in  */+      /* the first num_glyphs.                                        */++      charset->offset = offset;  /* record charset type */++      switch ( (FT_UInt)offset )+      {+      case 0:+        if ( num_glyphs > 229 )+        {+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"+                     "predefined charset (Adobe ISO-Latin)\n" ));+          error = CFF_Err_Invalid_File_Format;+          goto Exit;+        }++        /* Allocate memory for sids. */+        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )+          goto Exit;++        /* Copy the predefined charset into the allocated memory. */+        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );++        break;++      case 1:+        if ( num_glyphs > 166 )+        {+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"+                     "predefined charset (Adobe Expert)\n" ));+          error = CFF_Err_Invalid_File_Format;+          goto Exit;+        }++        /* Allocate memory for sids. */+        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )+          goto Exit;++        /* Copy the predefined charset into the allocated memory.     */+        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );++        break;++      case 2:+        if ( num_glyphs > 87 )+        {+          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"+                     "predefined charset (Adobe Expert Subset)\n" ));+          error = CFF_Err_Invalid_File_Format;+          goto Exit;+        }++        /* Allocate memory for sids. */+        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )+          goto Exit;++        /* Copy the predefined charset into the allocated memory.     */+        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );++        break;++      default:+        error = CFF_Err_Invalid_File_Format;+        goto Exit;+      }+    }++    /* we have to invert the `sids' array for subsetted CID-keyed fonts */+    if ( invert )+      error = cff_charset_compute_cids( charset, num_glyphs, memory );++  Exit:+    /* Clean up if there was an error. */+    if ( error )+    {+      FT_FREE( charset->sids );+      FT_FREE( charset->cids );+      charset->format = 0;+      charset->offset = 0;+      charset->sids   = 0;+    }++    return error;+  }+++  static void+  cff_encoding_done( CFF_Encoding  encoding )+  {+    encoding->format = 0;+    encoding->offset = 0;+    encoding->count  = 0;+  }+++  static FT_Error+  cff_encoding_load( CFF_Encoding  encoding,+                     CFF_Charset   charset,+                     FT_UInt       num_glyphs,+                     FT_Stream     stream,+                     FT_ULong      base_offset,+                     FT_ULong      offset )+  {+    FT_Error   error = CFF_Err_Ok;+    FT_UInt    count;+    FT_UInt    j;+    FT_UShort  glyph_sid;+    FT_UInt    glyph_code;+++    /* Check for charset->sids.  If we do not have this, we fail. */+    if ( !charset->sids )+    {+      error = CFF_Err_Invalid_File_Format;+      goto Exit;+    }++    /* Zero out the code to gid/sid mappings. */+    for ( j = 0; j < 256; j++ )+    {+      encoding->sids [j] = 0;+      encoding->codes[j] = 0;+    }++    /* Note: The encoding table in a CFF font is indexed by glyph index;  */+    /* the first encoded glyph index is 1.  Hence, we read the character  */+    /* code (`glyph_code') at index j and make the assignment:            */+    /*                                                                    */+    /*    encoding->codes[glyph_code] = j + 1                             */+    /*                                                                    */+    /* We also make the assignment:                                       */+    /*                                                                    */+    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */+    /*                                                                    */+    /* This gives us both a code to GID and a code to SID mapping.        */++    if ( offset > 1 )+    {+      encoding->offset = base_offset + offset;++      /* we need to parse the table to determine its size */+      if ( FT_STREAM_SEEK( encoding->offset ) ||+           FT_READ_BYTE( encoding->format )   ||+           FT_READ_BYTE( count )              )+        goto Exit;++      switch ( encoding->format & 0x7F )+      {+      case 0:+        {+          FT_Byte*  p;+++          /* By convention, GID 0 is always ".notdef" and is never */+          /* coded in the font.  Hence, the number of codes found  */+          /* in the table is `count+1'.                            */+          /*                                                       */+          encoding->count = count + 1;++          if ( FT_FRAME_ENTER( count ) )+            goto Exit;++          p = (FT_Byte*)stream->cursor;++          for ( j = 1; j <= count; j++ )+          {+            glyph_code = *p++;++            /* Make sure j is not too big. */+            if ( j < num_glyphs )+            {+              /* Assign code to GID mapping. */+              encoding->codes[glyph_code] = (FT_UShort)j;++              /* Assign code to SID mapping. */+              encoding->sids[glyph_code] = charset->sids[j];+            }+          }++          FT_FRAME_EXIT();+        }+        break;++      case 1:+        {+          FT_UInt  nleft;+          FT_UInt  i = 1;+          FT_UInt  k;+++          encoding->count = 0;++          /* Parse the Format1 ranges. */+          for ( j = 0;  j < count; j++, i += nleft )+          {+            /* Read the first glyph code of the range. */+            if ( FT_READ_BYTE( glyph_code ) )+              goto Exit;++            /* Read the number of codes in the range. */+            if ( FT_READ_BYTE( nleft ) )+              goto Exit;++            /* Increment nleft, so we read `nleft + 1' codes/sids. */+            nleft++;++            /* compute max number of character codes */+            if ( (FT_UInt)nleft > encoding->count )+              encoding->count = nleft;++            /* Fill in the range of codes/sids. */+            for ( k = i; k < nleft + i; k++, glyph_code++ )+            {+              /* Make sure k is not too big. */+              if ( k < num_glyphs && glyph_code < 256 )+              {+                /* Assign code to GID mapping. */+                encoding->codes[glyph_code] = (FT_UShort)k;++                /* Assign code to SID mapping. */+                encoding->sids[glyph_code] = charset->sids[k];+              }+            }+          }++          /* simple check; one never knows what can be found in a font */+          if ( encoding->count > 256 )+            encoding->count = 256;+        }+        break;++      default:+        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));+        error = CFF_Err_Invalid_File_Format;+        goto Exit;+      }++      /* Parse supplemental encodings, if any. */+      if ( encoding->format & 0x80 )+      {+        FT_UInt  gindex;+++        /* count supplements */+        if ( FT_READ_BYTE( count ) )+          goto Exit;++        for ( j = 0; j < count; j++ )+        {+          /* Read supplemental glyph code. */+          if ( FT_READ_BYTE( glyph_code ) )+            goto Exit;++          /* Read the SID associated with this glyph code. */+          if ( FT_READ_USHORT( glyph_sid ) )+            goto Exit;++          /* Assign code to SID mapping. */+          encoding->sids[glyph_code] = glyph_sid;++          /* First, look up GID which has been assigned to */+          /* SID glyph_sid.                                */+          for ( gindex = 0; gindex < num_glyphs; gindex++ )+          {+            if ( charset->sids[gindex] == glyph_sid )+            {+              encoding->codes[glyph_code] = (FT_UShort)gindex;+              break;+            }+          }+        }+      }+    }+    else+    {+      /* We take into account the fact a CFF font can use a predefined */+      /* encoding without containing all of the glyphs encoded by this */+      /* encoding (see the note at the end of section 12 in the CFF    */+      /* specification).                                               */++      switch ( (FT_UInt)offset )+      {+      case 0:+        /* First, copy the code to SID mapping. */+        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );+        goto Populate;++      case 1:+        /* First, copy the code to SID mapping. */+        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );++      Populate:+        /* Construct code to GID mapping from code to SID mapping */+        /* and charset.                                           */++        encoding->count = 0;++        error = cff_charset_compute_cids( charset, num_glyphs,+                                          stream->memory );+        if ( error )+          goto Exit;++        for ( j = 0; j < 256; j++ )+        {+          FT_UInt  sid = encoding->sids[j];+          FT_UInt  gid = 0;+++          if ( sid )+            gid = cff_charset_cid_to_gindex( charset, sid );++          if ( gid != 0 )+          {+            encoding->codes[j] = (FT_UShort)gid;+            encoding->count    = j + 1;+          }+          else+          {+            encoding->codes[j] = 0;+            encoding->sids [j] = 0;+          }+        }+        break;++      default:+        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));+        error = CFF_Err_Invalid_File_Format;+        goto Exit;+      }+    }++  Exit:++    /* Clean up if there was an error. */+    return error;+  }+++  static FT_Error+  cff_subfont_load( CFF_SubFont  font,+                    CFF_Index    idx,+                    FT_UInt      font_index,+                    FT_Stream    stream,+                    FT_ULong     base_offset,+                    FT_Library   library )+  {+    FT_Error         error;+    CFF_ParserRec    parser;+    FT_Byte*         dict = NULL;+    FT_ULong         dict_len;+    CFF_FontRecDict  top  = &font->font_dict;+    CFF_Private      priv = &font->private_dict;+++    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );++    /* set defaults */+    FT_MEM_ZERO( top, sizeof ( *top ) );++    top->underline_position  = -100L << 16;+    top->underline_thickness = 50L << 16;+    top->charstring_type     = 2;+    top->font_matrix.xx      = 0x10000L;+    top->font_matrix.yy      = 0x10000L;+    top->cid_count           = 8720;++    /* we use the implementation specific SID value 0xFFFF to indicate */+    /* missing entries                                                 */+    top->version             = 0xFFFFU;+    top->notice              = 0xFFFFU;+    top->copyright           = 0xFFFFU;+    top->full_name           = 0xFFFFU;+    top->family_name         = 0xFFFFU;+    top->weight              = 0xFFFFU;+    top->embedded_postscript = 0xFFFFU;++    top->cid_registry        = 0xFFFFU;+    top->cid_ordering        = 0xFFFFU;+    top->cid_font_name       = 0xFFFFU;++    error = cff_index_access_element( idx, font_index, &dict, &dict_len );+    if ( !error )+      error = cff_parser_run( &parser, dict, dict + dict_len );++    cff_index_forget_element( idx, &dict );++    if ( error )+      goto Exit;++    /* if it is a CID font, we stop there */+    if ( top->cid_registry != 0xFFFFU )+      goto Exit;++    /* parse the private dictionary, if any */+    if ( top->private_offset && top->private_size )+    {+      /* set defaults */+      FT_MEM_ZERO( priv, sizeof ( *priv ) );++      priv->blue_shift       = 7;+      priv->blue_fuzz        = 1;+      priv->lenIV            = -1;+      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );+      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );++      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );++      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||+           FT_FRAME_ENTER( font->font_dict.private_size )                 )+        goto Exit;++      error = cff_parser_run( &parser,+                              (FT_Byte*)stream->cursor,+                              (FT_Byte*)stream->limit );+      FT_FRAME_EXIT();+      if ( error )+        goto Exit;++      /* ensure that `num_blue_values' is even */+      priv->num_blue_values &= ~1;+    }++    /* read the local subrs, if any */+    if ( priv->local_subrs_offset )+    {+      if ( FT_STREAM_SEEK( base_offset + top->private_offset ++                           priv->local_subrs_offset ) )+        goto Exit;++      error = cff_index_init( &font->local_subrs_index, stream, 1 );+      if ( error )+        goto Exit;++      error = cff_index_get_pointers( &font->local_subrs_index,+                                      &font->local_subrs, NULL );+      if ( error )+        goto Exit;+    }++  Exit:+    return error;+  }+++  static void+  cff_subfont_done( FT_Memory    memory,+                    CFF_SubFont  subfont )+  {+    if ( subfont )+    {+      cff_index_done( &subfont->local_subrs_index );+      FT_FREE( subfont->local_subrs );+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_font_load( FT_Library library,+                 FT_Stream  stream,+                 FT_Int     face_index,+                 CFF_Font   font,+                 FT_Bool    pure_cff )+  {+    static const FT_Frame_Field  cff_header_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  CFF_FontRec++      FT_FRAME_START( 4 ),+        FT_FRAME_BYTE( version_major ),+        FT_FRAME_BYTE( version_minor ),+        FT_FRAME_BYTE( header_size ),+        FT_FRAME_BYTE( absolute_offsize ),+      FT_FRAME_END+    };++    FT_Error         error;+    FT_Memory        memory = stream->memory;+    FT_ULong         base_offset;+    CFF_FontRecDict  dict;+    CFF_IndexRec     string_index;+++    FT_ZERO( font );+    FT_ZERO( &string_index );++    font->stream = stream;+    font->memory = memory;+    dict         = &font->top_font.font_dict;+    base_offset  = FT_STREAM_POS();++    /* read CFF font header */+    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )+      goto Exit;++    /* check format */+    if ( font->version_major   != 1 ||+         font->header_size      < 4 ||+         font->absolute_offsize > 4 )+    {+      FT_TRACE2(( "[not a CFF font header]\n" ));+      error = CFF_Err_Unknown_File_Format;+      goto Exit;+    }++    /* skip the rest of the header */+    if ( FT_STREAM_SKIP( font->header_size - 4 ) )+      goto Exit;++    /* read the name, top dict, string and global subrs index */+    if ( FT_SET_ERROR( cff_index_init( &font->name_index,+                                       stream, 0 ) )                  ||+         FT_SET_ERROR( cff_index_init( &font->font_dict_index,+                                       stream, 0 ) )                  ||+         FT_SET_ERROR( cff_index_init( &string_index,+                                       stream, 1 ) )                  ||+         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,+                                       stream, 1 ) )                  ||+         FT_SET_ERROR( cff_index_get_pointers( &string_index,+                                               &font->strings,+                                               &font->string_pool ) ) )+      goto Exit;++    font->num_strings = string_index.count;++    /* well, we don't really forget the `disabled' fonts... */+    font->num_faces = font->name_index.count;+    if ( face_index >= (FT_Int)font->num_faces )+    {+      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",+                 face_index ));+      error = CFF_Err_Invalid_Argument;+    }++    /* in case of a font format check, simply exit now */+    if ( face_index < 0 )+      goto Exit;++    /* now, parse the top-level font dictionary */+    error = cff_subfont_load( &font->top_font,+                              &font->font_dict_index,+                              face_index,+                              stream,+                              base_offset,+                              library );+    if ( error )+      goto Exit;++    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )+      goto Exit;++    error = cff_index_init( &font->charstrings_index, stream, 0 );+    if ( error )+      goto Exit;++    /* now, check for a CID font */+    if ( dict->cid_registry != 0xFFFFU )+    {+      CFF_IndexRec  fd_index;+      CFF_SubFont   sub;+      FT_UInt       idx;+++      /* this is a CID-keyed font, we must now allocate a table of */+      /* sub-fonts, then load each of them separately              */+      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )+        goto Exit;++      error = cff_index_init( &fd_index, stream, 0 );+      if ( error )+        goto Exit;++      if ( fd_index.count > CFF_MAX_CID_FONTS )+      {+        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));+        goto Fail_CID;+      }++      /* allocate & read each font dict independently */+      font->num_subfonts = fd_index.count;+      if ( FT_NEW_ARRAY( sub, fd_index.count ) )+        goto Fail_CID;++      /* set up pointer table */+      for ( idx = 0; idx < fd_index.count; idx++ )+        font->subfonts[idx] = sub + idx;++      /* now load each subfont independently */+      for ( idx = 0; idx < fd_index.count; idx++ )+      {+        sub = font->subfonts[idx];+        error = cff_subfont_load( sub, &fd_index, idx,+                                  stream, base_offset, library );+        if ( error )+          goto Fail_CID;+      }++      /* now load the FD Select array */+      error = CFF_Load_FD_Select( &font->fd_select,+                                  font->charstrings_index.count,+                                  stream,+                                  base_offset + dict->cid_fd_select_offset );++    Fail_CID:+      cff_index_done( &fd_index );++      if ( error )+        goto Exit;+    }+    else+      font->num_subfonts = 0;++    /* read the charstrings index now */+    if ( dict->charstrings_offset == 0 )+    {+      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));+      error = CFF_Err_Unknown_File_Format;+      goto Exit;+    }++    font->num_glyphs = font->charstrings_index.count;++    error = cff_index_get_pointers( &font->global_subrs_index,+                                    &font->global_subrs, NULL );++    if ( error )+      goto Exit;++    /* read the Charset and Encoding tables if available */+    if ( font->num_glyphs > 0 )+    {+      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );+++      error = cff_charset_load( &font->charset, font->num_glyphs, stream,+                                base_offset, dict->charset_offset, invert );+      if ( error )+        goto Exit;++      /* CID-keyed CFFs don't have an encoding */+      if ( dict->cid_registry == 0xFFFFU )+      {+        error = cff_encoding_load( &font->encoding,+                                   &font->charset,+                                   font->num_glyphs,+                                   stream,+                                   base_offset,+                                   dict->encoding_offset );+        if ( error )+          goto Exit;+      }+    }++    /* get the font name (/CIDFontName for CID-keyed fonts, */+    /* /FontName otherwise)                                 */+    font->font_name = cff_index_get_name( font, face_index );++  Exit:+    cff_index_done( &string_index );++    return error;+  }+++  FT_LOCAL_DEF( void )+  cff_font_done( CFF_Font  font )+  {+    FT_Memory  memory = font->memory;+    FT_UInt    idx;+++    cff_index_done( &font->global_subrs_index );+    cff_index_done( &font->font_dict_index );+    cff_index_done( &font->name_index );+    cff_index_done( &font->charstrings_index );++    /* release font dictionaries, but only if working with */+    /* a CID keyed CFF font                                */+    if ( font->num_subfonts > 0 )+    {+      for ( idx = 0; idx < font->num_subfonts; idx++ )+        cff_subfont_done( memory, font->subfonts[idx] );++      /* the subfonts array has been allocated as a single block */+      FT_FREE( font->subfonts[0] );+    }++    cff_encoding_done( &font->encoding );+    cff_charset_done( &font->charset, font->stream );++    cff_subfont_done( memory, &font->top_font );++    CFF_Done_FD_Select( &font->fd_select, font->stream );++    FT_FREE( font->font_info );++    FT_FREE( font->font_name );+    FT_FREE( font->global_subrs );+    FT_FREE( font->strings );+    FT_FREE( font->string_pool );+  }+++/* END */
+ src/cff/cffload.h view
@@ -0,0 +1,83 @@+/***************************************************************************/+/*                                                                         */+/*  cffload.h                                                              */+/*                                                                         */+/*    OpenType & CFF data/program tables loader (specification).           */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFLOAD_H__+#define __CFFLOAD_H__+++#include <ft2build.h>+#include "cfftypes.h"+++FT_BEGIN_HEADER++  FT_LOCAL( FT_UShort )+  cff_get_standard_encoding( FT_UInt  charcode );+++  FT_LOCAL( FT_String* )+  cff_index_get_string( CFF_Font  font,+                        FT_UInt   element );++  FT_LOCAL( FT_String* )+  cff_index_get_sid_string( CFF_Font  font,+                            FT_UInt   sid );+++  FT_LOCAL( FT_Error )+  cff_index_access_element( CFF_Index  idx,+                            FT_UInt    element,+                            FT_Byte**  pbytes,+                            FT_ULong*  pbyte_len );++  FT_LOCAL( void )+  cff_index_forget_element( CFF_Index  idx,+                            FT_Byte**  pbytes );++  FT_LOCAL( FT_String* )+  cff_index_get_name( CFF_Font  font,+                      FT_UInt   element );+++  FT_LOCAL( FT_UInt )+  cff_charset_cid_to_gindex( CFF_Charset  charset,+                             FT_UInt      cid );+++  FT_LOCAL( FT_Error )+  cff_font_load( FT_Library library, +                 FT_Stream  stream,+                 FT_Int     face_index,+                 CFF_Font   font,+                 FT_Bool    pure_cff );++  FT_LOCAL( void )+  cff_font_done( CFF_Font  font );+++  FT_LOCAL( FT_Byte )+  cff_fd_select_get( CFF_FDSelect  fdselect,+                     FT_UInt       glyph_index );+++FT_END_HEADER++#endif /* __CFFLOAD_H__ */+++/* END */
+ src/cff/cffobjs.c view
@@ -0,0 +1,1008 @@+/***************************************************************************/+/*                                                                         */+/*  cffobjs.c                                                              */+/*                                                                         */+/*    OpenType objects manager (body).                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_STREAM_H+#include FT_ERRORS_H+#include FT_TRUETYPE_IDS_H+#include FT_TRUETYPE_TAGS_H+#include FT_INTERNAL_SFNT_H+#include "cffobjs.h"+#include "cffload.h"+#include "cffcmap.h"+#include "cfferrs.h"+#include "cffpic.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cffobjs+++  /*************************************************************************/+  /*                                                                       */+  /*                            SIZE FUNCTIONS                             */+  /*                                                                       */+  /*  Note that we store the global hints in the size's `internal' root    */+  /*  field.                                                               */+  /*                                                                       */+  /*************************************************************************/+++  static PSH_Globals_Funcs+  cff_size_get_globals_funcs( CFF_Size  size )+  {+    CFF_Face          face     = (CFF_Face)size->root.face;+    CFF_Font          font     = (CFF_Font)face->extra.data;+    PSHinter_Service  pshinter = font->pshinter;+    FT_Module         module;+++    module = FT_Get_Module( size->root.face->driver->root.library,+                            "pshinter" );+    return ( module && pshinter && pshinter->get_globals_funcs )+           ? pshinter->get_globals_funcs( module )+           : 0;+  }+++  FT_LOCAL_DEF( void )+  cff_size_done( FT_Size  cffsize )        /* CFF_Size */+  {+    CFF_Size      size     = (CFF_Size)cffsize;+    CFF_Face      face     = (CFF_Face)size->root.face;+    CFF_Font      font     = (CFF_Font)face->extra.data;+    CFF_Internal  internal = (CFF_Internal)cffsize->internal;+++    if ( internal )+    {+      PSH_Globals_Funcs  funcs;+++      funcs = cff_size_get_globals_funcs( size );+      if ( funcs )+      {+        FT_UInt  i;+++        funcs->destroy( internal->topfont );++        for ( i = font->num_subfonts; i > 0; i-- )+          funcs->destroy( internal->subfonts[i - 1] );+      }++      /* `internal' is freed by destroy_size (in ftobjs.c) */+    }+  }+++  /* CFF and Type 1 private dictionaries have slightly different      */+  /* structures; we need to synthesize a Type 1 dictionary on the fly */++  static void+  cff_make_private_dict( CFF_SubFont  subfont,+                         PS_Private   priv )+  {+    CFF_Private  cpriv = &subfont->private_dict;+    FT_UInt      n, count;+++    FT_MEM_ZERO( priv, sizeof ( *priv ) );++    count = priv->num_blue_values = cpriv->num_blue_values;+    for ( n = 0; n < count; n++ )+      priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];++    count = priv->num_other_blues = cpriv->num_other_blues;+    for ( n = 0; n < count; n++ )+      priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];++    count = priv->num_family_blues = cpriv->num_family_blues;+    for ( n = 0; n < count; n++ )+      priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];++    count = priv->num_family_other_blues = cpriv->num_family_other_blues;+    for ( n = 0; n < count; n++ )+      priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];++    priv->blue_scale = cpriv->blue_scale;+    priv->blue_shift = (FT_Int)cpriv->blue_shift;+    priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;++    priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;+    priv->standard_height[0] = (FT_UShort)cpriv->standard_height;++    count = priv->num_snap_widths = cpriv->num_snap_widths;+    for ( n = 0; n < count; n++ )+      priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];++    count = priv->num_snap_heights = cpriv->num_snap_heights;+    for ( n = 0; n < count; n++ )+      priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];++    priv->force_bold     = cpriv->force_bold;+    priv->language_group = cpriv->language_group;+    priv->lenIV          = cpriv->lenIV;+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_size_init( FT_Size  cffsize )         /* CFF_Size */+  {+    CFF_Size           size  = (CFF_Size)cffsize;+    FT_Error           error = CFF_Err_Ok;+    PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );+++    if ( funcs )+    {+      CFF_Face      face     = (CFF_Face)cffsize->face;+      CFF_Font      font     = (CFF_Font)face->extra.data;+      CFF_Internal  internal;++      PS_PrivateRec  priv;+      FT_Memory      memory = cffsize->face->memory;++      FT_UInt  i;+++      if ( FT_NEW( internal ) )+        goto Exit;++      cff_make_private_dict( &font->top_font, &priv );+      error = funcs->create( cffsize->face->memory, &priv,+                             &internal->topfont );+      if ( error )+        goto Exit;++      for ( i = font->num_subfonts; i > 0; i-- )+      {+        CFF_SubFont  sub = font->subfonts[i - 1];+++        cff_make_private_dict( sub, &priv );+        error = funcs->create( cffsize->face->memory, &priv,+                               &internal->subfonts[i - 1] );+        if ( error )+          goto Exit;+      }++      cffsize->internal = (FT_Size_Internal)(void*)internal;+    }++    size->strike_index = 0xFFFFFFFFUL;++  Exit:+    return error;+  }+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  FT_LOCAL_DEF( FT_Error )+  cff_size_select( FT_Size   size,+                   FT_ULong  strike_index )+  {+    CFF_Size           cffsize = (CFF_Size)size;+    PSH_Globals_Funcs  funcs;+++    cffsize->strike_index = strike_index;++    FT_Select_Metrics( size->face, strike_index );++    funcs = cff_size_get_globals_funcs( cffsize );++    if ( funcs )+    {+      CFF_Face      face     = (CFF_Face)size->face;+      CFF_Font      font     = (CFF_Font)face->extra.data;+      CFF_Internal  internal = (CFF_Internal)size->internal;++      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;+      FT_UInt   i;+++      funcs->set_scale( internal->topfont,+                        size->metrics.x_scale, size->metrics.y_scale,+                        0, 0 );++      for ( i = font->num_subfonts; i > 0; i-- )+      {+        CFF_SubFont  sub     = font->subfonts[i - 1];+        FT_ULong     sub_upm = sub->font_dict.units_per_em;+        FT_Pos       x_scale, y_scale;+++        if ( top_upm != sub_upm )+        {+          x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );+          y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );+        }+        else+        {+          x_scale = size->metrics.x_scale;+          y_scale = size->metrics.y_scale;+        }++        funcs->set_scale( internal->subfonts[i - 1],+                          x_scale, y_scale, 0, 0 );+      }+    }++    return CFF_Err_Ok;+  }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */+++  FT_LOCAL_DEF( FT_Error )+  cff_size_request( FT_Size          size,+                    FT_Size_Request  req )+  {+    CFF_Size           cffsize = (CFF_Size)size;+    PSH_Globals_Funcs  funcs;+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++    if ( FT_HAS_FIXED_SIZES( size->face ) )+    {+      CFF_Face      cffface = (CFF_Face)size->face;+      SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;+      FT_ULong      strike_index;+++      if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )+        cffsize->strike_index = 0xFFFFFFFFUL;+      else+        return cff_size_select( size, strike_index );+    }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */++    FT_Request_Metrics( size->face, req );++    funcs = cff_size_get_globals_funcs( cffsize );++    if ( funcs )+    {+      CFF_Face      cffface  = (CFF_Face)size->face;+      CFF_Font      font     = (CFF_Font)cffface->extra.data;+      CFF_Internal  internal = (CFF_Internal)size->internal;++      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;+      FT_UInt   i;+++      funcs->set_scale( internal->topfont,+                        size->metrics.x_scale, size->metrics.y_scale,+                        0, 0 );++      for ( i = font->num_subfonts; i > 0; i-- )+      {+        CFF_SubFont  sub     = font->subfonts[i - 1];+        FT_ULong     sub_upm = sub->font_dict.units_per_em;+        FT_Pos       x_scale, y_scale;+++        if ( top_upm != sub_upm )+        {+          x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );+          y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );+        }+        else+        {+          x_scale = size->metrics.x_scale;+          y_scale = size->metrics.y_scale;+        }++        funcs->set_scale( internal->subfonts[i - 1],+                          x_scale, y_scale, 0, 0 );+      }+    }++    return CFF_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                            SLOT  FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  cff_slot_done( FT_GlyphSlot  slot )+  {+    slot->internal->glyph_hints = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_slot_init( FT_GlyphSlot  slot )+  {+    CFF_Face          face     = (CFF_Face)slot->face;+    CFF_Font          font     = (CFF_Font)face->extra.data;+    PSHinter_Service  pshinter = font->pshinter;+++    if ( pshinter )+    {+      FT_Module  module;+++      module = FT_Get_Module( slot->face->driver->root.library,+                              "pshinter" );+      if ( module )+      {+        T2_Hints_Funcs  funcs;+++        funcs = pshinter->get_t2_funcs( module );+        slot->internal->glyph_hints = (void*)funcs;+      }+    }++    return CFF_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                           FACE  FUNCTIONS                             */+  /*                                                                       */+  /*************************************************************************/++  static FT_String*+  cff_strcpy( FT_Memory         memory,+              const FT_String*  source )+  {+    FT_Error    error;+    FT_String*  result;+++    (void)FT_STRDUP( result, source );++    FT_UNUSED( error );++    return result;+  }+++  /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */+  /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */+  /* have been seen in the wild.                                      */++  static void+  remove_subset_prefix( FT_String*  name )+  {+    FT_Int32  idx             = 0;+    FT_Int32  length          = strlen( name ) + 1;+    FT_Bool   continue_search = 1;+ ++    while ( continue_search )+    {+      if ( length >= 7 && name[6] == '+' )+      {+        for ( idx = 0; idx < 6; idx++ )+        {+          /* ASCII uppercase letters */+          if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )+            continue_search = 0;+        }++        if ( continue_search )+        {+          for ( idx = 7; idx < length; idx++ )+            name[idx - 7] = name[idx];+        }+      }+      else+        continue_search = 0;+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_face_init( FT_Stream      stream,+                 FT_Face        cffface,        /* CFF_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    CFF_Face            face = (CFF_Face)cffface;+    FT_Error            error;+    SFNT_Service        sfnt;+    FT_Service_PsCMaps  psnames;+    PSHinter_Service    pshinter;+    FT_Bool             pure_cff    = 1;+    FT_Bool             sfnt_format = 0;+    FT_Library library = cffface->driver->root.library;+++    sfnt = (SFNT_Service)FT_Get_Module_Interface(+             library, "sfnt" );+    if ( !sfnt )+      goto Bad_Format;++    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );++    pshinter = (PSHinter_Service)FT_Get_Module_Interface(+                 library, "pshinter" );++    /* create input stream from resource */+    if ( FT_STREAM_SEEK( 0 ) )+      goto Exit;++    /* check whether we have a valid OpenType file */+    error = sfnt->init_face( stream, face, face_index, num_params, params );+    if ( !error )+    {+      if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */+      {+        FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));+        goto Bad_Format;+      }++      /* if we are performing a simple font format check, exit immediately */+      if ( face_index < 0 )+        return CFF_Err_Ok;++      /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */+      if ( face_index > 0 )+      {+        FT_ERROR(( "cff_face_init: invalid face index\n" ));+        error = CFF_Err_Invalid_Argument;+        goto Exit;+      }++      sfnt_format = 1;++      /* now, the font can be either an OpenType/CFF font, or an SVG CEF */+      /* font; in the latter case it doesn't have a `head' table         */+      error = face->goto_table( face, TTAG_head, stream, 0 );+      if ( !error )+      {+        pure_cff = 0;++        /* load font directory */+        error = sfnt->load_face( stream, face, 0, num_params, params );+        if ( error )+          goto Exit;+      }+      else+      {+        /* load the `cmap' table explicitly */+        error = sfnt->load_cmap( face, stream );+        if ( error )+          goto Exit;++        /* XXX: we don't load the GPOS table, as OpenType Layout     */+        /* support will be added later to a layout library on top of */+        /* FreeType 2                                                */+      }++      /* now load the CFF part of the file */+      error = face->goto_table( face, TTAG_CFF, stream, 0 );+      if ( error )+        goto Exit;+    }+    else+    {+      /* rewind to start of file; we are going to load a pure-CFF font */+      if ( FT_STREAM_SEEK( 0 ) )+        goto Exit;+      error = CFF_Err_Ok;+    }++    /* now load and parse the CFF table in the file */+    {+      CFF_Font         cff;+      CFF_FontRecDict  dict;+      FT_Memory        memory = cffface->memory;+      FT_Int32         flags;+      FT_UInt          i;+++      if ( FT_NEW( cff ) )+        goto Exit;++      face->extra.data = cff;+      error = cff_font_load( library, stream, face_index, cff, pure_cff );+      if ( error )+        goto Exit;++      cff->pshinter = pshinter;+      cff->psnames  = psnames;++      cffface->face_index = face_index;++      /* Complement the root flags with some interesting information. */+      /* Note that this is only necessary for pure CFF and CEF fonts; */+      /* SFNT based fonts use the `name' table instead.               */++      cffface->num_glyphs = cff->num_glyphs;++      dict = &cff->top_font.font_dict;++      /* we need the `PSNames' module for CFF and CEF formats */+      /* which aren't CID-keyed                               */+      if ( dict->cid_registry == 0xFFFFU && !psnames )+      {+        FT_ERROR(( "cff_face_init:"+                   " cannot open CFF & CEF fonts\n"+                   "              "+                   " without the `PSNames' module\n" ));+        goto Bad_Format;+      }++      if ( !dict->units_per_em )+        dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;++      /* Normalize the font matrix so that `matrix->xx' is 1; the */+      /* scaling is done with `units_per_em' then (at this point, */+      /* it already contains the scaling factor, but without      */+      /* normalization of the matrix).                            */+      /*                                                          */+      /* Note that the offsets must be expressed in integer font  */+      /* units.                                                   */++      {+        FT_Matrix*  matrix = &dict->font_matrix;+        FT_Vector*  offset = &dict->font_offset;+        FT_ULong*   upm    = &dict->units_per_em;+        FT_Fixed    temp   = FT_ABS( matrix->yy );+++        if ( temp != 0x10000L )+        {+          *upm = FT_DivFix( *upm, temp );++          matrix->xx = FT_DivFix( matrix->xx, temp );+          matrix->yx = FT_DivFix( matrix->yx, temp );+          matrix->xy = FT_DivFix( matrix->xy, temp );+          matrix->yy = FT_DivFix( matrix->yy, temp );+          offset->x  = FT_DivFix( offset->x,  temp );+          offset->y  = FT_DivFix( offset->y,  temp );+        }++        offset->x >>= 16;+        offset->y >>= 16;+      }++      for ( i = cff->num_subfonts; i > 0; i-- )+      {+        CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;+        CFF_FontRecDict  top = &cff->top_font.font_dict;++        FT_Matrix*  matrix;+        FT_Vector*  offset;+        FT_ULong*   upm;+        FT_Fixed    temp;+++        if ( sub->units_per_em )+        {+          FT_Long  scaling;+++          if ( top->units_per_em > 1 && sub->units_per_em > 1 )+            scaling = FT_MIN( top->units_per_em, sub->units_per_em );+          else+            scaling = 1;++          FT_Matrix_Multiply_Scaled( &top->font_matrix,+                                     &sub->font_matrix,+                                     scaling );+          FT_Vector_Transform_Scaled( &sub->font_offset,+                                      &top->font_matrix,+                                      scaling );++          sub->units_per_em = FT_MulDiv( sub->units_per_em,+                                         top->units_per_em,+                                         scaling );+        }+        else+        {+          sub->font_matrix = top->font_matrix;+          sub->font_offset = top->font_offset;++          sub->units_per_em = top->units_per_em;+        }++        matrix = &sub->font_matrix;+        offset = &sub->font_offset;+        upm    = &sub->units_per_em;+        temp   = FT_ABS( matrix->yy );++        if ( temp != 0x10000L )+        {+          *upm = FT_DivFix( *upm, temp );++          /* if *upm is larger than 100*1000 we divide by 1000 --     */+          /* this can happen if e.g. there is no top-font FontMatrix  */+          /* and the subfont FontMatrix already contains the complete */+          /* scaling for the subfont (see section 5.11 of the PLRM)   */++          /* 100 is a heuristic value */++          if ( *upm > 100L * 1000L )+            *upm = ( *upm + 500 ) / 1000;++          matrix->xx = FT_DivFix( matrix->xx, temp );+          matrix->yx = FT_DivFix( matrix->yx, temp );+          matrix->xy = FT_DivFix( matrix->xy, temp );+          matrix->yy = FT_DivFix( matrix->yy, temp );+          offset->x  = FT_DivFix( offset->x,  temp );+          offset->y  = FT_DivFix( offset->y,  temp );+        }++        offset->x >>= 16;+        offset->y >>= 16;+      }++      if ( pure_cff )+      {+        char*  style_name = NULL;+++        /* set up num_faces */+        cffface->num_faces = cff->num_faces;++        /* compute number of glyphs */+        if ( dict->cid_registry != 0xFFFFU )+          cffface->num_glyphs = cff->charset.max_cid + 1;+        else+          cffface->num_glyphs = cff->charstrings_index.count;++        /* set global bbox, as well as EM size */+        cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;+        cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;+        /* no `U' suffix here to 0xFFFF! */+        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;+        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;++        cffface->units_per_EM = (FT_UShort)( dict->units_per_em );++        cffface->ascender  = (FT_Short)( cffface->bbox.yMax );+        cffface->descender = (FT_Short)( cffface->bbox.yMin );++        cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );+        if ( cffface->height < cffface->ascender - cffface->descender )+          cffface->height = (FT_Short)( cffface->ascender - cffface->descender );++        cffface->underline_position  =+          (FT_Short)( dict->underline_position >> 16 );+        cffface->underline_thickness =+          (FT_Short)( dict->underline_thickness >> 16 );++        /* retrieve font family & style name */+        cffface->family_name = cff_index_get_name( cff, face_index );+        if ( cffface->family_name )+        {+          char*  full   = cff_index_get_sid_string( cff,+                                                    dict->full_name );+          char*  fullp  = full;+          char*  family = cffface->family_name;+          char*  family_name = NULL;+++          remove_subset_prefix( cffface->family_name ); ++          if ( dict->family_name )+          {+            family_name = cff_index_get_sid_string( cff,+                                                    dict->family_name );+            if ( family_name )+              family = family_name;+          }++          /* We try to extract the style name from the full name.   */+          /* We need to ignore spaces and dashes during the search. */+          if ( full && family )+          {+            while ( *fullp )+            {+              /* skip common characters at the start of both strings */+              if ( *fullp == *family )+              {+                family++;+                fullp++;+                continue;+              }++              /* ignore spaces and dashes in full name during comparison */+              if ( *fullp == ' ' || *fullp == '-' )+              {+                fullp++;+                continue;+              }++              /* ignore spaces and dashes in family name during comparison */+              if ( *family == ' ' || *family == '-' )+              {+                family++;+                continue;+              }++              if ( !*family && *fullp )+              {+                /* The full name begins with the same characters as the  */+                /* family name, with spaces and dashes removed.  In this */+                /* case, the remaining string in `fullp' will be used as */+                /* the style name.                                       */+                style_name = cff_strcpy( memory, fullp );+              }+              break;+            }+          }+        }+        else+        {+          char  *cid_font_name =+                   cff_index_get_sid_string( cff,+                                             dict->cid_font_name );+++          /* do we have a `/FontName' for a CID-keyed font? */+          if ( cid_font_name )+            cffface->family_name = cff_strcpy( memory, cid_font_name );+        }++        if ( style_name )+          cffface->style_name = style_name;+        else+          /* assume "Regular" style if we don't know better */+          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );++        /*******************************************************************/+        /*                                                                 */+        /* Compute face flags.                                             */+        /*                                                                 */+        flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE   | /* scalable outlines */+                             FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */+                             FT_FACE_FLAG_HINTER );    /* has native hinter */++        if ( sfnt_format )+          flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;++        /* fixed width font? */+        if ( dict->is_fixed_pitch )+          flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;++  /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */+#if 0+        /* kerning available? */+        if ( face->kern_pairs )+          flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;+#endif++        cffface->face_flags = flags;++        /*******************************************************************/+        /*                                                                 */+        /* Compute style flags.                                            */+        /*                                                                 */+        flags = 0;++        if ( dict->italic_angle )+          flags |= FT_STYLE_FLAG_ITALIC;++        {+          char  *weight = cff_index_get_sid_string( cff,+                                                    dict->weight );+++          if ( weight )+            if ( !ft_strcmp( weight, "Bold"  ) ||+                 !ft_strcmp( weight, "Black" ) )+              flags |= FT_STYLE_FLAG_BOLD;+        }++        /* double check */+        if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )+          if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||+               !ft_strncmp( cffface->style_name, "Black", 5 ) )+            flags |= FT_STYLE_FLAG_BOLD;++        cffface->style_flags = flags;+      }+++#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES+      /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */+      /* has unset this flag because of the 3.0 `post' table.          */+      if ( dict->cid_registry == 0xFFFFU )+        cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;+#endif++      if ( dict->cid_registry != 0xFFFFU && pure_cff )+        cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;+++      /*******************************************************************/+      /*                                                                 */+      /* Compute char maps.                                              */+      /*                                                                 */++      /* Try to synthesize a Unicode charmap if there is none available */+      /* already.  If an OpenType font contains a Unicode "cmap", we    */+      /* will use it, whatever be in the CFF part of the file.          */+      {+        FT_CharMapRec  cmaprec;+        FT_CharMap     cmap;+        FT_UInt        nn;+        CFF_Encoding   encoding = &cff->encoding;+++        for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )+        {+          cmap = cffface->charmaps[nn];++          /* Windows Unicode? */+          if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&+               cmap->encoding_id == TT_MS_ID_UNICODE_CS   )+            goto Skip_Unicode;++          /* Apple Unicode platform id? */+          if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )+            goto Skip_Unicode; /* Apple Unicode */+        }++        /* since CID-keyed fonts don't contain glyph names, we can't */+        /* construct a cmap                                          */+        if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )+          goto Exit;++#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "cff_face_init: no Unicode cmap is found, "+                     "and too many subtables (%d) to add synthesized cmap\n",+                     nn ));+          goto Exit;+        }+#endif++        /* we didn't find a Unicode charmap -- synthesize one */+        cmaprec.face        = cffface;+        cmaprec.platform_id = TT_PLATFORM_MICROSOFT;+        cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;+        cmaprec.encoding    = FT_ENCODING_UNICODE;++        nn = (FT_UInt)cffface->num_charmaps;++        error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,+                             &cmaprec, NULL );+        if ( error && FT_Err_No_Unicode_Glyph_Name != error )+          goto Exit;+        error = FT_Err_Ok;++        /* if no Unicode charmap was previously selected, select this one */+        if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )+          cffface->charmap = cffface->charmaps[nn];++      Skip_Unicode:+#ifdef FT_MAX_CHARMAP_CACHEABLE+        if ( nn > FT_MAX_CHARMAP_CACHEABLE )+        {+          FT_ERROR(( "cff_face_init: Unicode cmap is found, "+                     "but too many preceding subtables (%d) to access\n",+                     nn - 1 ));+          goto Exit;+        }+#endif+        if ( encoding->count > 0 )+        {+          FT_CMap_Class  clazz;+++          cmaprec.face        = cffface;+          cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */++          if ( encoding->offset == 0 )+          {+            cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;+            cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;+          }+          else if ( encoding->offset == 1 )+          {+            cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;+            cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;+          }+          else+          {+            cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;+            cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;+          }++          error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );+        }+      }+    }++  Exit:+    return error;++  Bad_Format:+    error = CFF_Err_Unknown_File_Format;+    goto Exit;+  }+++  FT_LOCAL_DEF( void )+  cff_face_done( FT_Face  cffface )         /* CFF_Face */+  {+    CFF_Face      face = (CFF_Face)cffface;+    FT_Memory     memory;+    SFNT_Service  sfnt;+++    if ( !face )+      return;++    memory = cffface->memory;+    sfnt   = (SFNT_Service)face->sfnt;++    if ( sfnt )+      sfnt->done_face( face );++    {+      CFF_Font  cff = (CFF_Font)face->extra.data;+++      if ( cff )+      {+        cff_font_done( cff );+        FT_FREE( face->extra.data );+      }+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  cff_driver_init( FT_Module  module )+  {+    FT_UNUSED( module );++    return CFF_Err_Ok;+  }+++  FT_LOCAL_DEF( void )+  cff_driver_done( FT_Module  module )+  {+    FT_UNUSED( module );+  }+++/* END */
+ src/cff/cffobjs.h view
@@ -0,0 +1,181 @@+/***************************************************************************/+/*                                                                         */+/*  cffobjs.h                                                              */+/*                                                                         */+/*    OpenType objects manager (specification).                            */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFOBJS_H__+#define __CFFOBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include "cfftypes.h"+#include FT_INTERNAL_TRUETYPE_TYPES_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CFF_Driver                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an OpenType driver object.                             */+  /*                                                                       */+  typedef struct CFF_DriverRec_*  CFF_Driver;++  typedef TT_Face  CFF_Face;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CFF_Size                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an OpenType size object.                               */+  /*                                                                       */+  typedef struct  CFF_SizeRec_+  {+    FT_SizeRec  root;+    FT_ULong    strike_index;    /* 0xFFFFFFFF to indicate invalid */++  } CFF_SizeRec, *CFF_Size;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CFF_GlyphSlot                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to an OpenType glyph slot object.                         */+  /*                                                                       */+  typedef struct  CFF_GlyphSlotRec_+  {+    FT_GlyphSlotRec  root;++    FT_Bool          hint;+    FT_Bool          scaled;++    FT_Fixed         x_scale;+    FT_Fixed         y_scale;++  } CFF_GlyphSlotRec, *CFF_GlyphSlot;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CFF_Internal                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The interface to the `internal' field of `FT_Size'.                */+  /*                                                                       */+  typedef struct  CFF_InternalRec_+  {+    PSH_Globals  topfont;+    PSH_Globals  subfonts[CFF_MAX_CID_FONTS];++  } CFF_InternalRec, *CFF_Internal;+++  /*************************************************************************/+  /*                                                                       */+  /* Subglyph transformation record.                                       */+  /*                                                                       */+  typedef struct  CFF_Transform_+  {+    FT_Fixed    xx, xy;     /* transformation matrix coefficients */+    FT_Fixed    yx, yy;+    FT_F26Dot6  ox, oy;     /* offsets        */++  } CFF_Transform;+++  /***********************************************************************/+  /*                                                                     */+  /* TrueType driver class.                                              */+  /*                                                                     */+  typedef struct  CFF_DriverRec_+  {+    FT_DriverRec  root;+    void*         extension_component;++  } CFF_DriverRec;+++  FT_LOCAL( FT_Error )+  cff_size_init( FT_Size  size );           /* CFF_Size */++  FT_LOCAL( void )+  cff_size_done( FT_Size  size );           /* CFF_Size */++  FT_LOCAL( FT_Error )+  cff_size_request( FT_Size          size,+                    FT_Size_Request  req );++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  FT_LOCAL( FT_Error )+  cff_size_select( FT_Size   size,+                   FT_ULong  strike_index );++#endif++  FT_LOCAL( void )+  cff_slot_done( FT_GlyphSlot  slot );++  FT_LOCAL( FT_Error )+  cff_slot_init( FT_GlyphSlot  slot );+++  /*************************************************************************/+  /*                                                                       */+  /* Face functions                                                        */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  cff_face_init( FT_Stream      stream,+                 FT_Face        face,           /* CFF_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params );++  FT_LOCAL( void )+  cff_face_done( FT_Face  face );               /* CFF_Face */+++  /*************************************************************************/+  /*                                                                       */+  /* Driver functions                                                      */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  cff_driver_init( FT_Module  module );++  FT_LOCAL( void )+  cff_driver_done( FT_Module  module );+++FT_END_HEADER++#endif /* __CFFOBJS_H__ */+++/* END */
+ src/cff/cffparse.c view
@@ -0,0 +1,924 @@+/***************************************************************************/+/*                                                                         */+/*  cffparse.c                                                             */+/*                                                                         */+/*    CFF token stream parser (body)                                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "cffparse.h"+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_DEBUG_H++#include "cfferrs.h"+#include "cffpic.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cffparse+++++  FT_LOCAL_DEF( void )+  cff_parser_init( CFF_Parser  parser,+                   FT_UInt     code,+                   void*       object,+                   FT_Library  library)+  {+    FT_MEM_ZERO( parser, sizeof ( *parser ) );++    parser->top         = parser->stack;+    parser->object_code = code;+    parser->object      = object;+    parser->library     = library;+  }+++  /* read an integer */+  static FT_Long+  cff_parse_integer( FT_Byte*  start,+                     FT_Byte*  limit )+  {+    FT_Byte*  p   = start;+    FT_Int    v   = *p++;+    FT_Long   val = 0;+++    if ( v == 28 )+    {+      if ( p + 2 > limit )+        goto Bad;++      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );+      p  += 2;+    }+    else if ( v == 29 )+    {+      if ( p + 4 > limit )+        goto Bad;++      val = ( (FT_Long)p[0] << 24 ) |+            ( (FT_Long)p[1] << 16 ) |+            ( (FT_Long)p[2] <<  8 ) |+                       p[3];+      p += 4;+    }+    else if ( v < 247 )+    {+      val = v - 139;+    }+    else if ( v < 251 )+    {+      if ( p + 1 > limit )+        goto Bad;++      val = ( v - 247 ) * 256 + p[0] + 108;+      p++;+    }+    else+    {+      if ( p + 1 > limit )+        goto Bad;++      val = -( v - 251 ) * 256 - p[0] - 108;+      p++;+    }++  Exit:+    return val;++  Bad:+    val = 0;+    goto Exit;+  }+++  static const FT_Long power_tens[] =+  {+    1L,+    10L,+    100L,+    1000L,+    10000L,+    100000L,+    1000000L,+    10000000L,+    100000000L,+    1000000000L+  };+++  /* read a real */+  static FT_Fixed+  cff_parse_real( FT_Byte*  start,+                  FT_Byte*  limit,+                  FT_Long   power_ten,+                  FT_Long*  scaling )+  {+    FT_Byte*  p = start;+    FT_UInt   nib;+    FT_UInt   phase;++    FT_Long   result, number, exponent;+    FT_Int    sign = 0, exponent_sign = 0;+    FT_Long   exponent_add, integer_length, fraction_length;+++    if ( scaling )+      *scaling = 0;++    result = 0;++    number   = 0;+    exponent = 0;++    exponent_add    = 0;+    integer_length  = 0;+    fraction_length = 0;++    /* First of all, read the integer part. */+    phase = 4;++    for (;;)+    {+      /* If we entered this iteration with phase == 4, we need to */+      /* read a new byte.  This also skips past the initial 0x1E. */+      if ( phase )+      {+        p++;++        /* Make sure we don't read past the end. */+        if ( p >= limit )+          goto Exit;+      }++      /* Get the nibble. */+      nib   = ( p[0] >> phase ) & 0xF;+      phase = 4 - phase;++      if ( nib == 0xE )+        sign = 1;+      else if ( nib > 9 )+        break;+      else+      {+        /* Increase exponent if we can't add the digit. */+        if ( number >= 0xCCCCCCCL )+          exponent_add++;+        /* Skip leading zeros. */+        else if ( nib || number )+        {+          integer_length++;+          number = number * 10 + nib;+        }+      }+    }++    /* Read fraction part, if any. */+    if ( nib == 0xa )+      for (;;)+      {+        /* If we entered this iteration with phase == 4, we need */+        /* to read a new byte.                                   */+        if ( phase )+        {+          p++;++          /* Make sure we don't read past the end. */+          if ( p >= limit )+            goto Exit;+        }++        /* Get the nibble. */+        nib   = ( p[0] >> phase ) & 0xF;+        phase = 4 - phase;+        if ( nib >= 10 )+          break;++        /* Skip leading zeros if possible. */+        if ( !nib && !number )+          exponent_add--;+        /* Only add digit if we don't overflow. */+        else if ( number < 0xCCCCCCCL && fraction_length < 9 )+        {+          fraction_length++;+          number = number * 10 + nib;+        }+      }++    /* Read exponent, if any. */+    if ( nib == 12 )+    {+      exponent_sign = 1;+      nib           = 11;+    }++    if ( nib == 11 )+    {+      for (;;)+      {+        /* If we entered this iteration with phase == 4, */+        /* we need to read a new byte.                   */+        if ( phase )+        {+          p++;++          /* Make sure we don't read past the end. */+          if ( p >= limit )+            goto Exit;+        }++        /* Get the nibble. */+        nib   = ( p[0] >> phase ) & 0xF;+        phase = 4 - phase;+        if ( nib >= 10 )+          break;++        exponent = exponent * 10 + nib;++        /* Arbitrarily limit exponent. */+        if ( exponent > 1000 )+          goto Exit;+      }++      if ( exponent_sign )+        exponent = -exponent;+    }++    /* We don't check `power_ten' and `exponent_add'. */+    exponent += power_ten + exponent_add;++    if ( scaling )+    {+      /* Only use `fraction_length'. */+      fraction_length += integer_length;+      exponent        += integer_length;++      if ( fraction_length <= 5 )+      {+        if ( number > 0x7FFFL )+        {+          result   = FT_DivFix( number, 10 );+          *scaling = exponent - fraction_length + 1;+        }+        else+        {+          if ( exponent > 0 )+          {+            FT_Long  new_fraction_length, shift;+++            /* Make `scaling' as small as possible. */+            new_fraction_length = FT_MIN( exponent, 5 );+            exponent           -= new_fraction_length;+            shift               = new_fraction_length - fraction_length;++            number *= power_tens[shift];+            if ( number > 0x7FFFL )+            {+              number   /= 10;+              exponent += 1;+            }+          }+          else+            exponent -= fraction_length;++          result   = number << 16;+          *scaling = exponent;+        }+      }+      else+      {+        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )+        {+          result   = FT_DivFix( number, power_tens[fraction_length - 4] );+          *scaling = exponent - 4;+        }+        else+        {+          result   = FT_DivFix( number, power_tens[fraction_length - 5] );+          *scaling = exponent - 5;+        }+      }+    }+    else+    {+      integer_length  += exponent;+      fraction_length -= exponent;++      /* Check for overflow and underflow. */+      if ( FT_ABS( integer_length ) > 5 )+        goto Exit;++      /* Remove non-significant digits. */+      if ( integer_length < 0 )+      {+        number          /= power_tens[-integer_length];+        fraction_length += integer_length;+      }++      /* this can only happen if exponent was non-zero */+      if ( fraction_length == 10 )+      {+        number          /= 10;+        fraction_length -= 1;+      }++      /* Convert into 16.16 format. */+      if ( fraction_length > 0 )+      {+        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )+          goto Exit;++        result = FT_DivFix( number, power_tens[fraction_length] );+      }+      else+      {+        number *= power_tens[-fraction_length];++        if ( number > 0x7FFFL )+          goto Exit;++        result = number << 16;+      }+    }++    if ( sign )+      result = -result;++  Exit:+    return result;+  }+++  /* read a number, either integer or real */+  static FT_Long+  cff_parse_num( FT_Byte**  d )+  {+    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )+                     :   cff_parse_integer( d[0], d[1] );+  }+++  /* read a floating point number, either integer or real */+  static FT_Fixed+  cff_parse_fixed( FT_Byte**  d )+  {+    return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )+                     : cff_parse_integer( d[0], d[1] ) << 16;+  }+++  /* read a floating point number, either integer or real, */+  /* but return `10^scaling' times the number read in      */+  static FT_Fixed+  cff_parse_fixed_scaled( FT_Byte**  d,+                          FT_Long    scaling )+  {+    return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )+                     : ( cff_parse_integer( d[0], d[1] ) *+                           power_tens[scaling] ) << 16;+  }+++  /* read a floating point number, either integer or real,     */+  /* and return it as precise as possible -- `scaling' returns */+  /* the scaling factor (as a power of 10)                     */+  static FT_Fixed+  cff_parse_fixed_dynamic( FT_Byte**  d,+                           FT_Long*   scaling )+  {+    FT_ASSERT( scaling );++    if ( **d == 30 )+      return cff_parse_real( d[0], d[1], 0, scaling );+    else+    {+      FT_Long  number;+      FT_Int   integer_length;+++      number = cff_parse_integer( d[0], d[1] );++      if ( number > 0x7FFFL )+      {+        for ( integer_length = 5; integer_length < 10; integer_length++ )+          if ( number < power_tens[integer_length] )+            break;++        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )+        {+          *scaling = integer_length - 4;+          return FT_DivFix( number, power_tens[integer_length - 4] );+        }+        else+        {+          *scaling = integer_length - 5;+          return FT_DivFix( number, power_tens[integer_length - 5] );+        }+      }+      else+      {+        *scaling = 0;+        return number << 16;+      }+    }+  }+++  static FT_Error+  cff_parse_font_matrix( CFF_Parser  parser )+  {+    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;+    FT_Matrix*       matrix = &dict->font_matrix;+    FT_Vector*       offset = &dict->font_offset;+    FT_ULong*        upm    = &dict->units_per_em;+    FT_Byte**        data   = parser->stack;+    FT_Error         error  = CFF_Err_Stack_Underflow;+++    if ( parser->top >= parser->stack + 6 )+    {+      FT_Long  scaling;+++      error = CFF_Err_Ok;++      /* We expect a well-formed font matrix, this is, the matrix elements */+      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */+      /* loss of precision, we use the magnitude of element `xx' to scale  */+      /* all other elements.  The scaling factor is then contained in the  */+      /* `units_per_em' value.                                             */++      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );++      scaling = -scaling;++      if ( scaling < 0 || scaling > 9 )+      {+        /* Return default matrix in case of unlikely values. */+        matrix->xx = 0x10000L;+        matrix->yx = 0;+        matrix->yx = 0;+        matrix->yy = 0x10000L;+        offset->x  = 0;+        offset->y  = 0;+        *upm       = 1;++        goto Exit;+      }++      matrix->yx = cff_parse_fixed_scaled( data++, scaling );+      matrix->xy = cff_parse_fixed_scaled( data++, scaling );+      matrix->yy = cff_parse_fixed_scaled( data++, scaling );+      offset->x  = cff_parse_fixed_scaled( data++, scaling );+      offset->y  = cff_parse_fixed_scaled( data,   scaling );++      *upm = power_tens[scaling];+    }++  Exit:+    return error;+  }+++  static FT_Error+  cff_parse_font_bbox( CFF_Parser  parser )+  {+    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;+    FT_BBox*         bbox = &dict->font_bbox;+    FT_Byte**        data = parser->stack;+    FT_Error         error;+++    error = CFF_Err_Stack_Underflow;++    if ( parser->top >= parser->stack + 4 )+    {+      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );+      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );+      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );+      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );+      error = CFF_Err_Ok;+    }++    return error;+  }+++  static FT_Error+  cff_parse_private_dict( CFF_Parser  parser )+  {+    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;+    FT_Byte**        data = parser->stack;+    FT_Error         error;+++    error = CFF_Err_Stack_Underflow;++    if ( parser->top >= parser->stack + 2 )+    {+      dict->private_size   = cff_parse_num( data++ );+      dict->private_offset = cff_parse_num( data   );+      error = CFF_Err_Ok;+    }++    return error;+  }+++  static FT_Error+  cff_parse_cid_ros( CFF_Parser  parser )+  {+    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;+    FT_Byte**        data = parser->stack;+    FT_Error         error;+++    error = CFF_Err_Stack_Underflow;++    if ( parser->top >= parser->stack + 3 )+    {+      dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );+      dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );+      if ( **data == 30 )+        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));+      dict->cid_supplement = cff_parse_num( data );+      if ( dict->cid_supplement < 0 )+        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",+                   dict->cid_supplement ));+      error = CFF_Err_Ok;+    }++    return error;+  }+++#define CFF_FIELD_NUM( code, name ) \+          CFF_FIELD( code, name, cff_kind_num )+#define CFF_FIELD_FIXED( code, name ) \+          CFF_FIELD( code, name, cff_kind_fixed )+#define CFF_FIELD_FIXED_1000( code, name ) \+          CFF_FIELD( code, name, cff_kind_fixed_thousand )+#define CFF_FIELD_STRING( code, name ) \+          CFF_FIELD( code, name, cff_kind_string )+#define CFF_FIELD_BOOL( code, name ) \+          CFF_FIELD( code, name, cff_kind_bool )+#define CFF_FIELD_DELTA( code, name, max ) \+          CFF_FIELD( code, name, cff_kind_delta )++#define CFFCODE_TOPDICT  0x1000+#define CFFCODE_PRIVATE  0x2000++#ifndef FT_CONFIG_OPTION_PIC++#define CFF_FIELD_CALLBACK( code, name ) \+          {                              \+            cff_kind_callback,           \+            code | CFFCODE,              \+            0, 0,                        \+            cff_parse_ ## name,          \+            0, 0                         \+          },++#undef  CFF_FIELD+#define CFF_FIELD( code, name, kind ) \+          {                          \+            kind,                    \+            code | CFFCODE,          \+            FT_FIELD_OFFSET( name ), \+            FT_FIELD_SIZE( name ),   \+            0, 0, 0                  \+          },++#undef  CFF_FIELD_DELTA+#define CFF_FIELD_DELTA( code, name, max ) \+        {                                  \+          cff_kind_delta,                  \+          code | CFFCODE,                  \+          FT_FIELD_OFFSET( name ),         \+          FT_FIELD_SIZE_DELTA( name ),     \+          0,                               \+          max,                             \+          FT_FIELD_OFFSET( num_ ## name )  \+        },++  static const CFF_Field_Handler  cff_field_handlers[] =+  {++#include "cfftoken.h"++    { 0, 0, 0, 0, 0, 0, 0 }+  };+++#else /* FT_CONFIG_OPTION_PIC */++  void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)+  {+    FT_Memory memory = library->memory;+    if ( clazz )+      FT_FREE( clazz );+  }++  FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)+  {+    CFF_Field_Handler*  clazz;+    FT_Error          error;+    FT_Memory memory = library->memory;+    int i=0;++#undef CFF_FIELD+#undef CFF_FIELD_DELTA+#undef CFF_FIELD_CALLBACK+#define CFF_FIELD_CALLBACK( code, name ) i++;+#define CFF_FIELD( code, name, kind ) i++;+#define CFF_FIELD_DELTA( code, name, max ) i++;++#include "cfftoken.h"+    i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/++    if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )+      return error;++    i=0;+#undef CFF_FIELD+#undef CFF_FIELD_DELTA+#undef CFF_FIELD_CALLBACK++#define CFF_FIELD_CALLBACK( code_, name_ )                                   \+    clazz[i].kind = cff_kind_callback;                                       \+    clazz[i].code = code_ | CFFCODE;                                         \+    clazz[i].offset = 0;                                                     \+    clazz[i].size = 0;                                                       \+    clazz[i].reader = cff_parse_ ## name_;                                   \+    clazz[i].array_max = 0;                                                  \+    clazz[i].count_offset = 0;                                               \+    i++;++#undef  CFF_FIELD+#define CFF_FIELD( code_, name_, kind_ )                                     \+    clazz[i].kind = kind_;                                                   \+    clazz[i].code = code_ | CFFCODE;                                         \+    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \+    clazz[i].size = FT_FIELD_SIZE( name_ );                                  \+    clazz[i].reader = 0;                                                     \+    clazz[i].array_max = 0;                                                  \+    clazz[i].count_offset = 0;                                               \+    i++;                                                                     \++#undef  CFF_FIELD_DELTA+#define CFF_FIELD_DELTA( code_, name_, max_ )                                \+    clazz[i].kind = cff_kind_delta;                                          \+    clazz[i].code = code_ | CFFCODE;                                         \+    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \+    clazz[i].size = FT_FIELD_SIZE_DELTA( name_ );                            \+    clazz[i].reader = 0;                                                     \+    clazz[i].array_max = max_;                                               \+    clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ );                \+    i++;++#include "cfftoken.h"++    clazz[i].kind = 0;+    clazz[i].code = 0;+    clazz[i].offset = 0;+    clazz[i].size = 0;+    clazz[i].reader = 0;+    clazz[i].array_max = 0;+    clazz[i].count_offset = 0;++    *output_class = clazz;+    return CFF_Err_Ok;+  }+++#endif /* FT_CONFIG_OPTION_PIC */+++  FT_LOCAL_DEF( FT_Error )+  cff_parser_run( CFF_Parser  parser,+                  FT_Byte*    start,+                  FT_Byte*    limit )+  {+    FT_Byte*    p       = start;+    FT_Error    error   = CFF_Err_Ok;+    FT_Library  library = parser->library;+    FT_UNUSED(library);+++    parser->top    = parser->stack;+    parser->start  = start;+    parser->limit  = limit;+    parser->cursor = start;++    while ( p < limit )+    {+      FT_UInt  v = *p;+++      if ( v >= 27 && v != 31 )+      {+        /* it's a number; we will push its position on the stack */+        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )+          goto Stack_Overflow;++        *parser->top ++ = p;++        /* now, skip it */+        if ( v == 30 )+        {+          /* skip real number */+          p++;+          for (;;)+          {+            /* An unterminated floating point number at the */+            /* end of a dictionary is invalid but harmless. */+            if ( p >= limit )+              goto Exit;+            v = p[0] >> 4;+            if ( v == 15 )+              break;+            v = p[0] & 0xF;+            if ( v == 15 )+              break;+            p++;+          }+        }+        else if ( v == 28 )+          p += 2;+        else if ( v == 29 )+          p += 4;+        else if ( v > 246 )+          p += 1;+      }+      else+      {+        /* This is not a number, hence it's an operator.  Compute its code */+        /* and look for it in our current list.                            */++        FT_UInt                   code;+        FT_UInt                   num_args = (FT_UInt)+                                             ( parser->top - parser->stack );+        const CFF_Field_Handler*  field;+++        *parser->top = p;+        code = v;+        if ( v == 12 )+        {+          /* two byte operator */+          p++;+          if ( p >= limit )+            goto Syntax_Error;++          code = 0x100 | p[0];+        }+        code = code | parser->object_code;++        for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )+        {+          if ( field->code == (FT_Int)code )+          {+            /* we found our field's handler; read it */+            FT_Long   val;+            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;+++            /* check that we have enough arguments -- except for */+            /* delta encoded arrays, which can be empty          */+            if ( field->kind != cff_kind_delta && num_args < 1 )+              goto Stack_Underflow;++            switch ( field->kind )+            {+            case cff_kind_bool:+            case cff_kind_string:+            case cff_kind_num:+              val = cff_parse_num( parser->stack );+              goto Store_Number;++            case cff_kind_fixed:+              val = cff_parse_fixed( parser->stack );+              goto Store_Number;++            case cff_kind_fixed_thousand:+              val = cff_parse_fixed_scaled( parser->stack, 3 );++            Store_Number:+              switch ( field->size )+              {+              case (8 / FT_CHAR_BIT):+                *(FT_Byte*)q = (FT_Byte)val;+                break;++              case (16 / FT_CHAR_BIT):+                *(FT_Short*)q = (FT_Short)val;+                break;++              case (32 / FT_CHAR_BIT):+                *(FT_Int32*)q = (FT_Int)val;+                break;++              default:  /* for 64-bit systems */+                *(FT_Long*)q = val;+              }+              break;++            case cff_kind_delta:+              {+                FT_Byte*   qcount = (FT_Byte*)parser->object ++                                      field->count_offset;++                FT_Byte**  data = parser->stack;+++                if ( num_args > field->array_max )+                  num_args = field->array_max;++                /* store count */+                *qcount = (FT_Byte)num_args;++                val = 0;+                while ( num_args > 0 )+                {+                  val += cff_parse_num( data++ );+                  switch ( field->size )+                  {+                  case (8 / FT_CHAR_BIT):+                    *(FT_Byte*)q = (FT_Byte)val;+                    break;++                  case (16 / FT_CHAR_BIT):+                    *(FT_Short*)q = (FT_Short)val;+                    break;++                  case (32 / FT_CHAR_BIT):+                    *(FT_Int32*)q = (FT_Int)val;+                    break;++                  default:  /* for 64-bit systems */+                    *(FT_Long*)q = val;+                  }++                  q += field->size;+                  num_args--;+                }+              }+              break;++            default:  /* callback */+              error = field->reader( parser );+              if ( error )+                goto Exit;+            }+            goto Found;+          }+        }++        /* this is an unknown operator, or it is unsupported; */+        /* we will ignore it for now.                         */++      Found:+        /* clear stack */+        parser->top = parser->stack;+      }+      p++;+    }++  Exit:+    return error;++  Stack_Overflow:+    error = CFF_Err_Invalid_Argument;+    goto Exit;++  Stack_Underflow:+    error = CFF_Err_Invalid_Argument;+    goto Exit;++  Syntax_Error:+    error = CFF_Err_Invalid_Argument;+    goto Exit;+  }+++/* END */
+ src/cff/cffparse.h view
@@ -0,0 +1,102 @@+/***************************************************************************/+/*                                                                         */+/*  cffparse.h                                                             */+/*                                                                         */+/*    CFF token stream parser (specification)                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFF_PARSE_H__+#define __CFF_PARSE_H__+++#include <ft2build.h>+#include "cfftypes.h"+#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++#define CFF_MAX_STACK_DEPTH  96++#define CFF_CODE_TOPDICT  0x1000+#define CFF_CODE_PRIVATE  0x2000+++  typedef struct  CFF_ParserRec_+  {+    FT_Library library;+    FT_Byte*   start;+    FT_Byte*   limit;+    FT_Byte*   cursor;++    FT_Byte*   stack[CFF_MAX_STACK_DEPTH + 1];+    FT_Byte**  top;++    FT_UInt    object_code;+    void*      object;++  } CFF_ParserRec, *CFF_Parser;+++  FT_LOCAL( void )+  cff_parser_init( CFF_Parser  parser,+                   FT_UInt     code,+                   void*       object,+                   FT_Library  library);++  FT_LOCAL( FT_Error )+  cff_parser_run( CFF_Parser  parser,+                  FT_Byte*    start,+                  FT_Byte*    limit );+++  enum+  {+    cff_kind_none = 0,+    cff_kind_num,+    cff_kind_fixed,+    cff_kind_fixed_thousand,+    cff_kind_string,+    cff_kind_bool,+    cff_kind_delta,+    cff_kind_callback,++    cff_kind_max  /* do not remove */+  };+++  /* now generate handlers for the most simple fields */+  typedef FT_Error  (*CFF_Field_Reader)( CFF_Parser  parser );++  typedef struct  CFF_Field_Handler_+  {+    int               kind;+    int               code;+    FT_UInt           offset;+    FT_Byte           size;+    CFF_Field_Reader  reader;+    FT_UInt           array_max;+    FT_UInt           count_offset;++  } CFF_Field_Handler;+++FT_END_HEADER+++#endif /* __CFF_PARSE_H__ */+++/* END */
+ src/cff/cffpic.c view
@@ -0,0 +1,101 @@+/***************************************************************************/+/*                                                                         */+/*  cffpic.c                                                               */+/*                                                                         */+/*    The FreeType position independent code services for cff module.      */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "cffpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from cffdrivr.c */+  FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**);+  void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*);+  void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*);+  void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*);+  void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*);+  void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*);+  void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*);++  /* forward declaration of PIC init functions from cffparse.c */+  FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**);+  void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*);++  /* forward declaration of PIC init functions from cffcmap.c */+  void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*);+  void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*);++  void+  cff_driver_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->cff )+    {+      CffModulePIC* container = (CffModulePIC*)pic_container->cff;+      if(container->cff_services)+        FT_Destroy_Class_cff_services(library, container->cff_services);+      container->cff_services = NULL;+      if(container->cff_field_handlers)+        FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers);+      container->cff_field_handlers = NULL;+      FT_FREE( container );+      pic_container->cff = NULL;+    }+  }+++  FT_Error+  cff_driver_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error         = CFF_Err_Ok;+    CffModulePIC*      container;+    FT_Memory          memory        = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof ( *container ) );+    pic_container->cff = container;++    /* initialize pointer table - this is how the module usually expects this data */+    error = FT_Create_Class_cff_services(library, &container->cff_services);+    if(error) +      goto Exit;+    error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers);+    if(error) +      goto Exit;+    FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info);+    FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict);+    FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name);+    FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info);+    FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info);+    FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec);+    FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec);+Exit:+    if(error)+      cff_driver_class_pic_free(library);+    return error;+  }++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/cff/cffpic.h view
@@ -0,0 +1,80 @@+/***************************************************************************/+/*                                                                         */+/*  cffpic.h                                                               */+/*                                                                         */+/*    The FreeType position independent code services for cff module.      */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFPIC_H__+#define __CFFPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC+#define FT_CFF_SERVICE_PS_INFO_GET         cff_service_ps_info+#define FT_CFF_SERVICE_GLYPH_DICT_GET      cff_service_glyph_dict+#define FT_CFF_SERVICE_PS_NAME_GET         cff_service_ps_name+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET   cff_service_get_cmap_info+#define FT_CFF_SERVICE_CID_INFO_GET        cff_service_cid_info+#define FT_CFF_SERVICES_GET                cff_services+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET  cff_cmap_unicode_class_rec+#define FT_CFF_FIELD_HANDLERS_GET          cff_field_handlers++#else /* FT_CONFIG_OPTION_PIC */++#include FT_SERVICE_GLYPH_DICT_H+#include "cffparse.h"+#include FT_SERVICE_POSTSCRIPT_INFO_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_TT_CMAP_H+#include FT_SERVICE_CID_H++  typedef struct CffModulePIC_+  {+    FT_ServiceDescRec* cff_services;+    CFF_Field_Handler* cff_field_handlers;+    FT_Service_PsInfoRec cff_service_ps_info;+    FT_Service_GlyphDictRec cff_service_glyph_dict;+    FT_Service_PsFontNameRec cff_service_ps_name;+    FT_Service_TTCMapsRec  cff_service_get_cmap_info;+    FT_Service_CIDRec  cff_service_cid_info;+    FT_CMap_ClassRec cff_cmap_encoding_class_rec;+    FT_CMap_ClassRec cff_cmap_unicode_class_rec;+  } CffModulePIC;++#define GET_PIC(lib)                       ((CffModulePIC*)((lib)->pic_container.cff))+#define FT_CFF_SERVICE_PS_INFO_GET         (GET_PIC(library)->cff_service_ps_info)+#define FT_CFF_SERVICE_GLYPH_DICT_GET      (GET_PIC(library)->cff_service_glyph_dict)+#define FT_CFF_SERVICE_PS_NAME_GET         (GET_PIC(library)->cff_service_ps_name)+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET   (GET_PIC(library)->cff_service_get_cmap_info)+#define FT_CFF_SERVICE_CID_INFO_GET        (GET_PIC(library)->cff_service_cid_info)+#define FT_CFF_SERVICES_GET                (GET_PIC(library)->cff_services)+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec)+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET  (GET_PIC(library)->cff_cmap_unicode_class_rec)+#define FT_CFF_FIELD_HANDLERS_GET          (GET_PIC(library)->cff_field_handlers)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __CFFPIC_H__ */+++/* END */
+ src/cff/cfftoken.h view
@@ -0,0 +1,97 @@+/***************************************************************************/+/*                                                                         */+/*  cfftoken.h                                                             */+/*                                                                         */+/*    CFF token definitions (specification only).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  CFF_FontRecDictRec++#undef  CFFCODE+#define CFFCODE       CFFCODE_TOPDICT++  CFF_FIELD_STRING  ( 0,     version )+  CFF_FIELD_STRING  ( 1,     notice )+  CFF_FIELD_STRING  ( 0x100, copyright )+  CFF_FIELD_STRING  ( 2,     full_name )+  CFF_FIELD_STRING  ( 3,     family_name )+  CFF_FIELD_STRING  ( 4,     weight )+  CFF_FIELD_BOOL    ( 0x101, is_fixed_pitch )+  CFF_FIELD_FIXED   ( 0x102, italic_angle )+  CFF_FIELD_FIXED   ( 0x103, underline_position )+  CFF_FIELD_FIXED   ( 0x104, underline_thickness )+  CFF_FIELD_NUM     ( 0x105, paint_type )+  CFF_FIELD_NUM     ( 0x106, charstring_type )+  CFF_FIELD_CALLBACK( 0x107, font_matrix )+  CFF_FIELD_NUM     ( 13,    unique_id )+  CFF_FIELD_CALLBACK( 5,     font_bbox )+  CFF_FIELD_NUM     ( 0x108, stroke_width )+  CFF_FIELD_NUM     ( 15,    charset_offset )+  CFF_FIELD_NUM     ( 16,    encoding_offset )+  CFF_FIELD_NUM     ( 17,    charstrings_offset )+  CFF_FIELD_CALLBACK( 18,    private_dict )+  CFF_FIELD_NUM     ( 0x114, synthetic_base )+  CFF_FIELD_STRING  ( 0x115, embedded_postscript )++#if 0+  CFF_FIELD_STRING  ( 0x116, base_font_name )+  CFF_FIELD_DELTA   ( 0x117, base_font_blend, 16 )+  CFF_FIELD_CALLBACK( 0x118, multiple_master )+  CFF_FIELD_CALLBACK( 0x119, blend_axis_types )+#endif++  CFF_FIELD_CALLBACK( 0x11E, cid_ros )+  CFF_FIELD_NUM     ( 0x11F, cid_font_version )+  CFF_FIELD_NUM     ( 0x120, cid_font_revision )+  CFF_FIELD_NUM     ( 0x121, cid_font_type )+  CFF_FIELD_NUM     ( 0x122, cid_count )+  CFF_FIELD_NUM     ( 0x123, cid_uid_base )+  CFF_FIELD_NUM     ( 0x124, cid_fd_array_offset )+  CFF_FIELD_NUM     ( 0x125, cid_fd_select_offset )+  CFF_FIELD_STRING  ( 0x126, cid_font_name )++#if 0+  CFF_FIELD_NUM     ( 0x127, chameleon )+#endif+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  CFF_PrivateRec+#undef  CFFCODE+#define CFFCODE       CFFCODE_PRIVATE++  CFF_FIELD_DELTA     ( 6,     blue_values, 14 )+  CFF_FIELD_DELTA     ( 7,     other_blues, 10 )+  CFF_FIELD_DELTA     ( 8,     family_blues, 14 )+  CFF_FIELD_DELTA     ( 9,     family_other_blues, 10 )+  CFF_FIELD_FIXED_1000( 0x109, blue_scale )+  CFF_FIELD_NUM       ( 0x10A, blue_shift )+  CFF_FIELD_NUM       ( 0x10B, blue_fuzz )+  CFF_FIELD_NUM       ( 10,    standard_width )+  CFF_FIELD_NUM       ( 11,    standard_height )+  CFF_FIELD_DELTA     ( 0x10C, snap_widths, 13 )+  CFF_FIELD_DELTA     ( 0x10D, snap_heights, 13 )+  CFF_FIELD_BOOL      ( 0x10E, force_bold )+  CFF_FIELD_FIXED     ( 0x10F, force_bold_threshold )+  CFF_FIELD_NUM       ( 0x110, lenIV )+  CFF_FIELD_NUM       ( 0x111, language_group )+  CFF_FIELD_FIXED     ( 0x112, expansion_factor )+  CFF_FIELD_NUM       ( 0x113, initial_random_seed )+  CFF_FIELD_NUM       ( 19,    local_subrs_offset )+  CFF_FIELD_NUM       ( 20,    default_width )+  CFF_FIELD_NUM       ( 21,    nominal_width )+++/* END */
+ src/cff/cfftypes.h view
@@ -0,0 +1,281 @@+/***************************************************************************/+/*                                                                         */+/*  cfftypes.h                                                             */+/*                                                                         */+/*    Basic OpenType/CFF type definitions and interface (specification     */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2010 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CFFTYPES_H__+#define __CFFTYPES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TYPE1_TABLES_H+#include FT_INTERNAL_SERVICE_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CFF_IndexRec                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A structure used to model a CFF Index table.                       */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    stream      :: The source input stream.                            */+  /*                                                                       */+  /*    start       :: The position of the first index byte in the         */+  /*                   input stream.                                       */+  /*                                                                       */+  /*    count       :: The number of elements in the index.                */+  /*                                                                       */+  /*    off_size    :: The size in bytes of object offsets in index.       */+  /*                                                                       */+  /*    data_offset :: The position of first data byte in the index's      */+  /*                   bytes.                                              */+  /*                                                                       */+  /*    data_size   :: The size of the data table in this index.           */+  /*                                                                       */+  /*    offsets     :: A table of element offsets in the index.  Must be   */+  /*                   loaded explicitly.                                  */+  /*                                                                       */+  /*    bytes       :: If the index is loaded in memory, its bytes.        */+  /*                                                                       */+  typedef struct  CFF_IndexRec_+  {+    FT_Stream  stream;+    FT_ULong   start;+    FT_UInt    count;+    FT_Byte    off_size;+    FT_ULong   data_offset;+    FT_ULong   data_size;++    FT_ULong*  offsets;+    FT_Byte*   bytes;++  } CFF_IndexRec, *CFF_Index;+++  typedef struct  CFF_EncodingRec_+  {+    FT_UInt     format;+    FT_ULong    offset;++    FT_UInt     count;+    FT_UShort   sids [256];  /* avoid dynamic allocations */+    FT_UShort   codes[256];++  } CFF_EncodingRec, *CFF_Encoding;+++  typedef struct  CFF_CharsetRec_+  {++    FT_UInt     format;+    FT_ULong    offset;++    FT_UShort*  sids;+    FT_UShort*  cids;       /* the inverse mapping of `sids'; only needed */+                            /* for CID-keyed fonts                        */+    FT_UInt     max_cid;+    FT_UInt     num_glyphs;++  } CFF_CharsetRec, *CFF_Charset;+++  typedef struct  CFF_FontRecDictRec_+  {+    FT_UInt    version;+    FT_UInt    notice;+    FT_UInt    copyright;+    FT_UInt    full_name;+    FT_UInt    family_name;+    FT_UInt    weight;+    FT_Bool    is_fixed_pitch;+    FT_Fixed   italic_angle;+    FT_Fixed   underline_position;+    FT_Fixed   underline_thickness;+    FT_Int     paint_type;+    FT_Int     charstring_type;+    FT_Matrix  font_matrix;+    FT_ULong   units_per_em;  /* temporarily used as scaling value also */+    FT_Vector  font_offset;+    FT_ULong   unique_id;+    FT_BBox    font_bbox;+    FT_Pos     stroke_width;+    FT_ULong   charset_offset;+    FT_ULong   encoding_offset;+    FT_ULong   charstrings_offset;+    FT_ULong   private_offset;+    FT_ULong   private_size;+    FT_Long    synthetic_base;+    FT_UInt    embedded_postscript;++    /* these should only be used for the top-level font dictionary */+    FT_UInt    cid_registry;+    FT_UInt    cid_ordering;+    FT_Long    cid_supplement;++    FT_Long    cid_font_version;+    FT_Long    cid_font_revision;+    FT_Long    cid_font_type;+    FT_ULong   cid_count;+    FT_ULong   cid_uid_base;+    FT_ULong   cid_fd_array_offset;+    FT_ULong   cid_fd_select_offset;+    FT_UInt    cid_font_name;++  } CFF_FontRecDictRec, *CFF_FontRecDict;+++  typedef struct  CFF_PrivateRec_+  {+    FT_Byte   num_blue_values;+    FT_Byte   num_other_blues;+    FT_Byte   num_family_blues;+    FT_Byte   num_family_other_blues;++    FT_Pos    blue_values[14];+    FT_Pos    other_blues[10];+    FT_Pos    family_blues[14];+    FT_Pos    family_other_blues[10];++    FT_Fixed  blue_scale;+    FT_Pos    blue_shift;+    FT_Pos    blue_fuzz;+    FT_Pos    standard_width;+    FT_Pos    standard_height;++    FT_Byte   num_snap_widths;+    FT_Byte   num_snap_heights;+    FT_Pos    snap_widths[13];+    FT_Pos    snap_heights[13];+    FT_Bool   force_bold;+    FT_Fixed  force_bold_threshold;+    FT_Int    lenIV;+    FT_Int    language_group;+    FT_Fixed  expansion_factor;+    FT_Long   initial_random_seed;+    FT_ULong  local_subrs_offset;+    FT_Pos    default_width;+    FT_Pos    nominal_width;++  } CFF_PrivateRec, *CFF_Private;+++  typedef struct  CFF_FDSelectRec_+  {+    FT_Byte   format;+    FT_UInt   range_count;++    /* that's the table, taken from the file `as is' */+    FT_Byte*  data;+    FT_UInt   data_size;++    /* small cache for format 3 only */+    FT_UInt   cache_first;+    FT_UInt   cache_count;+    FT_Byte   cache_fd;++  } CFF_FDSelectRec, *CFF_FDSelect;+++  /* A SubFont packs a font dict and a private dict together.  They are */+  /* needed to support CID-keyed CFF fonts.                             */+  typedef struct  CFF_SubFontRec_+  {+    CFF_FontRecDictRec  font_dict;+    CFF_PrivateRec      private_dict;++    CFF_IndexRec        local_subrs_index;+    FT_Byte**           local_subrs; /* array of pointers into Local Subrs INDEX data */++  } CFF_SubFontRec, *CFF_SubFont;+++  /* maximum number of sub-fonts in a CID-keyed file */+#define CFF_MAX_CID_FONTS  32+++  typedef struct  CFF_FontRec_+  {+    FT_Stream        stream;+    FT_Memory        memory;+    FT_UInt          num_faces;+    FT_UInt          num_glyphs;++    FT_Byte          version_major;+    FT_Byte          version_minor;+    FT_Byte          header_size;+    FT_Byte          absolute_offsize;+++    CFF_IndexRec     name_index;+    CFF_IndexRec     top_dict_index;+    CFF_IndexRec     global_subrs_index;++    CFF_EncodingRec  encoding;+    CFF_CharsetRec   charset;++    CFF_IndexRec     charstrings_index;+    CFF_IndexRec     font_dict_index;+    CFF_IndexRec     private_index;+    CFF_IndexRec     local_subrs_index;++    FT_String*       font_name;++    /* array of pointers into Global Subrs INDEX data */+    FT_Byte**        global_subrs;++    /* array of pointers into String INDEX data stored at string_pool */+    FT_UInt          num_strings;+    FT_Byte**        strings;+    FT_Byte*         string_pool;++    CFF_SubFontRec   top_font;+    FT_UInt          num_subfonts;+    CFF_SubFont      subfonts[CFF_MAX_CID_FONTS];++    CFF_FDSelectRec  fd_select;++    /* interface to PostScript hinter */+    PSHinter_Service  pshinter;++    /* interface to Postscript Names service */+    FT_Service_PsCMaps  psnames;++    /* since version 2.3.0 */+    PS_FontInfoRec*  font_info;   /* font info dictionary */++    /* since version 2.3.6 */+    FT_String*       registry;+    FT_String*       ordering;+      +  } CFF_FontRec, *CFF_Font;+++FT_END_HEADER++#endif /* __CFFTYPES_H__ */+++/* END */
+ src/cid/ciderrs.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  ciderrs.h                                                              */+/*                                                                         */+/*    CID error codes (specification only).                                */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the CID error enumeration constants.      */+  /*                                                                       */+  /*************************************************************************/++#ifndef __CIDERRS_H__+#define __CIDERRS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  CID_Err_+#define FT_ERR_BASE    FT_Mod_Err_CID++#include FT_ERRORS_H++#endif /* __CIDERRS_H__ */+++/* END */
+ src/cid/cidgload.c view
@@ -0,0 +1,442 @@+/***************************************************************************/+/*                                                                         */+/*  cidgload.c                                                             */+/*                                                                         */+/*    CID-keyed Type1 Glyph Loader (body).                                 */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "cidload.h"+#include "cidgload.h"+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_OUTLINE_H+#include FT_INTERNAL_CALC_H++#include "ciderrs.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cidgload+++  FT_CALLBACK_DEF( FT_Error )+  cid_load_glyph( T1_Decoder  decoder,+                  FT_UInt     glyph_index )+  {+    CID_Face       face = (CID_Face)decoder->builder.face;+    CID_FaceInfo   cid  = &face->cid;+    FT_Byte*       p;+    FT_UInt        fd_select;+    FT_Stream      stream       = face->cid_stream;+    FT_Error       error        = CID_Err_Ok;+    FT_Byte*       charstring   = 0;+    FT_Memory      memory       = face->root.memory;+    FT_ULong       glyph_length = 0;+    PSAux_Service  psaux        = (PSAux_Service)face->psaux;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    FT_Incremental_InterfaceRec *inc =+                                  face->root.internal->incremental_interface;+#endif+++    FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index ));++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* For incremental fonts get the character data using */+    /* the callback function.                             */+    if ( inc )+    {+      FT_Data  glyph_data;+++      error = inc->funcs->get_glyph_data( inc->object,+                                          glyph_index, &glyph_data );+      if ( error )+        goto Exit;++      p         = (FT_Byte*)glyph_data.pointer;+      fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes );++      if ( glyph_data.length != 0 )+      {+        glyph_length = glyph_data.length - cid->fd_bytes;+        (void)FT_ALLOC( charstring, glyph_length );+        if ( !error )+          ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes,+                     glyph_length );+      }++      inc->funcs->free_glyph_data( inc->object, &glyph_data );++      if ( error )+        goto Exit;+    }++    else++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    /* For ordinary fonts read the CID font dictionary index */+    /* and charstring offset from the CIDMap.                */+    {+      FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;+      FT_ULong  off1;+++      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset ++                           glyph_index * entry_len )               ||+           FT_FRAME_ENTER( 2 * entry_len )                         )+        goto Exit;++      p            = (FT_Byte*)stream->cursor;+      fd_select    = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );+      off1         = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );+      p           += cid->fd_bytes;+      glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;+      FT_FRAME_EXIT();++      if ( fd_select >= (FT_UInt)cid->num_dicts )+      {+        error = CID_Err_Invalid_Offset;+        goto Exit;+      }+      if ( glyph_length == 0 )+        goto Exit;+      if ( FT_ALLOC( charstring, glyph_length ) )+        goto Exit;+      if ( FT_STREAM_READ_AT( cid->data_offset + off1,+                              charstring, glyph_length ) )+        goto Exit;+    }++    /* Now set up the subrs array and parse the charstrings. */+    {+      CID_FaceDict  dict;+      CID_Subrs     cid_subrs = face->subrs + fd_select;+      FT_Int        cs_offset;+++      /* Set up subrs */+      decoder->num_subrs = cid_subrs->num_subrs;+      decoder->subrs     = cid_subrs->code;+      decoder->subrs_len = 0;++      /* Set up font matrix */+      dict                 = cid->font_dicts + fd_select;++      decoder->font_matrix = dict->font_matrix;+      decoder->font_offset = dict->font_offset;+      decoder->lenIV       = dict->private_dict.lenIV;++      /* Decode the charstring. */++      /* Adjustment for seed bytes. */+      cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );++      /* Decrypt only if lenIV >= 0. */+      if ( decoder->lenIV >= 0 )+        psaux->t1_decrypt( charstring, glyph_length, 4330 );++      error = decoder->funcs.parse_charstrings(+                decoder, charstring + cs_offset,+                (FT_Int)glyph_length - cs_offset );+    }++    FT_FREE( charstring );++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* Incremental fonts can optionally override the metrics. */+    if ( !error && inc && inc->funcs->get_glyph_metrics )+    {+      FT_Incremental_MetricsRec  metrics;+++      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );+      metrics.bearing_y = 0;+      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );+      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );++      error = inc->funcs->get_glyph_metrics( inc->object,+                                             glyph_index, FALSE, &metrics );++      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );+      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );+      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );+    }++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++  Exit:+    return error;+  }+++#if 0+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /**********                                                      *********/+  /**********                                                      *********/+  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/+  /**********                                                      *********/+  /**********    The following code is in charge of computing      *********/+  /**********    the maximum advance width of the font.  It        *********/+  /**********    quickly processes each glyph charstring to        *********/+  /**********    extract the value from either a `sbw' or `seac'   *********/+  /**********    operator.                                         *********/+  /**********                                                      *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  cid_face_compute_max_advance( CID_Face  face,+                                FT_Int*   max_advance )+  {+    FT_Error       error;+    T1_DecoderRec  decoder;+    FT_Int         glyph_index;++    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    *max_advance = 0;++    /* Initialize load decoder */+    error = psaux->t1_decoder_funcs->init( &decoder,+                                           (FT_Face)face,+                                           0, /* size       */+                                           0, /* glyph slot */+                                           0, /* glyph names! XXX */+                                           0, /* blend == 0 */+                                           0, /* hinting == 0 */+                                           cid_load_glyph );+    if ( error )+      return error;++    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */+    /*       if we ever support CID-keyed multiple master fonts     */++    decoder.builder.metrics_only = 1;+    decoder.builder.load_points  = 0;++    /* for each glyph, parse the glyph charstring and extract */+    /* the advance width                                      */+    for ( glyph_index = 0; glyph_index < face->root.num_glyphs;+          glyph_index++ )+    {+      /* now get load the unscaled outline */+      error = cid_load_glyph( &decoder, glyph_index );+      /* ignore the error if one occurred - skip to next glyph */+    }++    *max_advance = FIXED_TO_INT( decoder.builder.advance.x );++    psaux->t1_decoder_funcs->done( &decoder );++    return CID_Err_Ok;+  }+++#endif /* 0 */+++  FT_LOCAL_DEF( FT_Error )+  cid_slot_load_glyph( FT_GlyphSlot  cidglyph,      /* CID_GlyphSlot */+                       FT_Size       cidsize,       /* CID_Size      */+                       FT_UInt       glyph_index,+                       FT_Int32      load_flags )+  {+    CID_GlyphSlot  glyph = (CID_GlyphSlot)cidglyph;+    FT_Error       error;+    T1_DecoderRec  decoder;+    CID_Face       face = (CID_Face)cidglyph->face;+    FT_Bool        hinting;++    PSAux_Service  psaux = (PSAux_Service)face->psaux;+    FT_Matrix      font_matrix;+    FT_Vector      font_offset;+++    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )+    {+      error = CID_Err_Invalid_Argument;+      goto Exit;+    }++    if ( load_flags & FT_LOAD_NO_RECURSE )+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;++    glyph->x_scale = cidsize->metrics.x_scale;+    glyph->y_scale = cidsize->metrics.y_scale;++    cidglyph->outline.n_points   = 0;+    cidglyph->outline.n_contours = 0;++    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&+                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );++    cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;++    error = psaux->t1_decoder_funcs->init( &decoder,+                                           cidglyph->face,+                                           cidsize,+                                           cidglyph,+                                           0, /* glyph names -- XXX */+                                           0, /* blend == 0 */+                                           hinting,+                                           FT_LOAD_TARGET_MODE( load_flags ),+                                           cid_load_glyph );+    if ( error )+      goto Exit;++    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */+    /*       if we ever support CID-keyed multiple master fonts     */++    /* set up the decoder */+    decoder.builder.no_recurse = FT_BOOL(+      ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );++    error = cid_load_glyph( &decoder, glyph_index );+    if ( error )+      goto Exit;++    font_matrix = decoder.font_matrix;+    font_offset = decoder.font_offset;++    /* save new glyph tables */+    psaux->t1_decoder_funcs->done( &decoder );++    /* now set the metrics -- this is rather simple, as    */+    /* the left side bearing is the xMin, and the top side */+    /* bearing the yMax                                    */+    cidglyph->outline.flags &= FT_OUTLINE_OWNER;+    cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;++    /* for composite glyphs, return only left side bearing and */+    /* advance width                                           */+    if ( load_flags & FT_LOAD_NO_RECURSE )+    {+      FT_Slot_Internal  internal = cidglyph->internal;+++      cidglyph->metrics.horiBearingX =+        FIXED_TO_INT( decoder.builder.left_bearing.x );+      cidglyph->metrics.horiAdvance =+        FIXED_TO_INT( decoder.builder.advance.x );++      internal->glyph_matrix      = font_matrix;+      internal->glyph_delta       = font_offset;+      internal->glyph_transformed = 1;+    }+    else+    {+      FT_BBox            cbox;+      FT_Glyph_Metrics*  metrics = &cidglyph->metrics;+      FT_Vector          advance;+++      /* copy the _unscaled_ advance width */+      metrics->horiAdvance =+        FIXED_TO_INT( decoder.builder.advance.x );+      cidglyph->linearHoriAdvance =+        FIXED_TO_INT( decoder.builder.advance.x );+      cidglyph->internal->glyph_transformed = 0;++      /* make up vertical ones */+      metrics->vertAdvance        = ( face->cid.font_bbox.yMax -+                                      face->cid.font_bbox.yMin ) >> 16;+      cidglyph->linearVertAdvance = metrics->vertAdvance;++      cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;++      if ( cidsize->metrics.y_ppem < 24 )+        cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;++      /* apply the font matrix */+      FT_Outline_Transform( &cidglyph->outline, &font_matrix );++      FT_Outline_Translate( &cidglyph->outline,+                            font_offset.x,+                            font_offset.y );++      advance.x = metrics->horiAdvance;+      advance.y = 0;+      FT_Vector_Transform( &advance, &font_matrix );+      metrics->horiAdvance = advance.x + font_offset.x;++      advance.x = 0;+      advance.y = metrics->vertAdvance;+      FT_Vector_Transform( &advance, &font_matrix );+      metrics->vertAdvance = advance.y + font_offset.y;++      if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )+      {+        /* scale the outline and the metrics */+        FT_Int       n;+        FT_Outline*  cur = decoder.builder.base;+        FT_Vector*   vec = cur->points;+        FT_Fixed     x_scale = glyph->x_scale;+        FT_Fixed     y_scale = glyph->y_scale;+++        /* First of all, scale the points */+        if ( !hinting || !decoder.builder.hints_funcs )+          for ( n = cur->n_points; n > 0; n--, vec++ )+          {+            vec->x = FT_MulFix( vec->x, x_scale );+            vec->y = FT_MulFix( vec->y, y_scale );+          }++        /* Then scale the metrics */+        metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );+        metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );+      }++      /* compute the other metrics */+      FT_Outline_Get_CBox( &cidglyph->outline, &cbox );++      metrics->width  = cbox.xMax - cbox.xMin;+      metrics->height = cbox.yMax - cbox.yMin;++      metrics->horiBearingX = cbox.xMin;+      metrics->horiBearingY = cbox.yMax;++      if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) +      {+        /* make up vertical ones */+        ft_synthesize_vertical_metrics( metrics,+                                        metrics->vertAdvance );+      }+    }++  Exit:+    return error;+  }+++/* END */
+ src/cid/cidgload.h view
@@ -0,0 +1,51 @@+/***************************************************************************/+/*                                                                         */+/*  cidgload.h                                                             */+/*                                                                         */+/*    OpenType Glyph Loader (specification).                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CIDGLOAD_H__+#define __CIDGLOAD_H__+++#include <ft2build.h>+#include "cidobjs.h"+++FT_BEGIN_HEADER+++#if 0++  /* Compute the maximum advance width of a font through quick parsing */+  FT_LOCAL( FT_Error )+  cid_face_compute_max_advance( CID_Face  face,+                                FT_Int*   max_advance );++#endif /* 0 */++  FT_LOCAL( FT_Error )+  cid_slot_load_glyph( FT_GlyphSlot  glyph,         /* CID_Glyph_Slot */+                       FT_Size       size,          /* CID_Size       */+                       FT_UInt       glyph_index,+                       FT_Int32      load_flags );+++FT_END_HEADER++#endif /* __CIDGLOAD_H__ */+++/* END */
+ src/cid/cidload.c view
@@ -0,0 +1,672 @@+/***************************************************************************/+/*                                                                         */+/*  cidload.c                                                              */+/*                                                                         */+/*    CID-keyed Type1 font loader (body).                                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_CONFIG_CONFIG_H+#include FT_MULTIPLE_MASTERS_H+#include FT_INTERNAL_TYPE1_TYPES_H++#include "cidload.h"++#include "ciderrs.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cidload+++  /* read a single offset */+  FT_LOCAL_DEF( FT_Long )+  cid_get_offset( FT_Byte*  *start,+                  FT_Byte    offsize )+  {+    FT_Long   result;+    FT_Byte*  p = *start;+++    for ( result = 0; offsize > 0; offsize-- )+    {+      result <<= 8;+      result  |= *p++;+    }++    *start = p;+    return result;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    TYPE 1 SYMBOL PARSING                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  static FT_Error+  cid_load_keyword( CID_Face        face,+                    CID_Loader*     loader,+                    const T1_Field  keyword )+  {+    FT_Error      error;+    CID_Parser*   parser = &loader->parser;+    FT_Byte*      object;+    void*         dummy_object;+    CID_FaceInfo  cid = &face->cid;+++    /* if the keyword has a dedicated callback, call it */+    if ( keyword->type == T1_FIELD_TYPE_CALLBACK )+    {+      keyword->reader( (FT_Face)face, parser );+      error = parser->root.error;+      goto Exit;+    }++    /* we must now compute the address of our target object */+    switch ( keyword->location )+    {+    case T1_FIELD_LOCATION_CID_INFO:+      object = (FT_Byte*)cid;+      break;++    case T1_FIELD_LOCATION_FONT_INFO:+      object = (FT_Byte*)&cid->font_info;+      break;++    case T1_FIELD_LOCATION_FONT_EXTRA:+      object = (FT_Byte*)&face->font_extra;+      break;++    case T1_FIELD_LOCATION_BBOX:+      object = (FT_Byte*)&cid->font_bbox;+      break;++    default:+      {+        CID_FaceDict  dict;+++        if ( parser->num_dict < 0 )+        {+          FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n",+                     keyword->ident ));+          error = CID_Err_Syntax_Error;+          goto Exit;+        }++        dict = cid->font_dicts + parser->num_dict;+        switch ( keyword->location )+        {+        case T1_FIELD_LOCATION_PRIVATE:+          object = (FT_Byte*)&dict->private_dict;+          break;++        default:+          object = (FT_Byte*)dict;+        }+      }+    }++    dummy_object = object;++    /* now, load the keyword data in the object's field(s) */+    if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY ||+         keyword->type == T1_FIELD_TYPE_FIXED_ARRAY   )+      error = cid_parser_load_field_table( &loader->parser, keyword,+                                           &dummy_object );+    else+      error = cid_parser_load_field( &loader->parser,+                                     keyword, &dummy_object );+  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  parse_font_matrix( CID_Face     face,+                     CID_Parser*  parser )+  {+    FT_Matrix*    matrix;+    FT_Vector*    offset;+    CID_FaceDict  dict;+    FT_Face       root = (FT_Face)&face->root;+    FT_Fixed      temp[6];+    FT_Fixed      temp_scale;+++    if ( parser->num_dict >= 0 )+    {+      dict   = face->cid.font_dicts + parser->num_dict;+      matrix = &dict->font_matrix;+      offset = &dict->font_offset;++      (void)cid_parser_to_fixed_array( parser, 6, temp, 3 );++      temp_scale = FT_ABS( temp[3] );++      /* Set units per EM based on FontMatrix values.  We set the value to */+      /* `1000/temp_scale', because temp_scale was already multiplied by   */+      /* 1000 (in `t1_tofixed', from psobjs.c).                            */+      root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L,+                                        FT_DivFix( temp_scale, 1000 ) ) );++      /* we need to scale the values by 1.0/temp[3] */+      if ( temp_scale != 0x10000L )+      {+        temp[0] = FT_DivFix( temp[0], temp_scale );+        temp[1] = FT_DivFix( temp[1], temp_scale );+        temp[2] = FT_DivFix( temp[2], temp_scale );+        temp[4] = FT_DivFix( temp[4], temp_scale );+        temp[5] = FT_DivFix( temp[5], temp_scale );+        temp[3] = 0x10000L;+      }++      matrix->xx = temp[0];+      matrix->yx = temp[1];+      matrix->xy = temp[2];+      matrix->yy = temp[3];++      /* note that the font offsets are expressed in integer font units */+      offset->x  = temp[4] >> 16;+      offset->y  = temp[5] >> 16;+    }++    return CID_Err_Ok;      /* this is a callback function; */+                            /* we must return an error code */+  }+++  FT_CALLBACK_DEF( FT_Error )+  parse_fd_array( CID_Face     face,+                  CID_Parser*  parser )+  {+    CID_FaceInfo  cid    = &face->cid;+    FT_Memory     memory = face->root.memory;+    FT_Error      error  = CID_Err_Ok;+    FT_Long       num_dicts;+++    num_dicts = cid_parser_to_int( parser );++    if ( !cid->font_dicts )+    {+      FT_Int  n;+++      if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) )+        goto Exit;++      cid->num_dicts = (FT_UInt)num_dicts;++      /* don't forget to set a few defaults */+      for ( n = 0; n < cid->num_dicts; n++ )+      {+        CID_FaceDict  dict = cid->font_dicts + n;+++        /* default value for lenIV */+        dict->private_dict.lenIV = 4;+      }+    }++  Exit:+    return error;+  }+++  /* by mistake, `expansion_factor' appears both in PS_PrivateRec */+  /* and CID_FaceDictRec (both are public header files and can't  */+  /* changed); we simply copy the value                           */++  FT_CALLBACK_DEF( FT_Error )+  parse_expansion_factor( CID_Face     face,+                          CID_Parser*  parser )+  {+    CID_FaceDict  dict;+++    if ( parser->num_dict >= 0 )+    {+      dict = face->cid.font_dicts + parser->num_dict;++      dict->expansion_factor              = cid_parser_to_fixed( parser, 0 );+      dict->private_dict.expansion_factor = dict->expansion_factor;+    }++    return CID_Err_Ok;+  }+++  static+  const T1_FieldRec  cid_field_records[] =+  {++#include "cidtoken.h"++    T1_FIELD_CALLBACK( "FDArray",         parse_fd_array, 0 )+    T1_FIELD_CALLBACK( "FontMatrix",      parse_font_matrix, 0 )+    T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 )++    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }+  };+++  static FT_Error+  cid_parse_dict( CID_Face     face,+                  CID_Loader*  loader,+                  FT_Byte*     base,+                  FT_Long      size )+  {+    CID_Parser*  parser = &loader->parser;+++    parser->root.cursor = base;+    parser->root.limit  = base + size;+    parser->root.error  = CID_Err_Ok;++    {+      FT_Byte*  cur   = base;+      FT_Byte*  limit = cur + size;+++      for (;;)+      {+        FT_Byte*  newlimit;+++        parser->root.cursor = cur;+        cid_parser_skip_spaces( parser );++        if ( parser->root.cursor >= limit )+          newlimit = limit - 1 - 17;+        else+          newlimit = parser->root.cursor - 17;++        /* look for `%ADOBeginFontDict' */+        for ( ; cur < newlimit; cur++ )+        {+          if ( *cur == '%'                                            &&+               ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )+          {+            /* if /FDArray was found, then cid->num_dicts is > 0, and */+            /* we can start increasing parser->num_dict               */+            if ( face->cid.num_dicts > 0 )+              parser->num_dict++;+          }+        }++        cur = parser->root.cursor;+        /* no error can occur in cid_parser_skip_spaces */+        if ( cur >= limit )+          break;++        cid_parser_skip_PS_token( parser );+        if ( parser->root.cursor >= limit || parser->root.error )+          break;++        /* look for immediates */+        if ( *cur == '/' && cur + 2 < limit )+        {+          FT_PtrDist  len;+++          cur++;+          len = parser->root.cursor - cur;++          if ( len > 0 && len < 22 )+          {+            /* now compare the immediate name to the keyword table */+            T1_Field  keyword = (T1_Field)cid_field_records;+++            for (;;)+            {+              FT_Byte*  name;+++              name = (FT_Byte*)keyword->ident;+              if ( !name )+                break;++              if ( cur[0] == name[0]                                 &&+                   len == (FT_PtrDist)ft_strlen( (const char*)name ) )+              {+                FT_PtrDist  n;+++                for ( n = 1; n < len; n++ )+                  if ( cur[n] != name[n] )+                    break;++                if ( n >= len )+                {+                  /* we found it - run the parsing callback */+                  parser->root.error = cid_load_keyword( face,+                                                         loader,+                                                         keyword );+                  if ( parser->root.error )+                    return parser->root.error;+                  break;+                }+              }+              keyword++;+            }+          }+        }++        cur = parser->root.cursor;+      }+    }+    return parser->root.error;+  }+++  /* read the subrmap and the subrs of each font dict */+  static FT_Error+  cid_read_subrs( CID_Face  face )+  {+    CID_FaceInfo   cid    = &face->cid;+    FT_Memory      memory = face->root.memory;+    FT_Stream      stream = face->cid_stream;+    FT_Error       error;+    FT_Int         n;+    CID_Subrs      subr;+    FT_UInt        max_offsets = 0;+    FT_ULong*      offsets = 0;+    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) )+      goto Exit;++    subr = face->subrs;+    for ( n = 0; n < cid->num_dicts; n++, subr++ )+    {+      CID_FaceDict  dict  = cid->font_dicts + n;+      FT_Int        lenIV = dict->private_dict.lenIV;+      FT_UInt       count, num_subrs = dict->num_subrs;+      FT_ULong      data_len;+      FT_Byte*      p;+++      /* reallocate offsets array if needed */+      if ( num_subrs + 1 > max_offsets )+      {+        FT_UInt  new_max = FT_PAD_CEIL( num_subrs + 1, 4 );+++        if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) )+          goto Fail;++        max_offsets = new_max;+      }++      /* read the subrmap's offsets */+      if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) ||+           FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes )      )+        goto Fail;++      p = (FT_Byte*)stream->cursor;+      for ( count = 0; count <= num_subrs; count++ )+        offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes );++      FT_FRAME_EXIT();++      /* now, compute the size of subrs charstrings, */+      /* allocate, and read them                     */+      data_len = offsets[num_subrs] - offsets[0];++      if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) ||+               FT_ALLOC( subr->code[0], data_len )   )+        goto Fail;++      if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||+           FT_STREAM_READ( subr->code[0], data_len )  )+        goto Fail;++      /* set up pointers */+      for ( count = 1; count <= num_subrs; count++ )+      {+        FT_ULong  len;+++        len               = offsets[count] - offsets[count - 1];+        subr->code[count] = subr->code[count - 1] + len;+      }++      /* decrypt subroutines, but only if lenIV >= 0 */+      if ( lenIV >= 0 )+      {+        for ( count = 0; count < num_subrs; count++ )+        {+          FT_ULong  len;+++          len = offsets[count + 1] - offsets[count];+          psaux->t1_decrypt( subr->code[count], len, 4330 );+        }+      }++      subr->num_subrs = num_subrs;+    }++  Exit:+    FT_FREE( offsets );+    return error;++  Fail:+    if ( face->subrs )+    {+      for ( n = 0; n < cid->num_dicts; n++ )+      {+        if ( face->subrs[n].code )+          FT_FREE( face->subrs[n].code[0] );++        FT_FREE( face->subrs[n].code );+      }+      FT_FREE( face->subrs );+    }+    goto Exit;+  }+++  static void+  t1_init_loader( CID_Loader*  loader,+                  CID_Face     face )+  {+    FT_UNUSED( face );++    FT_MEM_ZERO( loader, sizeof ( *loader ) );+  }+++  static void+  t1_done_loader( CID_Loader*  loader )+  {+    CID_Parser*  parser = &loader->parser;+++    /* finalize parser */+    cid_parser_done( parser );+  }+++  static FT_Error+  cid_hex_to_binary( FT_Byte*  data,+                     FT_Long   data_len,+                     FT_ULong  offset,+                     CID_Face  face )+  {+    FT_Stream  stream = face->root.stream;+    FT_Error   error;++    FT_Byte    buffer[256];+    FT_Byte   *p, *plimit;+    FT_Byte   *d, *dlimit;+    FT_Byte    val;++    FT_Bool    upper_nibble, done;+++    if ( FT_STREAM_SEEK( offset ) )+      goto Exit;++    d      = data;+    dlimit = d + data_len;+    p      = buffer;+    plimit = p;++    upper_nibble = 1;+    done         = 0;++    while ( d < dlimit )+    {+      if ( p >= plimit )+      {+        FT_ULong  oldpos = FT_STREAM_POS();+        FT_ULong  size   = stream->size - oldpos;+++        if ( size == 0 )+        {+          error = CID_Err_Syntax_Error;+          goto Exit;+        }++        if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) )+          goto Exit;+        p      = buffer;+        plimit = p + FT_STREAM_POS() - oldpos;+      }++      if ( ft_isdigit( *p ) )+        val = (FT_Byte)( *p - '0' );+      else if ( *p >= 'a' && *p <= 'f' )+        val = (FT_Byte)( *p - 'a' );+      else if ( *p >= 'A' && *p <= 'F' )+        val = (FT_Byte)( *p - 'A' + 10 );+      else if ( *p == ' '  ||+                *p == '\t' ||+                *p == '\r' ||+                *p == '\n' ||+                *p == '\f' ||+                *p == '\0' )+      {+        p++;+        continue;+      }+      else if ( *p == '>' )+      {+        val  = 0;+        done = 1;+      }+      else+      {+        error = CID_Err_Syntax_Error;+        goto Exit;+      }++      if ( upper_nibble )+        *d = (FT_Byte)( val << 4 );+      else+      {+        *d = (FT_Byte)( *d + val );+        d++;+      }++      upper_nibble = (FT_Byte)( 1 - upper_nibble );++      if ( done )+        break;++      p++;+    }++    error = CID_Err_Ok;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  cid_face_open( CID_Face  face,+                 FT_Int    face_index )+  {+    CID_Loader   loader;+    CID_Parser*  parser;+    FT_Memory    memory = face->root.memory;+    FT_Error     error;+++    t1_init_loader( &loader, face );++    parser = &loader.parser;+    error = cid_parser_new( parser, face->root.stream, face->root.memory,+                            (PSAux_Service)face->psaux );+    if ( error )+      goto Exit;++    error = cid_parse_dict( face, &loader,+                            parser->postscript,+                            parser->postscript_len );+    if ( error )+      goto Exit;++    if ( face_index < 0 )+      goto Exit;++    if ( FT_NEW( face->cid_stream ) )+      goto Exit;++    if ( parser->binary_length )+    {+      /* we must convert the data section from hexadecimal to binary */+      if ( FT_ALLOC( face->binary_data, parser->binary_length )         ||+           cid_hex_to_binary( face->binary_data, parser->binary_length,+                              parser->data_offset, face )               )+        goto Exit;++      FT_Stream_OpenMemory( face->cid_stream,+                            face->binary_data, parser->binary_length );+      face->cid.data_offset = 0;+    }+    else+    {+      *face->cid_stream     = *face->root.stream;+      face->cid.data_offset = loader.parser.data_offset;+    }++    error = cid_read_subrs( face );++  Exit:+    t1_done_loader( &loader );+    return error;+  }+++/* END */
+ src/cid/cidload.h view
@@ -0,0 +1,53 @@+/***************************************************************************/+/*                                                                         */+/*  cidload.h                                                              */+/*                                                                         */+/*    CID-keyed Type1 font loader (specification).                         */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CIDLOAD_H__+#define __CIDLOAD_H__+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include "cidparse.h"+++FT_BEGIN_HEADER+++  typedef struct  CID_Loader_+  {+    CID_Parser  parser;          /* parser used to read the stream */+    FT_Int      num_chars;       /* number of characters in encoding */++  } CID_Loader;+++  FT_LOCAL( FT_Long )+  cid_get_offset( FT_Byte**  start,+                  FT_Byte    offsize );++  FT_LOCAL( FT_Error )+  cid_face_open( CID_Face  face,+                 FT_Int    face_index );+++FT_END_HEADER++#endif /* __CIDLOAD_H__ */+++/* END */
+ src/cid/cidobjs.c view
@@ -0,0 +1,482 @@+/***************************************************************************/+/*                                                                         */+/*  cidobjs.c                                                              */+/*                                                                         */+/*    CID objects manager (body).                                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H++#include "cidgload.h"+#include "cidload.h"++#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H++#include "ciderrs.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cidobjs+++  /*************************************************************************/+  /*                                                                       */+  /*                            SLOT  FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  cid_slot_done( FT_GlyphSlot  slot )+  {+    slot->internal->glyph_hints = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  cid_slot_init( FT_GlyphSlot  slot )+  {+    CID_Face          face;+    PSHinter_Service  pshinter;+++    face     = (CID_Face)slot->face;+    pshinter = (PSHinter_Service)face->pshinter;++    if ( pshinter )+    {+      FT_Module  module;+++      module = FT_Get_Module( slot->face->driver->root.library,+                              "pshinter" );+      if ( module )+      {+        T1_Hints_Funcs  funcs;+++        funcs = pshinter->get_t1_funcs( module );+        slot->internal->glyph_hints = (void*)funcs;+      }+    }++    return 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                           SIZE  FUNCTIONS                             */+  /*                                                                       */+  /*************************************************************************/+++  static PSH_Globals_Funcs+  cid_size_get_globals_funcs( CID_Size  size )+  {+    CID_Face          face     = (CID_Face)size->root.face;+    PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;+    FT_Module         module;+++    module = FT_Get_Module( size->root.face->driver->root.library,+                            "pshinter" );+    return ( module && pshinter && pshinter->get_globals_funcs )+           ? pshinter->get_globals_funcs( module )+           : 0;+  }+++  FT_LOCAL_DEF( void )+  cid_size_done( FT_Size  cidsize )         /* CID_Size */+  {+    CID_Size  size = (CID_Size)cidsize;+++    if ( cidsize->internal )+    {+      PSH_Globals_Funcs  funcs;+++      funcs = cid_size_get_globals_funcs( size );+      if ( funcs )+        funcs->destroy( (PSH_Globals)cidsize->internal );++      cidsize->internal = 0;+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  cid_size_init( FT_Size  cidsize )     /* CID_Size */+  {+    CID_Size           size  = (CID_Size)cidsize;+    FT_Error           error = CID_Err_Ok;+    PSH_Globals_Funcs  funcs = cid_size_get_globals_funcs( size );+++    if ( funcs )+    {+      PSH_Globals   globals;+      CID_Face      face = (CID_Face)cidsize->face;+      CID_FaceDict  dict = face->cid.font_dicts + face->root.face_index;+      PS_Private    priv = &dict->private_dict;+++      error = funcs->create( cidsize->face->memory, priv, &globals );+      if ( !error )+        cidsize->internal = (FT_Size_Internal)(void*)globals;+    }++    return error;+  }+++  FT_LOCAL( FT_Error )+  cid_size_request( FT_Size          size,+                    FT_Size_Request  req )+  {+    PSH_Globals_Funcs  funcs;+++    FT_Request_Metrics( size->face, req );++    funcs = cid_size_get_globals_funcs( (CID_Size)size );++    if ( funcs )+      funcs->set_scale( (PSH_Globals)size->internal,+                        size->metrics.x_scale,+                        size->metrics.y_scale,+                        0, 0 );++    return CID_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                           FACE  FUNCTIONS                             */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cid_face_done                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a given face object.                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A pointer to the face object to destroy.                   */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  cid_face_done( FT_Face  cidface )         /* CID_Face */+  {+    CID_Face      face = (CID_Face)cidface;+    FT_Memory     memory;+    CID_FaceInfo  cid;+    PS_FontInfo   info;+++    if ( !face )+      return;++    cid    = &face->cid;+    info   = &cid->font_info;+    memory = cidface->memory;++    /* release subrs */+    if ( face->subrs )+    {+      FT_Int  n;+++      for ( n = 0; n < cid->num_dicts; n++ )+      {+        CID_Subrs  subr = face->subrs + n;+++        if ( subr->code )+        {+          FT_FREE( subr->code[0] );+          FT_FREE( subr->code );+        }+      }++      FT_FREE( face->subrs );+    }++    /* release FontInfo strings */+    FT_FREE( info->version );+    FT_FREE( info->notice );+    FT_FREE( info->full_name );+    FT_FREE( info->family_name );+    FT_FREE( info->weight );++    /* release font dictionaries */+    FT_FREE( cid->font_dicts );+    cid->num_dicts = 0;++    /* release other strings */+    FT_FREE( cid->cid_font_name );+    FT_FREE( cid->registry );+    FT_FREE( cid->ordering );++    cidface->family_name = 0;+    cidface->style_name  = 0;++    FT_FREE( face->binary_data );+    FT_FREE( face->cid_stream );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cid_face_init                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given CID face object.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream     :: The source font stream.                              */+  /*                                                                       */+  /*    face_index :: The index of the font face in the resource.          */+  /*                                                                       */+  /*    num_params :: Number of additional generic parameters.  Ignored.   */+  /*                                                                       */+  /*    params     :: Additional generic parameters.  Ignored.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The newly built face object.                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  cid_face_init( FT_Stream      stream,+                 FT_Face        cidface,        /* CID_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    CID_Face          face = (CID_Face)cidface;+    FT_Error          error;+    PSAux_Service     psaux;+    PSHinter_Service  pshinter;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+    FT_UNUSED( stream );+++    cidface->num_faces = 1;++    psaux = (PSAux_Service)face->psaux;+    if ( !psaux )+    {+      psaux = (PSAux_Service)FT_Get_Module_Interface(+                FT_FACE_LIBRARY( face ), "psaux" );++      face->psaux = psaux;+    }++    pshinter = (PSHinter_Service)face->pshinter;+    if ( !pshinter )+    {+      pshinter = (PSHinter_Service)FT_Get_Module_Interface(+                   FT_FACE_LIBRARY( face ), "pshinter" );++      face->pshinter = pshinter;+    }++    /* open the tokenizer; this will also check the font format */+    if ( FT_STREAM_SEEK( 0 ) )+      goto Exit;++    error = cid_face_open( face, face_index );+    if ( error )+      goto Exit;++    /* if we just wanted to check the format, leave successfully now */+    if ( face_index < 0 )+      goto Exit;++    /* check the face index */+    /* XXX: handle CID fonts with more than a single face */+    if ( face_index != 0 )+    {+      FT_ERROR(( "cid_face_init: invalid face index\n" ));+      error = CID_Err_Invalid_Argument;+      goto Exit;+    }++    /* now load the font program into the face object */++    /* initialize the face object fields */++    /* set up root face fields */+    {+      CID_FaceInfo  cid  = &face->cid;+      PS_FontInfo   info = &cid->font_info;+++      cidface->num_glyphs   = cid->cid_count;+      cidface->num_charmaps = 0;++      cidface->face_index = face_index;+      cidface->face_flags = FT_FACE_FLAG_SCALABLE   | /* scalable outlines */+                            FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */+                            FT_FACE_FLAG_HINTER;      /* has native hinter */++      if ( info->is_fixed_pitch )+        cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      /* XXX: TODO: add kerning with .afm support */++      /* get style name -- be careful, some broken fonts only */+      /* have a /FontName dictionary entry!                   */+      cidface->family_name = info->family_name;+      /* assume "Regular" style if we don't know better */+      cidface->style_name = (char *)"Regular";+      if ( cidface->family_name )+      {+        char*  full   = info->full_name;+        char*  family = cidface->family_name;+++        if ( full )+        {+          while ( *full )+          {+            if ( *full == *family )+            {+              family++;+              full++;+            }+            else+            {+              if ( *full == ' ' || *full == '-' )+                full++;+              else if ( *family == ' ' || *family == '-' )+                family++;+              else+              {+                if ( !*family )+                  cidface->style_name = full;+                break;+              }+            }+          }+        }+      }+      else+      {+        /* do we have a `/FontName'? */+        if ( cid->cid_font_name )+          cidface->family_name = cid->cid_font_name;+      }++      /* compute style flags */+      cidface->style_flags = 0;+      if ( info->italic_angle )+        cidface->style_flags |= FT_STYLE_FLAG_ITALIC;+      if ( info->weight )+      {+        if ( !ft_strcmp( info->weight, "Bold"  ) ||+             !ft_strcmp( info->weight, "Black" ) )+          cidface->style_flags |= FT_STYLE_FLAG_BOLD;+      }++      /* no embedded bitmap support */+      cidface->num_fixed_sizes = 0;+      cidface->available_sizes = 0;++      cidface->bbox.xMin =   cid->font_bbox.xMin            >> 16;+      cidface->bbox.yMin =   cid->font_bbox.yMin            >> 16;+      /* no `U' suffix here to 0xFFFF! */+      cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16;+      cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16;++      if ( !cidface->units_per_EM )+        cidface->units_per_EM = 1000;++      cidface->ascender  = (FT_Short)( cidface->bbox.yMax );+      cidface->descender = (FT_Short)( cidface->bbox.yMin );++      cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 );+      if ( cidface->height < cidface->ascender - cidface->descender )+        cidface->height = (FT_Short)( cidface->ascender - cidface->descender );++      cidface->underline_position  = (FT_Short)info->underline_position;+      cidface->underline_thickness = (FT_Short)info->underline_thickness;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cid_driver_init                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given CID driver object.                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target driver object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  cid_driver_init( FT_Module  driver )+  {+    FT_UNUSED( driver );++    return CID_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    cid_driver_done                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a given CID driver.                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target CID driver.                       */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  cid_driver_done( FT_Module  driver )+  {+    FT_UNUSED( driver );+  }+++/* END */
+ src/cid/cidobjs.h view
@@ -0,0 +1,154 @@+/***************************************************************************/+/*                                                                         */+/*  cidobjs.h                                                              */+/*                                                                         */+/*    CID objects manager (specification).                                 */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CIDOBJS_H__+#define __CIDOBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_TYPE1_TYPES_H+++FT_BEGIN_HEADER+++  /* The following structures must be defined by the hinter */+  typedef struct CID_Size_Hints_   CID_Size_Hints;+  typedef struct CID_Glyph_Hints_  CID_Glyph_Hints;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CID_Driver                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 driver object.                                */+  /*                                                                       */+  typedef struct CID_DriverRec_*  CID_Driver;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CID_Size                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 size object.                                  */+  /*                                                                       */+  typedef struct CID_SizeRec_*  CID_Size;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CID_GlyphSlot                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 glyph slot object.                            */+  /*                                                                       */+  typedef struct CID_GlyphSlotRec_*  CID_GlyphSlot;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    CID_CharMap                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 character mapping object.                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The Type 1 format doesn't use a charmap but an encoding table.     */+  /*    The driver is responsible for making up charmap objects            */+  /*    corresponding to these tables.                                     */+  /*                                                                       */+  typedef struct CID_CharMapRec_*  CID_CharMap;+++  /*************************************************************************/+  /*                                                                       */+  /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF                                 */+  /*                                                                       */+  /*************************************************************************/+++  typedef struct  CID_SizeRec_+  {+    FT_SizeRec  root;+    FT_Bool     valid;++  } CID_SizeRec;+++  typedef struct  CID_GlyphSlotRec_+  {+    FT_GlyphSlotRec  root;++    FT_Bool          hint;+    FT_Bool          scaled;++    FT_Fixed         x_scale;+    FT_Fixed         y_scale;++  } CID_GlyphSlotRec;+++  FT_LOCAL( void )+  cid_slot_done( FT_GlyphSlot  slot );++  FT_LOCAL( FT_Error )+  cid_slot_init( FT_GlyphSlot  slot );+++  FT_LOCAL( void )+  cid_size_done( FT_Size  size );       /* CID_Size */++  FT_LOCAL( FT_Error )+  cid_size_init( FT_Size  size );       /* CID_Size */++  FT_LOCAL( FT_Error )+  cid_size_request( FT_Size          size,      /* CID_Size */+                    FT_Size_Request  req );++  FT_LOCAL( FT_Error )+  cid_face_init( FT_Stream      stream,+                 FT_Face        face,           /* CID_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params );++  FT_LOCAL( void )+  cid_face_done( FT_Face  face );               /* CID_Face */+++  FT_LOCAL( FT_Error )+  cid_driver_init( FT_Module  driver );++  FT_LOCAL( void )+  cid_driver_done( FT_Module  driver );+++FT_END_HEADER++#endif /* __CIDOBJS_H__ */+++/* END */
+ src/cid/cidparse.c view
@@ -0,0 +1,225 @@+/***************************************************************************/+/*                                                                         */+/*  cidparse.c                                                             */+/*                                                                         */+/*    CID-keyed Type1 parser (body).                                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_STREAM_H++#include "cidparse.h"++#include "ciderrs.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_cidparse+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    INPUT STREAM PARSER                        *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  cid_parser_new( CID_Parser*    parser,+                  FT_Stream      stream,+                  FT_Memory      memory,+                  PSAux_Service  psaux )+  {+    FT_Error  error;+    FT_ULong  base_offset, offset, ps_len;+    FT_Byte   *cur, *limit;+    FT_Byte   *arg1, *arg2;+++    FT_MEM_ZERO( parser, sizeof ( *parser ) );+    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );++    parser->stream = stream;++    base_offset = FT_STREAM_POS();++    /* first of all, check the font format in the header */+    if ( FT_FRAME_ENTER( 31 ) )+      goto Exit;++    if ( ft_strncmp( (char *)stream->cursor,+                     "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )+    {+      FT_TRACE2(( "[not a valid CID-keyed font]\n" ));+      error = CID_Err_Unknown_File_Format;+    }++    FT_FRAME_EXIT();+    if ( error )+      goto Exit;++  Again:+    /* now, read the rest of the file until we find */+    /* `StartData' or `/sfnts'                      */+    {+      FT_Byte   buffer[256 + 10];+      FT_Long   read_len = 256 + 10; /* same as signed FT_Stream->size */+      FT_Byte*  p        = buffer;+++      for ( offset = FT_STREAM_POS(); ; offset += 256 )+      {+        FT_Long  stream_len; /* same as signed FT_Stream->size */+++        stream_len = stream->size - FT_STREAM_POS();+        if ( stream_len == 0 )+        {+          FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));+          error = CID_Err_Unknown_File_Format;+          goto Exit;+        }++        read_len = FT_MIN( read_len, stream_len );+        if ( FT_STREAM_READ( p, read_len ) )+          goto Exit;++        if ( read_len < 256 )+          p[read_len]  = '\0';++        limit = p + read_len - 10;++        for ( p = buffer; p < limit; p++ )+        {+          if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )+          {+            /* save offset of binary data after `StartData' */+            offset += p - buffer + 10;+            goto Found;+          }+          else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )+          {+            offset += p - buffer + 7;+            goto Found;+          }+        }++        FT_MEM_MOVE( buffer, p, 10 );+        read_len = 256;+        p = buffer + 10;+      }+    }++  Found:+    /* We have found the start of the binary data or the `/sfnts' token. */+    /* Now rewind and extract the frame corresponding to this PostScript */+    /* section.                                                          */++    ps_len = offset - base_offset;+    if ( FT_STREAM_SEEK( base_offset )                  ||+         FT_FRAME_EXTRACT( ps_len, parser->postscript ) )+      goto Exit;++    parser->data_offset    = offset;+    parser->postscript_len = ps_len;+    parser->root.base      = parser->postscript;+    parser->root.cursor    = parser->postscript;+    parser->root.limit     = parser->root.cursor + ps_len;+    parser->num_dict       = -1;++    /* Finally, we check whether `StartData' or `/sfnts' was real --  */+    /* it could be in a comment or string.  We also get the arguments */+    /* of `StartData' to find out whether the data is represented in  */+    /* binary or hex format.                                          */++    arg1 = parser->root.cursor;+    cid_parser_skip_PS_token( parser );+    cid_parser_skip_spaces  ( parser );+    arg2 = parser->root.cursor;+    cid_parser_skip_PS_token( parser );+    cid_parser_skip_spaces  ( parser );++    limit = parser->root.limit;+    cur   = parser->root.cursor;++    while ( cur < limit )+    {+      if ( parser->root.error )+      {+        error = parser->root.error;+        goto Exit;+      }++      if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )+      {+        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )+          parser->binary_length = ft_atol( (const char *)arg2 );++        limit = parser->root.limit;+        cur   = parser->root.cursor;+        goto Exit;+      }+      else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )+      {+        FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));+        error = CID_Err_Unknown_File_Format;+        goto Exit;+      }++      cid_parser_skip_PS_token( parser );+      cid_parser_skip_spaces  ( parser );+      arg1 = arg2;+      arg2 = cur;+      cur  = parser->root.cursor;+    }++    /* we haven't found the correct `StartData'; go back and continue */+    /* searching                                                      */+    FT_FRAME_RELEASE( parser->postscript );+    if ( !FT_STREAM_SEEK( offset ) )+      goto Again;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  cid_parser_done( CID_Parser*  parser )+  {+    /* always free the private dictionary */+    if ( parser->postscript )+    {+      FT_Stream  stream = parser->stream;+++      FT_FRAME_RELEASE( parser->postscript );+    }+    parser->root.funcs.done( &parser->root );+  }+++/* END */
+ src/cid/cidparse.h view
@@ -0,0 +1,123 @@+/***************************************************************************/+/*                                                                         */+/*  cidparse.h                                                             */+/*                                                                         */+/*    CID-keyed Type1 parser (specification).                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CIDPARSE_H__+#define __CIDPARSE_H__+++#include <ft2build.h>+#include FT_INTERNAL_TYPE1_TYPES_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    CID_Parser                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A CID_Parser is an object used to parse a Type 1 fonts very        */+  /*    quickly.                                                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root           :: The root PS_ParserRec fields.                    */+  /*                                                                       */+  /*    stream         :: The current input stream.                        */+  /*                                                                       */+  /*    postscript     :: A pointer to the data to be parsed.              */+  /*                                                                       */+  /*    postscript_len :: The length of the data to be parsed.             */+  /*                                                                       */+  /*    data_offset    :: The start position of the binary data (i.e., the */+  /*                      end of the data to be parsed.                    */+  /*                                                                       */+  /*    binary_length  :: The length of the data after the `StartData'     */+  /*                      command if the data format is hexadecimal.       */+  /*                                                                       */+  /*    cid            :: A structure which holds the information about    */+  /*                      the current font.                                */+  /*                                                                       */+  /*    num_dict       :: The number of font dictionaries.                 */+  /*                                                                       */+  typedef struct  CID_Parser_+  {+    PS_ParserRec  root;+    FT_Stream     stream;++    FT_Byte*      postscript;+    FT_Long       postscript_len;++    FT_ULong      data_offset;++    FT_Long       binary_length;++    CID_FaceInfo  cid;+    FT_Int        num_dict;++  } CID_Parser;+++  FT_LOCAL( FT_Error )+  cid_parser_new( CID_Parser*    parser,+                  FT_Stream      stream,+                  FT_Memory      memory,+                  PSAux_Service  psaux );++  FT_LOCAL( void )+  cid_parser_done( CID_Parser*  parser );+++  /*************************************************************************/+  /*                                                                       */+  /*                            PARSING ROUTINES                           */+  /*                                                                       */+  /*************************************************************************/++#define cid_parser_skip_spaces( p ) \+          (p)->root.funcs.skip_spaces( &(p)->root )+#define cid_parser_skip_PS_token( p ) \+          (p)->root.funcs.skip_PS_token( &(p)->root )++#define cid_parser_to_int( p )        (p)->root.funcs.to_int( &(p)->root )+#define cid_parser_to_fixed( p, t )   (p)->root.funcs.to_fixed( &(p)->root, t )++#define cid_parser_to_coord_array( p, m, c )                          \+          (p)->root.funcs.to_coord_array( &(p)->root, m, c )+#define cid_parser_to_fixed_array( p, m, f, t )                          \+          (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )+#define cid_parser_to_token( p, t )                         \+          (p)->root.funcs.to_token( &(p)->root, t )+#define cid_parser_to_token_array( p, t, m, c )                          \+          (p)->root.funcs.to_token_array( &(p)->root, t, m, c )++#define cid_parser_load_field( p, f, o )                              \+          (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 )+#define cid_parser_load_field_table( p, f, o )                              \+          (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 )+++FT_END_HEADER++#endif /* __CIDPARSE_H__ */+++/* END */
+ src/cid/cidriver.c view
@@ -0,0 +1,240 @@+/***************************************************************************/+/*                                                                         */+/*  cidriver.c                                                             */+/*                                                                         */+/*    CID driver interface (body).                                         */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "cidriver.h"+#include "cidgload.h"+#include FT_INTERNAL_DEBUG_H++#include "ciderrs.h"++#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_XFREE86_NAME_H+#include FT_SERVICE_POSTSCRIPT_INFO_H+#include FT_SERVICE_CID_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ciddriver+++  /*+   *  POSTSCRIPT NAME SERVICE+   *+   */++  static const char*+  cid_get_postscript_name( CID_Face  face )+  {+    const char*  result = face->cid.cid_font_name;+++    if ( result && result[0] == '/' )+      result++;++    return result;+  }+++  static const FT_Service_PsFontNameRec  cid_service_ps_name =+  {+    (FT_PsName_GetFunc) cid_get_postscript_name+  };+++  /*+   *  POSTSCRIPT INFO SERVICE+   *+   */++  static FT_Error+  cid_ps_get_font_info( FT_Face          face,+                        PS_FontInfoRec*  afont_info )+  {+    *afont_info = ((CID_Face)face)->cid.font_info;++    return CID_Err_Ok;+  }++  static FT_Error+  cid_ps_get_font_extra( FT_Face          face,+                        PS_FontExtraRec*  afont_extra )+  {+    *afont_extra = ((CID_Face)face)->font_extra;++    return CID_Err_Ok;+  }++  static const FT_Service_PsInfoRec  cid_service_ps_info =+  {+    (PS_GetFontInfoFunc)   cid_ps_get_font_info,+    (PS_GetFontExtraFunc)  cid_ps_get_font_extra,+    (PS_HasGlyphNamesFunc) NULL,        /* unsupported with CID fonts */+    (PS_GetFontPrivateFunc)NULL         /* unsupported                */+  };+++  /*+   *  CID INFO SERVICE+   *+   */+  static FT_Error+  cid_get_ros( CID_Face      face,+               const char*  *registry,+               const char*  *ordering,+               FT_Int       *supplement )+  {+    CID_FaceInfo  cid = &face->cid;+++    if ( registry )+      *registry = cid->registry;+      +    if ( ordering )+      *ordering = cid->ordering;++    if ( supplement )+      *supplement = cid->supplement;+      +    return CID_Err_Ok;+  }+++  static FT_Error+  cid_get_is_cid( CID_Face  face,+                  FT_Bool  *is_cid )+  {+    FT_Error  error = CID_Err_Ok;+    FT_UNUSED( face );+++    if ( is_cid )+      *is_cid = 1; /* cid driver is only used for CID keyed fonts */++    return error;+  }+++  static FT_Error+  cid_get_cid_from_glyph_index( CID_Face  face,+                                FT_UInt   glyph_index,+                                FT_UInt  *cid )+  {+    FT_Error  error = CID_Err_Ok;+    FT_UNUSED( face );+++    if ( cid )+      *cid = glyph_index; /* identity mapping */++    return error;+  }+++  static const FT_Service_CIDRec  cid_service_cid_info =+  {+     (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros,+     (FT_CID_GetIsInternallyCIDKeyedFunc)      cid_get_is_cid,+     (FT_CID_GetCIDFromGlyphIndexFunc)         cid_get_cid_from_glyph_index+  };+++  /*+   *  SERVICE LIST+   *+   */++  static const FT_ServiceDescRec  cid_services[] =+  {+    { FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CID },+    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name },+    { FT_SERVICE_ID_POSTSCRIPT_INFO,      &cid_service_ps_info },+    { FT_SERVICE_ID_CID,                  &cid_service_cid_info },+    { NULL, NULL }+  };+++  FT_CALLBACK_DEF( FT_Module_Interface )+  cid_get_interface( FT_Module    module,+                     const char*  cid_interface )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( cid_services, cid_interface );+  }++++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  t1cid_driver_class =+  {+    /* first of all, the FT_Module_Class fields */+    {+      FT_MODULE_FONT_DRIVER       |+      FT_MODULE_DRIVER_SCALABLE   |+      FT_MODULE_DRIVER_HAS_HINTER,++      sizeof( FT_DriverRec ),+      "t1cid",   /* module name           */+      0x10000L,  /* version 1.0 of driver */+      0x20000L,  /* requires FreeType 2.0 */++      0,++      cid_driver_init,+      cid_driver_done,+      cid_get_interface+    },++    /* then the other font drivers fields */+    sizeof( CID_FaceRec ),+    sizeof( CID_SizeRec ),+    sizeof( CID_GlyphSlotRec ),++    cid_face_init,+    cid_face_done,++    cid_size_init,+    cid_size_done,+    cid_slot_init,+    cid_slot_done,++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif++    cid_slot_load_glyph,++    0,                      /* FT_Face_GetKerningFunc  */+    0,                      /* FT_Face_AttachFunc      */++    0,                      /* FT_Face_GetAdvancesFunc */++    cid_size_request,+    0                       /* FT_Size_SelectFunc      */+  };+++/* END */
+ src/cid/cidriver.h view
@@ -0,0 +1,43 @@+/***************************************************************************/+/*                                                                         */+/*  cidriver.h                                                             */+/*                                                                         */+/*    High-level CID driver interface (specification).                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __CIDRIVER_H__+#define __CIDRIVER_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  FT_CALLBACK_TABLE+  const FT_Driver_ClassRec  t1cid_driver_class;+++FT_END_HEADER++#endif /* __CIDRIVER_H__ */+++/* END */
+ src/cid/cidtoken.h view
@@ -0,0 +1,112 @@+/***************************************************************************/+/*                                                                         */+/*  cidtoken.h                                                             */+/*                                                                         */+/*    CID token definitions (specification only).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  CID_FaceInfoRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_CID_INFO++  T1_FIELD_KEY   ( "CIDFontName",    cid_font_name, 0 )+  T1_FIELD_FIXED ( "CIDFontVersion", cid_version,   0 )+  T1_FIELD_NUM   ( "CIDFontType",    cid_font_type, 0 )+  T1_FIELD_STRING( "Registry",       registry,      0 )+  T1_FIELD_STRING( "Ordering",       ordering,      0 )+  T1_FIELD_NUM   ( "Supplement",     supplement,    0 )+  T1_FIELD_NUM   ( "UIDBase",        uid_base,      0 )+  T1_FIELD_NUM   ( "CIDMapOffset",   cidmap_offset, 0 )+  T1_FIELD_NUM   ( "FDBytes",        fd_bytes,      0 )+  T1_FIELD_NUM   ( "GDBytes",        gd_bytes,      0 )+  T1_FIELD_NUM   ( "CIDCount",       cid_count,     0 )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_FontInfoRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_INFO++  T1_FIELD_STRING( "version",            version,             0 )+  T1_FIELD_STRING( "Notice",             notice,              0 )+  T1_FIELD_STRING( "FullName",           full_name,           0 )+  T1_FIELD_STRING( "FamilyName",         family_name,         0 )+  T1_FIELD_STRING( "Weight",             weight,              0 )+  T1_FIELD_NUM   ( "ItalicAngle",        italic_angle,        0 )+  T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch,      0 )+  T1_FIELD_NUM   ( "UnderlinePosition",  underline_position,  0 )+  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, 0 )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_FontExtraRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_EXTRA++  T1_FIELD_NUM   ( "FSType",             fs_type,             0 )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  CID_FaceDictRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_DICT++  T1_FIELD_NUM  ( "PaintType",          paint_type,          0 )+  T1_FIELD_NUM  ( "FontType",           font_type,           0 )+  T1_FIELD_NUM  ( "SubrMapOffset",      subrmap_offset,      0 )+  T1_FIELD_NUM  ( "SDBytes",            sd_bytes,            0 )+  T1_FIELD_NUM  ( "SubrCount",          num_subrs,           0 )+  T1_FIELD_NUM  ( "lenBuildCharArray",  len_buildchar,       0 )+  T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )+  T1_FIELD_FIXED( "StrokeWidth",        stroke_width,        0 )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_PrivateRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_PRIVATE++  T1_FIELD_NUM       ( "UniqueID",         unique_id,      0 )+  T1_FIELD_NUM       ( "lenIV",            lenIV,          0 )+  T1_FIELD_NUM       ( "LanguageGroup",    language_group, 0 )+  T1_FIELD_NUM       ( "password",         password,       0 )++  T1_FIELD_FIXED_1000( "BlueScale",        blue_scale,     0 )+  T1_FIELD_NUM       ( "BlueShift",        blue_shift,     0 )+  T1_FIELD_NUM       ( "BlueFuzz",         blue_fuzz,      0 )++  T1_FIELD_NUM_TABLE ( "BlueValues",       blue_values,        14, 0 )+  T1_FIELD_NUM_TABLE ( "OtherBlues",       other_blues,        10, 0 )+  T1_FIELD_NUM_TABLE ( "FamilyBlues",      family_blues,       14, 0 )+  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )++  T1_FIELD_NUM_TABLE2( "StdHW",            standard_width,      1, 0 )+  T1_FIELD_NUM_TABLE2( "StdVW",            standard_height,     1, 0 )+  T1_FIELD_NUM_TABLE2( "MinFeature",       min_feature,         2, 0 )++  T1_FIELD_NUM_TABLE ( "StemSnapH",        snap_widths,        12, 0 )+  T1_FIELD_NUM_TABLE ( "StemSnapV",        snap_heights,       12, 0 )++  T1_FIELD_BOOL      ( "ForceBold",        force_bold,          0 )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  FT_BBox+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_BBOX++  T1_FIELD_BBOX( "FontBBox", xMin, 0 )+++/* END */
+ src/cid/type1cid.c view
@@ -0,0 +1,29 @@+/***************************************************************************/+/*                                                                         */+/*  type1cid.c                                                             */+/*                                                                         */+/*    FreeType OpenType driver component (body only).                      */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "cidparse.c"+#include "cidload.c"+#include "cidobjs.c"+#include "cidriver.c"+#include "cidgload.c"+++/* END */
+ src/gzip/adler32.c view
@@ -0,0 +1,48 @@+/* adler32.c -- compute the Adler-32 checksum of a data stream+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* @(#) $Id$ */++#include "zlib.h"++#define BASE 65521L /* largest prime smaller than 65536 */+#define NMAX 5552+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */++#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);+#define DO16(buf)   DO8(buf,0); DO8(buf,8);++/* ========================================================================= */+ZEXPORT(uLong) adler32( /* adler, buf, len) */+    uLong adler,+    const Bytef *buf,+    uInt len )+{+    unsigned long s1 = adler & 0xffff;+    unsigned long s2 = (adler >> 16) & 0xffff;+    int k;++    if (buf == Z_NULL) return 1L;++    while (len > 0) {+        k = len < NMAX ? len : NMAX;+        len -= k;+        while (k >= 16) {+            DO16(buf);+            buf += 16;+            k -= 16;+        }+        if (k != 0) do {+            s1 += *buf++;+            s2 += s1;+        } while (--k);+        s1 %= BASE;+        s2 %= BASE;+    }+    return (s2 << 16) | s1;+}
+ src/gzip/ftgzip.c view
@@ -0,0 +1,688 @@+/***************************************************************************/+/*                                                                         */+/*  ftgzip.c                                                               */+/*                                                                         */+/*    FreeType support for .gz compressed files.                           */+/*                                                                         */+/*  This optional component relies on zlib.  It should mainly be used to   */+/*  parse compressed PCF fonts, as found with many X11 server              */+/*  distributions.                                                         */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2009, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_DEBUG_H+#include FT_GZIP_H+#include FT_CONFIG_STANDARD_LIBRARY_H+++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  Gzip_Err_+#define FT_ERR_BASE    FT_Mod_Err_Gzip++#include FT_ERRORS_H+++#ifdef FT_CONFIG_OPTION_USE_ZLIB++#ifdef FT_CONFIG_OPTION_PIC+#error "gzip code does not support PIC yet"+#endif ++#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB++#include <zlib.h>++#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */++ /* In this case, we include our own modified sources of the ZLib    */+ /* within the "ftgzip" component.  The modifications were necessary */+ /* to #include all files without conflicts, as well as preventing   */+ /* the definition of "extern" functions that may cause linking      */+ /* conflicts when a program is linked with both FreeType and the    */+ /* original ZLib.                                                   */++#define NO_DUMMY_DECL+#ifndef USE_ZLIB_ZCALLOC+#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */+#endif++#include "zlib.h"++#undef  SLOW+#define SLOW  1  /* we can't use asm-optimized sources here! */++  /* Urgh.  `inflate_mask' must not be declared twice -- C++ doesn't like+     this.  We temporarily disable it and load all necessary header files. */+#define NO_INFLATE_MASK+#include "zutil.h"+#include "inftrees.h"+#include "infblock.h"+#include "infcodes.h"+#include "infutil.h"+#undef  NO_INFLATE_MASK++  /* infutil.c must be included before infcodes.c */+#include "zutil.c"+#include "inftrees.c"+#include "infutil.c"+#include "infcodes.c"+#include "infblock.c"+#include "inflate.c"+#include "adler32.c"++#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */+++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****            Z L I B   M E M O R Y   M A N A G E M E N T          *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++  /* it is better to use FreeType memory routines instead of raw+     'malloc/free' */++  static voidpf+  ft_gzip_alloc( FT_Memory  memory,+                 uInt       items,+                 uInt       size )+  {+    FT_ULong    sz = (FT_ULong)size * items;+    FT_Error    error;+    FT_Pointer  p  = NULL;+++    (void)FT_ALLOC( p, sz );+    return p;+  }+++  static void+  ft_gzip_free( FT_Memory  memory,+                voidpf     address )+  {+    FT_MEM_FREE( address );+  }+++#if !defined( FT_CONFIG_OPTION_SYSTEM_ZLIB ) && !defined( USE_ZLIB_ZCALLOC )++  local voidpf+  zcalloc ( voidpf    opaque,+            unsigned  items,+            unsigned  size )+  {+    return ft_gzip_alloc( (FT_Memory)opaque, items, size );+  }++  local void+  zcfree( voidpf  opaque,+          voidpf  ptr )+  {+    ft_gzip_free( (FT_Memory)opaque, ptr );+  }++#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */+++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****               Z L I B   F I L E   D E S C R I P T O R           *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++#define FT_GZIP_BUFFER_SIZE  4096++  typedef struct  FT_GZipFileRec_+  {+    FT_Stream  source;         /* parent/source stream        */+    FT_Stream  stream;         /* embedding stream            */+    FT_Memory  memory;         /* memory allocator            */+    z_stream   zstream;        /* zlib input stream           */++    FT_ULong   start;          /* starting position, after .gz header */+    FT_Byte    input[FT_GZIP_BUFFER_SIZE];   /* input read buffer  */++    FT_Byte    buffer[FT_GZIP_BUFFER_SIZE];  /* output buffer      */+    FT_ULong   pos;                          /* position in output */+    FT_Byte*   cursor;+    FT_Byte*   limit;++  } FT_GZipFileRec, *FT_GZipFile;+++  /* gzip flag byte */+#define FT_GZIP_ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */+#define FT_GZIP_HEAD_CRC     0x02 /* bit 1 set: header CRC present */+#define FT_GZIP_EXTRA_FIELD  0x04 /* bit 2 set: extra field present */+#define FT_GZIP_ORIG_NAME    0x08 /* bit 3 set: original file name present */+#define FT_GZIP_COMMENT      0x10 /* bit 4 set: file comment present */+#define FT_GZIP_RESERVED     0xE0 /* bits 5..7: reserved */+++  /* check and skip .gz header - we don't support `transparent' compression */+  static FT_Error+  ft_gzip_check_header( FT_Stream  stream )+  {+    FT_Error  error;+    FT_Byte   head[4];+++    if ( FT_STREAM_SEEK( 0 )       ||+         FT_STREAM_READ( head, 4 ) )+      goto Exit;++    /* head[0] && head[1] are the magic numbers;    */+    /* head[2] is the method, and head[3] the flags */+    if ( head[0] != 0x1f              ||+         head[1] != 0x8b              ||+         head[2] != Z_DEFLATED        ||+        (head[3] & FT_GZIP_RESERVED)  )+    {+      error = Gzip_Err_Invalid_File_Format;+      goto Exit;+    }++    /* skip time, xflags and os code */+    (void)FT_STREAM_SKIP( 6 );++    /* skip the extra field */+    if ( head[3] & FT_GZIP_EXTRA_FIELD )+    {+      FT_UInt  len;+++      if ( FT_READ_USHORT_LE( len ) ||+           FT_STREAM_SKIP( len )    )+        goto Exit;+    }++    /* skip original file name */+    if ( head[3] & FT_GZIP_ORIG_NAME )+      for (;;)+      {+        FT_UInt  c;+++        if ( FT_READ_BYTE( c ) )+          goto Exit;++        if ( c == 0 )+          break;+      }++    /* skip .gz comment */+    if ( head[3] & FT_GZIP_COMMENT )+      for (;;)+      {+        FT_UInt  c;+++        if ( FT_READ_BYTE( c ) )+          goto Exit;++        if ( c == 0 )+          break;+      }++    /* skip CRC */+    if ( head[3] & FT_GZIP_HEAD_CRC )+      if ( FT_STREAM_SKIP( 2 ) )+        goto Exit;++  Exit:+    return error;+  }+++  static FT_Error+  ft_gzip_file_init( FT_GZipFile  zip,+                     FT_Stream    stream,+                     FT_Stream    source )+  {+    z_stream*  zstream = &zip->zstream;+    FT_Error   error   = Gzip_Err_Ok;+++    zip->stream = stream;+    zip->source = source;+    zip->memory = stream->memory;++    zip->limit  = zip->buffer + FT_GZIP_BUFFER_SIZE;+    zip->cursor = zip->limit;+    zip->pos    = 0;++    /* check and skip .gz header */+    {+      stream = source;++      error = ft_gzip_check_header( stream );+      if ( error )+        goto Exit;++      zip->start = FT_STREAM_POS();+    }++    /* initialize zlib -- there is no zlib header in the compressed stream */+    zstream->zalloc = (alloc_func)ft_gzip_alloc;+    zstream->zfree  = (free_func) ft_gzip_free;+    zstream->opaque = stream->memory;++    zstream->avail_in = 0;+    zstream->next_in  = zip->buffer;++    if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK ||+         zstream->next_in == NULL                     )+      error = Gzip_Err_Invalid_File_Format;++  Exit:+    return error;+  }+++  static void+  ft_gzip_file_done( FT_GZipFile  zip )+  {+    z_stream*  zstream = &zip->zstream;+++    inflateEnd( zstream );++    /* clear the rest */+    zstream->zalloc    = NULL;+    zstream->zfree     = NULL;+    zstream->opaque    = NULL;+    zstream->next_in   = NULL;+    zstream->next_out  = NULL;+    zstream->avail_in  = 0;+    zstream->avail_out = 0;++    zip->memory = NULL;+    zip->source = NULL;+    zip->stream = NULL;+  }+++  static FT_Error+  ft_gzip_file_reset( FT_GZipFile  zip )+  {+    FT_Stream  stream = zip->source;+    FT_Error   error;+++    if ( !FT_STREAM_SEEK( zip->start ) )+    {+      z_stream*  zstream = &zip->zstream;+++      inflateReset( zstream );++      zstream->avail_in  = 0;+      zstream->next_in   = zip->input;+      zstream->avail_out = 0;+      zstream->next_out  = zip->buffer;++      zip->limit  = zip->buffer + FT_GZIP_BUFFER_SIZE;+      zip->cursor = zip->limit;+      zip->pos    = 0;+    }++    return error;+  }+++  static FT_Error+  ft_gzip_file_fill_input( FT_GZipFile  zip )+  {+    z_stream*  zstream = &zip->zstream;+    FT_Stream  stream  = zip->source;+    FT_ULong   size;+++    if ( stream->read )+    {+      size = stream->read( stream, stream->pos, zip->input,+                           FT_GZIP_BUFFER_SIZE );+      if ( size == 0 )+        return Gzip_Err_Invalid_Stream_Operation;+    }+    else+    {+      size = stream->size - stream->pos;+      if ( size > FT_GZIP_BUFFER_SIZE )+        size = FT_GZIP_BUFFER_SIZE;++      if ( size == 0 )+        return Gzip_Err_Invalid_Stream_Operation;++      FT_MEM_COPY( zip->input, stream->base + stream->pos, size );+    }+    stream->pos += size;++    zstream->next_in  = zip->input;+    zstream->avail_in = size;++    return Gzip_Err_Ok;+  }+++  static FT_Error+  ft_gzip_file_fill_output( FT_GZipFile  zip )+  {+    z_stream*  zstream = &zip->zstream;+    FT_Error   error   = Gzip_Err_Ok;+++    zip->cursor        = zip->buffer;+    zstream->next_out  = zip->cursor;+    zstream->avail_out = FT_GZIP_BUFFER_SIZE;++    while ( zstream->avail_out > 0 )+    {+      int  err;+++      if ( zstream->avail_in == 0 )+      {+        error = ft_gzip_file_fill_input( zip );+        if ( error )+          break;+      }++      err = inflate( zstream, Z_NO_FLUSH );++      if ( err == Z_STREAM_END )+      {+        zip->limit = zstream->next_out;+        if ( zip->limit == zip->cursor )+          error = Gzip_Err_Invalid_Stream_Operation;+        break;+      }+      else if ( err != Z_OK )+      {+        error = Gzip_Err_Invalid_Stream_Operation;+        break;+      }+    }++    return error;+  }+++  /* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */+  static FT_Error+  ft_gzip_file_skip_output( FT_GZipFile  zip,+                            FT_ULong     count )+  {+    FT_Error  error = Gzip_Err_Ok;+    FT_ULong  delta;+++    for (;;)+    {+      delta = (FT_ULong)( zip->limit - zip->cursor );+      if ( delta >= count )+        delta = count;++      zip->cursor += delta;+      zip->pos    += delta;++      count -= delta;+      if ( count == 0 )+        break;++      error = ft_gzip_file_fill_output( zip );+      if ( error )+        break;+    }++    return error;+  }+++  static FT_ULong+  ft_gzip_file_io( FT_GZipFile  zip,+                   FT_ULong     pos,+                   FT_Byte*     buffer,+                   FT_ULong     count )+  {+    FT_ULong  result = 0;+    FT_Error  error;+++    /* Reset inflate stream if we're seeking backwards.        */+    /* Yes, that is not too efficient, but it saves memory :-) */+    if ( pos < zip->pos )+    {+      error = ft_gzip_file_reset( zip );+      if ( error )+        goto Exit;+    }++    /* skip unwanted bytes */+    if ( pos > zip->pos )+    {+      error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );+      if ( error )+        goto Exit;+    }++    if ( count == 0 )+      goto Exit;++    /* now read the data */+    for (;;)+    {+      FT_ULong  delta;+++      delta = (FT_ULong)( zip->limit - zip->cursor );+      if ( delta >= count )+        delta = count;++      FT_MEM_COPY( buffer, zip->cursor, delta );+      buffer      += delta;+      result      += delta;+      zip->cursor += delta;+      zip->pos    += delta;++      count -= delta;+      if ( count == 0 )+        break;++      error = ft_gzip_file_fill_output( zip );+      if ( error )+        break;+    }++  Exit:+    return result;+  }+++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****               G Z   E M B E D D I N G   S T R E A M             *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++  static void+  ft_gzip_stream_close( FT_Stream  stream )+  {+    FT_GZipFile  zip    = (FT_GZipFile)stream->descriptor.pointer;+    FT_Memory    memory = stream->memory;+++    if ( zip )+    {+      /* finalize gzip file descriptor */+      ft_gzip_file_done( zip );++      FT_FREE( zip );++      stream->descriptor.pointer = NULL;+    }+  }+++  static FT_ULong+  ft_gzip_stream_io( FT_Stream  stream,+                     FT_ULong   pos,+                     FT_Byte*   buffer,+                     FT_ULong   count )+  {+    FT_GZipFile  zip = (FT_GZipFile)stream->descriptor.pointer;+++    return ft_gzip_file_io( zip, pos, buffer, count );+  }+++  static FT_ULong+  ft_gzip_get_uncompressed_size( FT_Stream  stream )+  {+    FT_Error  error;+    FT_ULong  old_pos;+    FT_ULong  result = 0;+++    old_pos = stream->pos;+    if ( !FT_Stream_Seek( stream, stream->size - 4 ) )+    {+      result = (FT_ULong)FT_Stream_ReadLong( stream, &error );+      if ( error )+        result = 0;++      (void)FT_Stream_Seek( stream, old_pos );+    }++    return result;+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Stream_OpenGzip( FT_Stream  stream,+                      FT_Stream  source )+  {+    FT_Error     error;+    FT_Memory    memory = source->memory;+    FT_GZipFile  zip;+++    /*+     *  check the header right now; this prevents allocating un-necessary+     *  objects when we don't need them+     */+    error = ft_gzip_check_header( source );+    if ( error )+      goto Exit;++    FT_ZERO( stream );+    stream->memory = memory;++    if ( !FT_QNEW( zip ) )+    {+      error = ft_gzip_file_init( zip, stream, source );+      if ( error )+      {+        FT_FREE( zip );+        goto Exit;+      }++      stream->descriptor.pointer = zip;+    }++    /*+     *  We use the following trick to try to dramatically improve the+     *  performance while dealing with small files.  If the original stream+     *  size is less than a certain threshold, we try to load the whole font+     *  file into memory.  This saves us from using the 32KB buffer needed+     *  to inflate the file, plus the two 4KB intermediate input/output+     *  buffers used in the `FT_GZipFile' structure.+     */+    {+      FT_ULong  zip_size = ft_gzip_get_uncompressed_size( source );+++      if ( zip_size != 0 && zip_size < 40 * 1024 )+      {+        FT_Byte*  zip_buff;+++        if ( !FT_ALLOC( zip_buff, zip_size ) )+        {+          FT_ULong  count;+++          count = ft_gzip_file_io( zip, 0, zip_buff, zip_size );+          if ( count == zip_size )+          {+            ft_gzip_file_done( zip );+            FT_FREE( zip );++            stream->descriptor.pointer = NULL;++            stream->size  = zip_size;+            stream->pos   = 0;+            stream->base  = zip_buff;+            stream->read  = NULL;+            stream->close = ft_gzip_stream_close;++            goto Exit;+          }++          ft_gzip_file_io( zip, 0, NULL, 0 );+          FT_FREE( zip_buff );+        }+        error = Gzip_Err_Ok;+      }+    }++    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */+    stream->pos   = 0;+    stream->base  = 0;+    stream->read  = ft_gzip_stream_io;+    stream->close = ft_gzip_stream_close;++  Exit:+    return error;+  }++#else  /* !FT_CONFIG_OPTION_USE_ZLIB */++  FT_EXPORT_DEF( FT_Error )+  FT_Stream_OpenGzip( FT_Stream  stream,+                      FT_Stream  source )+  {+    FT_UNUSED( stream );+    FT_UNUSED( source );++    return Gzip_Err_Unimplemented_Feature;+  }++#endif /* !FT_CONFIG_OPTION_USE_ZLIB */+++/* END */
+ src/gzip/infblock.c view
@@ -0,0 +1,387 @@+/* infblock.c -- interpret and process block types to last block+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++#include "zutil.h"+#include "infblock.h"+#include "inftrees.h"+#include "infcodes.h"+#include "infutil.h"+++/* simplify the use of the inflate_huft type with some defines */+#define exop word.what.Exop+#define bits word.what.Bits++/* Table for deflate from PKZIP's appnote.txt. */+local const uInt border[] = { /* Order of the bit length code lengths */+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};++/*+   Notes beyond the 1.93a appnote.txt:++   1. Distance pointers never point before the beginning of the output+      stream.+   2. Distance pointers can point back across blocks, up to 32k away.+   3. There is an implied maximum of 7 bits for the bit length table and+      15 bits for the actual data.+   4. If only one code exists, then it is encoded using one bit.  (Zero+      would be more efficient, but perhaps a little confusing.)  If two+      codes exist, they are coded using one bit each (0 and 1).+   5. There is no way of sending zero distance codes--a dummy must be+      sent if there are none.  (History: a pre 2.0 version of PKZIP would+      store blocks with no distance codes, but this was discovered to be+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow+      zero distance codes, which is sent as one code of zero bits in+      length.+   6. There are up to 286 literal/length codes.  Code 256 represents the+      end-of-block.  Note however that the static length tree defines+      288 codes just to fill out the Huffman codes.  Codes 286 and 287+      cannot be used though, since there is no length base or extra bits+      defined for them.  Similarily, there are up to 30 distance codes.+      However, static trees define 32 codes (all 5 bits) to fill out the+      Huffman codes, but the last two had better not show up in the data.+   7. Unzip can check dynamic Huffman blocks for complete code sets.+      The exception is that a single code would not be complete (see #4).+   8. The five bits following the block type is really the number of+      literal codes sent minus 257.+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits+      (1+6+6).  Therefore, to output three times the length, you output+      three codes (1+1+1), whereas to output four times the same length,+      you only need two codes (1+3).  Hmm.+  10. In the tree reconstruction algorithm, Code = Code + Increment+      only if BitLength(i) is not zero.  (Pretty obvious.)+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)+  12. Note: length code 284 can represent 227-258, but length code 285+      really is 258.  The last length deserves its own, short code+      since it gets used a lot in very redundant files.  The length+      258 is special since 258 - 3 (the min match length) is 255.+  13. The literal/length and distance code bit lengths are read as a+      single stream of lengths.  It is possible (and advantageous) for+      a repeat code (16, 17, or 18) to go across the boundary between+      the two sets of lengths.+ */+++local void inflate_blocks_reset( /* s, z, c) */+inflate_blocks_statef *s,+z_streamp z,+uLongf *c )+{+  if (c != Z_NULL)+    *c = s->check;+  if (s->mode == BTREE || s->mode == DTREE)+    ZFREE(z, s->sub.trees.blens);+  if (s->mode == CODES)+    inflate_codes_free(s->sub.decode.codes, z);+  s->mode = TYPE;+  s->bitk = 0;+  s->bitb = 0;+  s->read = s->write = s->window;+  if (s->checkfn != Z_NULL)+    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);+  Tracev((stderr, "inflate:   blocks reset\n"));+}+++local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */+z_streamp z,+check_func c,+uInt w )+{+  inflate_blocks_statef *s;++  if ((s = (inflate_blocks_statef *)ZALLOC+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)+    return s;+  if ((s->hufts =+       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)+  {+    ZFREE(z, s);+    return Z_NULL;+  }+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)+  {+    ZFREE(z, s->hufts);+    ZFREE(z, s);+    return Z_NULL;+  }+  s->end = s->window + w;+  s->checkfn = c;+  s->mode = TYPE;+  Tracev((stderr, "inflate:   blocks allocated\n"));+  inflate_blocks_reset(s, z, Z_NULL);+  return s;+}+++local int inflate_blocks( /* s, z, r) */+inflate_blocks_statef *s,+z_streamp z,+int r )+{+  uInt t;               /* temporary storage */+  uLong b;              /* bit buffer */+  uInt k;               /* bits in bit buffer */+  Bytef *p;             /* input data pointer */+  uInt n;               /* bytes available there */+  Bytef *q;             /* output window write pointer */+  uInt m;               /* bytes to end of window or read pointer */++  /* copy input/output information to locals (UPDATE macro restores) */+  LOAD++  /* process input based on current state */+  while (1) switch (s->mode)+  {+    case TYPE:+      NEEDBITS(3)+      t = (uInt)b & 7;+      s->last = t & 1;+      switch (t >> 1)+      {+        case 0:                         /* stored */+          Tracev((stderr, "inflate:     stored block%s\n",+                 s->last ? " (last)" : ""));+          DUMPBITS(3)+          t = k & 7;                    /* go to byte boundary */+          DUMPBITS(t)+          s->mode = LENS;               /* get length of stored block */+          break;+        case 1:                         /* fixed */+          Tracev((stderr, "inflate:     fixed codes block%s\n",+                 s->last ? " (last)" : ""));+          {+            uInt bl, bd;+            inflate_huft *tl, *td;++            inflate_trees_fixed(&bl, &bd, (const inflate_huft**)&tl,+                                          (const inflate_huft**)&td, z);+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);+            if (s->sub.decode.codes == Z_NULL)+            {+              r = Z_MEM_ERROR;+              LEAVE+            }+          }+          DUMPBITS(3)+          s->mode = CODES;+          break;+        case 2:                         /* dynamic */+          Tracev((stderr, "inflate:     dynamic codes block%s\n",+                 s->last ? " (last)" : ""));+          DUMPBITS(3)+          s->mode = TABLE;+          break;+        case 3:                         /* illegal */+          DUMPBITS(3)+          s->mode = BAD;+          z->msg = (char*)"invalid block type";+          r = Z_DATA_ERROR;+          LEAVE+      }+      break;+    case LENS:+      NEEDBITS(32)+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))+      {+        s->mode = BAD;+        z->msg = (char*)"invalid stored block lengths";+        r = Z_DATA_ERROR;+        LEAVE+      }+      s->sub.left = (uInt)b & 0xffff;+      b = k = 0;                      /* dump bits */+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);+      break;+    case STORED:+      if (n == 0)+        LEAVE+      NEEDOUT+      t = s->sub.left;+      if (t > n) t = n;+      if (t > m) t = m;+      zmemcpy(q, p, t);+      p += t;  n -= t;+      q += t;  m -= t;+      if ((s->sub.left -= t) != 0)+        break;+      Tracev((stderr, "inflate:       stored end, %lu total out\n",+              z->total_out + (q >= s->read ? q - s->read :+              (s->end - s->read) + (q - s->window))));+      s->mode = s->last ? DRY : TYPE;+      break;+    case TABLE:+      NEEDBITS(14)+      s->sub.trees.table = t = (uInt)b & 0x3fff;+#ifndef PKZIP_BUG_WORKAROUND+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)+      {+        s->mode = BAD;+        z->msg = (char*)"too many length or distance symbols";+        r = Z_DATA_ERROR;+        LEAVE+      }+#endif+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)+      {+        r = Z_MEM_ERROR;+        LEAVE+      }+      DUMPBITS(14)+      s->sub.trees.index = 0;+      Tracev((stderr, "inflate:       table sizes ok\n"));+      s->mode = BTREE;+    case BTREE:+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))+      {+        NEEDBITS(3)+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;+        DUMPBITS(3)+      }+      while (s->sub.trees.index < 19)+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;+      s->sub.trees.bb = 7;+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,+                             &s->sub.trees.tb, s->hufts, z);+      if (t != Z_OK)+      {+        r = t;+        if (r == Z_DATA_ERROR)+        {+          ZFREE(z, s->sub.trees.blens);+          s->mode = BAD;+        }+        LEAVE+      }+      s->sub.trees.index = 0;+      Tracev((stderr, "inflate:       bits tree ok\n"));+      s->mode = DTREE;+    case DTREE:+      while (t = s->sub.trees.table,+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))+      {+        inflate_huft *h;+        uInt i, j, c;++        t = s->sub.trees.bb;+        NEEDBITS(t)+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);+        t = h->bits;+        c = h->base;+        if (c < 16)+        {+          DUMPBITS(t)+          s->sub.trees.blens[s->sub.trees.index++] = c;+        }+        else /* c == 16..18 */+        {+          i = c == 18 ? 7 : c - 14;+          j = c == 18 ? 11 : 3;+          NEEDBITS(t + i)+          DUMPBITS(t)+          j += (uInt)b & inflate_mask[i];+          DUMPBITS(i)+          i = s->sub.trees.index;+          t = s->sub.trees.table;+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||+              (c == 16 && i < 1))+          {+            ZFREE(z, s->sub.trees.blens);+            s->mode = BAD;+            z->msg = (char*)"invalid bit length repeat";+            r = Z_DATA_ERROR;+            LEAVE+          }+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;+          do {+            s->sub.trees.blens[i++] = c;+          } while (--j);+          s->sub.trees.index = i;+        }+      }+      s->sub.trees.tb = Z_NULL;+      {+        uInt bl, bd;+        inflate_huft *tl, *td;+        inflate_codes_statef *c;++        bl = 9;         /* must be <= 9 for lookahead assumptions */+        bd = 6;         /* must be <= 9 for lookahead assumptions */+        t = s->sub.trees.table;+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),+                                  s->sub.trees.blens, &bl, &bd, &tl, &td,+                                  s->hufts, z);+        if (t != Z_OK)+        {+          if (t == (uInt)Z_DATA_ERROR)+          {+            ZFREE(z, s->sub.trees.blens);+            s->mode = BAD;+          }+          r = t;+          LEAVE+        }+        Tracev((stderr, "inflate:       trees ok\n"));+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)+        {+          r = Z_MEM_ERROR;+          LEAVE+        }+        s->sub.decode.codes = c;+      }+      ZFREE(z, s->sub.trees.blens);+      s->mode = CODES;+    case CODES:+      UPDATE+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)+        return inflate_flush(s, z, r);+      r = Z_OK;+      inflate_codes_free(s->sub.decode.codes, z);+      LOAD+      Tracev((stderr, "inflate:       codes end, %lu total out\n",+              z->total_out + (q >= s->read ? q - s->read :+              (s->end - s->read) + (q - s->window))));+      if (!s->last)+      {+        s->mode = TYPE;+        break;+      }+      s->mode = DRY;+    case DRY:+      FLUSH+      if (s->read != s->write)+        LEAVE+      s->mode = DONE;+    case DONE:+      r = Z_STREAM_END;+      LEAVE+    case BAD:+      r = Z_DATA_ERROR;+      LEAVE+    default:+      r = Z_STREAM_ERROR;+      LEAVE+  }+#ifdef NEED_DUMMY_RETURN+  return 0;+#endif+}+++local int inflate_blocks_free( /* s, z) */+inflate_blocks_statef *s,+z_streamp z )+{+  inflate_blocks_reset(s, z, Z_NULL);+  ZFREE(z, s->window);+  ZFREE(z, s->hufts);+  ZFREE(z, s);+  Tracev((stderr, "inflate:   blocks freed\n"));+  return Z_OK;+}++
+ src/gzip/infblock.h view
@@ -0,0 +1,36 @@+/* infblock.h -- header to use infblock.c+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++#ifndef _INFBLOCK_H+#define _INFBLOCK_H++struct inflate_blocks_state;+typedef struct inflate_blocks_state FAR inflate_blocks_statef;++local  inflate_blocks_statef * inflate_blocks_new OF((+    z_streamp z,+    check_func c,               /* check function */+    uInt w));                   /* window size */++local  int inflate_blocks OF((+    inflate_blocks_statef *,+    z_streamp ,+    int));                      /* initial return code */++local  void inflate_blocks_reset OF((+    inflate_blocks_statef *,+    z_streamp ,+    uLongf *));                  /* check value on output */++local  int inflate_blocks_free OF((+    inflate_blocks_statef *,+    z_streamp));++#endif /* _INFBLOCK_H */
+ src/gzip/infcodes.c view
@@ -0,0 +1,250 @@+/* infcodes.c -- process literals and length/distance pairs+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++#include "zutil.h"+#include "inftrees.h"+#include "infblock.h"+#include "infcodes.h"+#include "infutil.h"++/* simplify the use of the inflate_huft type with some defines */+#define exop word.what.Exop+#define bits word.what.Bits++typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */+      START,    /* x: set up for LEN */+      LEN,      /* i: get length/literal/eob next */+      LENEXT,   /* i: getting length extra (have base) */+      DIST,     /* i: get distance next */+      DISTEXT,  /* i: getting distance extra */+      COPY,     /* o: copying bytes in window, waiting for space */+      LIT,      /* o: got literal, waiting for output space */+      WASH,     /* o: got eob, possibly still output waiting */+      END,      /* x: got eob and all data flushed */+      BADCODE}  /* x: got error */+inflate_codes_mode;++/* inflate codes private state */+struct inflate_codes_state {++  /* mode */+  inflate_codes_mode mode;      /* current inflate_codes mode */++  /* mode dependent information */+  uInt len;+  union {+    struct {+      inflate_huft *tree;       /* pointer into tree */+      uInt need;                /* bits needed */+    } code;             /* if LEN or DIST, where in tree */+    uInt lit;           /* if LIT, literal */+    struct {+      uInt get;                 /* bits to get for extra */+      uInt dist;                /* distance back to copy from */+    } copy;             /* if EXT or COPY, where and how much */+  } sub;                /* submode */++  /* mode independent information */+  Byte lbits;           /* ltree bits decoded per branch */+  Byte dbits;           /* dtree bits decoder per branch */+  inflate_huft *ltree;          /* literal/length/eob tree */+  inflate_huft *dtree;          /* distance tree */++};+++local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */+uInt bl, uInt bd,+inflate_huft *tl,+inflate_huft *td, /* need separate declaration for Borland C++ */+z_streamp z )+{+  inflate_codes_statef *c;++  if ((c = (inflate_codes_statef *)+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)+  {+    c->mode = START;+    c->lbits = (Byte)bl;+    c->dbits = (Byte)bd;+    c->ltree = tl;+    c->dtree = td;+    Tracev((stderr, "inflate:       codes new\n"));+  }+  return c;+}+++local int inflate_codes( /* s, z, r) */+inflate_blocks_statef *s,+z_streamp z,+int r )+{+  uInt j;               /* temporary storage */+  inflate_huft *t;      /* temporary pointer */+  uInt e;               /* extra bits or operation */+  uLong b;              /* bit buffer */+  uInt k;               /* bits in bit buffer */+  Bytef *p;             /* input data pointer */+  uInt n;               /* bytes available there */+  Bytef *q;             /* output window write pointer */+  uInt m;               /* bytes to end of window or read pointer */+  Bytef *f;             /* pointer to copy strings from */+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */++  /* copy input/output information to locals (UPDATE macro restores) */+  LOAD++  /* process input and output based on current state */+  while (1) switch (c->mode)+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */+    case START:         /* x: set up for LEN */+#ifndef SLOW+      if (m >= 258 && n >= 10)+      {+        UPDATE+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);+        LOAD+        if (r != Z_OK)+        {+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;+          break;+        }+      }+#endif /* !SLOW */+      c->sub.code.need = c->lbits;+      c->sub.code.tree = c->ltree;+      c->mode = LEN;+    case LEN:           /* i: get length/literal/eob next */+      j = c->sub.code.need;+      NEEDBITS(j)+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);+      DUMPBITS(t->bits)+      e = (uInt)(t->exop);+      if (e == 0)               /* literal */+      {+        c->sub.lit = t->base;+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?+                 "inflate:         literal '%c'\n" :+                 "inflate:         literal 0x%02x\n", t->base));+        c->mode = LIT;+        break;+      }+      if (e & 16)               /* length */+      {+        c->sub.copy.get = e & 15;+        c->len = t->base;+        c->mode = LENEXT;+        break;+      }+      if ((e & 64) == 0)        /* next table */+      {+        c->sub.code.need = e;+        c->sub.code.tree = t + t->base;+        break;+      }+      if (e & 32)               /* end of block */+      {+        Tracevv((stderr, "inflate:         end of block\n"));+        c->mode = WASH;+        break;+      }+      c->mode = BADCODE;        /* invalid code */+      z->msg = (char*)"invalid literal/length code";+      r = Z_DATA_ERROR;+      LEAVE+    case LENEXT:        /* i: getting length extra (have base) */+      j = c->sub.copy.get;+      NEEDBITS(j)+      c->len += (uInt)b & inflate_mask[j];+      DUMPBITS(j)+      c->sub.code.need = c->dbits;+      c->sub.code.tree = c->dtree;+      Tracevv((stderr, "inflate:         length %u\n", c->len));+      c->mode = DIST;+    case DIST:          /* i: get distance next */+      j = c->sub.code.need;+      NEEDBITS(j)+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);+      DUMPBITS(t->bits)+      e = (uInt)(t->exop);+      if (e & 16)               /* distance */+      {+        c->sub.copy.get = e & 15;+        c->sub.copy.dist = t->base;+        c->mode = DISTEXT;+        break;+      }+      if ((e & 64) == 0)        /* next table */+      {+        c->sub.code.need = e;+        c->sub.code.tree = t + t->base;+        break;+      }+      c->mode = BADCODE;        /* invalid code */+      z->msg = (char*)"invalid distance code";+      r = Z_DATA_ERROR;+      LEAVE+    case DISTEXT:       /* i: getting distance extra */+      j = c->sub.copy.get;+      NEEDBITS(j)+      c->sub.copy.dist += (uInt)b & inflate_mask[j];+      DUMPBITS(j)+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));+      c->mode = COPY;+    case COPY:          /* o: copying bytes in window, waiting for space */+      f = q - c->sub.copy.dist;+      while (f < s->window)             /* modulo window size-"while" instead */+        f += s->end - s->window;        /* of "if" handles invalid distances */+      while (c->len)+      {+        NEEDOUT+        OUTBYTE(*f++)+        if (f == s->end)+          f = s->window;+        c->len--;+      }+      c->mode = START;+      break;+    case LIT:           /* o: got literal, waiting for output space */+      NEEDOUT+      OUTBYTE(c->sub.lit)+      c->mode = START;+      break;+    case WASH:          /* o: got eob, possibly more output */+      if (k > 7)        /* return unused byte, if any */+      {+        Assert(k < 16, "inflate_codes grabbed too many bytes")+        k -= 8;+        n++;+        p--;            /* can always return one */+      }+      FLUSH+      if (s->read != s->write)+        LEAVE+      c->mode = END;+    case END:+      r = Z_STREAM_END;+      LEAVE+    case BADCODE:       /* x: got error */+      r = Z_DATA_ERROR;+      LEAVE+    default:+      r = Z_STREAM_ERROR;+      LEAVE+  }+#ifdef NEED_DUMMY_RETURN+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */+#endif+}+++local void inflate_codes_free( /* c, z) */+inflate_codes_statef *c,+z_streamp z )+{+  ZFREE(z, c);+  Tracev((stderr, "inflate:       codes free\n"));+}
+ src/gzip/infcodes.h view
@@ -0,0 +1,31 @@+/* infcodes.h -- header to use infcodes.c+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++#ifndef _INFCODES_H+#define _INFCODES_H++struct inflate_codes_state;+typedef struct inflate_codes_state FAR inflate_codes_statef;++local inflate_codes_statef *inflate_codes_new OF((+    uInt, uInt,+    inflate_huft *, inflate_huft *,+    z_streamp ));++local int inflate_codes OF((+    inflate_blocks_statef *,+    z_streamp ,+    int));++local void inflate_codes_free OF((+    inflate_codes_statef *,+    z_streamp ));++#endif /* _INFCODES_H */
+ src/gzip/inffixed.h view
@@ -0,0 +1,151 @@+/* inffixed.h -- table for decoding fixed codes+ * Generated automatically by the maketree.c program+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++local const uInt fixed_bl = 9;+local const uInt fixed_bd = 5;+local const inflate_huft fixed_tl[] = {+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}+  };+local const inflate_huft fixed_td[] = {+    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},+    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},+    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},+    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},+    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},+    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},+    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},+    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}+  };
+ src/gzip/inflate.c view
@@ -0,0 +1,273 @@+/* inflate.c -- zlib interface to inflate modules+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++#include "zutil.h"+#include "infblock.h"++#define  DONE  INFLATE_DONE+#define  BAD   INFLATE_BAD++typedef enum {+      METHOD,   /* waiting for method byte */+      FLAG,     /* waiting for flag byte */+      DICT4,    /* four dictionary check bytes to go */+      DICT3,    /* three dictionary check bytes to go */+      DICT2,    /* two dictionary check bytes to go */+      DICT1,    /* one dictionary check byte to go */+      DICT0,    /* waiting for inflateSetDictionary */+      BLOCKS,   /* decompressing blocks */+      CHECK4,   /* four check bytes to go */+      CHECK3,   /* three check bytes to go */+      CHECK2,   /* two check bytes to go */+      CHECK1,   /* one check byte to go */+      DONE,     /* finished check, done */+      BAD}      /* got an error--stay here */+inflate_mode;++/* inflate private state */+struct internal_state {++  /* mode */+  inflate_mode  mode;   /* current inflate mode */++  /* mode dependent information */+  union {+    uInt method;        /* if FLAGS, method byte */+    struct {+      uLong was;                /* computed check value */+      uLong need;               /* stream check value */+    } check;            /* if CHECK, check values to compare */+    uInt marker;        /* if BAD, inflateSync's marker bytes count */+  } sub;        /* submode */++  /* mode independent information */+  int  nowrap;          /* flag for no wrapper */+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */+  inflate_blocks_statef+    *blocks;            /* current inflate_blocks state */++};+++ZEXPORT(int) inflateReset( /* z) */+z_streamp z )+{+  if (z == Z_NULL || z->state == Z_NULL)+    return Z_STREAM_ERROR;+  z->total_in = z->total_out = 0;+  z->msg = Z_NULL;+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;+  inflate_blocks_reset(z->state->blocks, z, Z_NULL);+  Tracev((stderr, "inflate: reset\n"));+  return Z_OK;+}+++ZEXPORT(int) inflateEnd( /* z) */+z_streamp z )+{+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)+    return Z_STREAM_ERROR;+  if (z->state->blocks != Z_NULL)+    inflate_blocks_free(z->state->blocks, z);+  ZFREE(z, z->state);+  z->state = Z_NULL;+  Tracev((stderr, "inflate: end\n"));+  return Z_OK;+}+++ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */+z_streamp z,+int w,+const char *version,+int stream_size )+{+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||+      stream_size != sizeof(z_stream))+      return Z_VERSION_ERROR;++  /* initialize state */+  if (z == Z_NULL)+    return Z_STREAM_ERROR;+  z->msg = Z_NULL;+  if (z->zalloc == Z_NULL)+  {+    z->zalloc = zcalloc;+    z->opaque = (voidpf)0;+  }+  if (z->zfree == Z_NULL) z->zfree = zcfree;+  if ((z->state = (struct internal_state FAR *)+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)+    return Z_MEM_ERROR;+  z->state->blocks = Z_NULL;++  /* handle undocumented nowrap option (no zlib header or check) */+  z->state->nowrap = 0;+  if (w < 0)+  {+    w = - w;+    z->state->nowrap = 1;+  }++  /* set window size */+  if (w < 8 || w > 15)+  {+    inflateEnd(z);+    return Z_STREAM_ERROR;+  }+  z->state->wbits = (uInt)w;++  /* create inflate_blocks state */+  if ((z->state->blocks =+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))+      == Z_NULL)+  {+    inflateEnd(z);+    return Z_MEM_ERROR;+  }+  Tracev((stderr, "inflate: allocated\n"));++  /* reset state */+  inflateReset(z);+  return Z_OK;+}++++#undef  NEEDBYTE+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}++#undef  NEXTBYTE+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)+++ZEXPORT(int) inflate( /* z, f) */+z_streamp z,+int f )+{+  int r;+  uInt b;++  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)+    return Z_STREAM_ERROR;+  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;+  r = Z_BUF_ERROR;+  while (1) switch (z->state->mode)+  {+    case METHOD:+      NEEDBYTE+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)+      {+        z->state->mode = BAD;+        z->msg = (char*)"unknown compression method";+        z->state->sub.marker = 5;       /* can't try inflateSync */+        break;+      }+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)+      {+        z->state->mode = BAD;+        z->msg = (char*)"invalid window size";+        z->state->sub.marker = 5;       /* can't try inflateSync */+        break;+      }+      z->state->mode = FLAG;+    case FLAG:+      NEEDBYTE+      b = NEXTBYTE;+      if (((z->state->sub.method << 8) + b) % 31)+      {+        z->state->mode = BAD;+        z->msg = (char*)"incorrect header check";+        z->state->sub.marker = 5;       /* can't try inflateSync */+        break;+      }+      Tracev((stderr, "inflate: zlib header ok\n"));+      if (!(b & PRESET_DICT))+      {+        z->state->mode = BLOCKS;+        break;+      }+      z->state->mode = DICT4;+    case DICT4:+      NEEDBYTE+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;+      z->state->mode = DICT3;+    case DICT3:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;+      z->state->mode = DICT2;+    case DICT2:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;+      z->state->mode = DICT1;+    case DICT1:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE;+      z->adler = z->state->sub.check.need;+      z->state->mode = DICT0;+      return Z_NEED_DICT;+    case DICT0:+      z->state->mode = BAD;+      z->msg = (char*)"need dictionary";+      z->state->sub.marker = 0;       /* can try inflateSync */+      return Z_STREAM_ERROR;+    case BLOCKS:+      r = inflate_blocks(z->state->blocks, z, r);+      if (r == Z_DATA_ERROR)+      {+        z->state->mode = BAD;+        z->state->sub.marker = 0;       /* can try inflateSync */+        break;+      }+      if (r == Z_OK)+        r = f;+      if (r != Z_STREAM_END)+        return r;+      r = f;+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);+      if (z->state->nowrap)+      {+        z->state->mode = DONE;+        break;+      }+      z->state->mode = CHECK4;+    case CHECK4:+      NEEDBYTE+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;+      z->state->mode = CHECK3;+    case CHECK3:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;+      z->state->mode = CHECK2;+    case CHECK2:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;+      z->state->mode = CHECK1;+    case CHECK1:+      NEEDBYTE+      z->state->sub.check.need += (uLong)NEXTBYTE;++      if (z->state->sub.check.was != z->state->sub.check.need)+      {+        z->state->mode = BAD;+        z->msg = (char*)"incorrect data check";+        z->state->sub.marker = 5;       /* can't try inflateSync */+        break;+      }+      Tracev((stderr, "inflate: zlib check ok\n"));+      z->state->mode = DONE;+    case DONE:+      return Z_STREAM_END;+    case BAD:+      return Z_DATA_ERROR;+    default:+      return Z_STREAM_ERROR;+  }+#ifdef NEED_DUMMY_RETURN+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */+#endif+}+
+ src/gzip/inftrees.c view
@@ -0,0 +1,468 @@+/* inftrees.c -- generate Huffman trees for efficient decoding+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++#include "zutil.h"+#include "inftrees.h"++#if !defined(BUILDFIXED) && !defined(STDC)+#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */+#endif+++#if 0+local const char inflate_copyright[] =+   " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";+#endif+/*+  If you use the zlib library in a product, an acknowledgment is welcome+  in the documentation of your product. If for some reason you cannot+  include such an acknowledgment, I would appreciate that you keep this+  copyright string in the executable of your product.+ */++/* simplify the use of the inflate_huft type with some defines */+#define exop word.what.Exop+#define bits word.what.Bits+++local int huft_build OF((+    uIntf *,            /* code lengths in bits */+    uInt,               /* number of codes */+    uInt,               /* number of "simple" codes */+    const uIntf *,      /* list of base values for non-simple codes */+    const uIntf *,      /* list of extra bits for non-simple codes */+    inflate_huft * FAR*,/* result: starting table */+    uIntf *,            /* maximum lookup bits (returns actual) */+    inflate_huft *,     /* space for trees */+    uInt *,             /* hufts used in space */+    uIntf * ));         /* space for values */++/* Tables for deflate from PKZIP's appnote.txt. */+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};+        /* see note #13 above about 258 */+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,+        8193, 12289, 16385, 24577};+local const uInt cpdext[30] = { /* Extra bits for distance codes */+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,+        12, 12, 13, 13};++/*+   Huffman code decoding is performed using a multi-level table lookup.+   The fastest way to decode is to simply build a lookup table whose+   size is determined by the longest code.  However, the time it takes+   to build this table can also be a factor if the data being decoded+   is not very long.  The most common codes are necessarily the+   shortest codes, so those codes dominate the decoding time, and hence+   the speed.  The idea is you can have a shorter table that decodes the+   shorter, more probable codes, and then point to subsidiary tables for+   the longer codes.  The time it costs to decode the longer codes is+   then traded against the time it takes to make longer tables.++   This results of this trade are in the variables lbits and dbits+   below.  lbits is the number of bits the first level table for literal/+   length codes can decode in one step, and dbits is the same thing for+   the distance codes.  Subsequent tables are also less than or equal to+   those sizes.  These values may be adjusted either when all of the+   codes are shorter than that, in which case the longest code length in+   bits is used, or when the shortest code is *longer* than the requested+   table size, in which case the length of the shortest code in bits is+   used.++   There are two different values for the two tables, since they code a+   different number of possibilities each.  The literal/length table+   codes 286 possible values, or in a flat code, a little over eight+   bits.  The distance table codes 30 possible values, or a little less+   than five bits, flat.  The optimum values for speed end up being+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.+   The optimum values may differ though from machine to machine, and+   possibly even between compilers.  Your mileage may vary.+ */+++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */+#define BMAX 15         /* maximum bit length of any code */++local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */+uIntf *b,               /* code lengths in bits (all assumed <= BMAX) */+uInt n,                 /* number of codes (assumed <= 288) */+uInt s,                 /* number of simple-valued codes (0..s-1) */+const uIntf *d,         /* list of base values for non-simple codes */+const uIntf *e,         /* list of extra bits for non-simple codes */+inflate_huft * FAR *t,  /* result: starting table */+uIntf *m,               /* maximum lookup bits, returns actual */+inflate_huft *hp,       /* space for trees */+uInt *hn,               /* hufts used in space */+uIntf *v                /* working area: values in order of bit length */+/* Given a list of code lengths and a maximum table size, make a set of+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR+   if the given code set is incomplete (the tables are still built in this+   case), or Z_DATA_ERROR if the input is invalid. */+)+{++  uInt a;                       /* counter for codes of length k */+  uInt c[BMAX+1];               /* bit length count table */+  uInt f;                       /* i repeats in table every f entries */+  int g;                        /* maximum code length */+  int h;                        /* table level */+  register uInt i;              /* counter, current code */+  register uInt j;              /* counter */+  register int k;               /* number of bits in current code */+  int l;                        /* bits per table (returned in m) */+  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */+  register uIntf *p;            /* pointer into c[], b[], or v[] */+  inflate_huft *q;              /* points to current table */+  struct inflate_huft_s r;      /* table entry for structure assignment */+  inflate_huft *u[BMAX];        /* table stack */+  register int w;               /* bits before this table == (l * h) */+  uInt x[BMAX+1];               /* bit offsets, then code stack */+  uIntf *xp;                    /* pointer into x */+  int y;                        /* number of dummy codes added */+  uInt z;                       /* number of entries in current table */+++  /* Make compiler happy */+  r.base = 0;++  /* Generate counts for each bit length */+  p = c;+#define C0 *p++ = 0;+#define C2 C0 C0 C0 C0+#define C4 C2 C2 C2 C2+  C4                            /* clear c[]--assume BMAX+1 is 16 */+  p = b;  i = n;+  do {+    c[*p++]++;                  /* assume all entries <= BMAX */+  } while (--i);+  if (c[0] == n)                /* null input--all zero length codes */+  {+    *t = (inflate_huft *)Z_NULL;+    *m = 0;+    return Z_OK;+  }+++  /* Find minimum and maximum length, bound *m by those */+  l = *m;+  for (j = 1; j <= BMAX; j++)+    if (c[j])+      break;+  k = j;                        /* minimum code length */+  if ((uInt)l < j)+    l = j;+  for (i = BMAX; i; i--)+    if (c[i])+      break;+  g = i;                        /* maximum code length */+  if ((uInt)l > i)+    l = i;+  *m = l;+++  /* Adjust last length count to fill out codes, if needed */+  for (y = 1 << j; j < i; j++, y <<= 1)+    if ((y -= c[j]) < 0)+      return Z_DATA_ERROR;+  if ((y -= c[i]) < 0)+    return Z_DATA_ERROR;+  c[i] += y;+++  /* Generate starting offsets into the value table for each length */+  x[1] = j = 0;+  p = c + 1;  xp = x + 2;+  while (--i) {                 /* note that i == g from above */+    *xp++ = (j += *p++);+  }+++  /* Make a table of values in order of bit lengths */+  p = b;  i = 0;+  do {+    if ((j = *p++) != 0)+      v[x[j]++] = i;+  } while (++i < n);+  n = x[g];                     /* set n to length of v */+++  /* Generate the Huffman codes and for each, make the table entries */+  x[0] = i = 0;                 /* first Huffman code is zero */+  p = v;                        /* grab values in bit order */+  h = -1;                       /* no tables yet--level -1 */+  w = -l;                       /* bits decoded == (l * h) */+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */+  q = (inflate_huft *)Z_NULL;   /* ditto */+  z = 0;                        /* ditto */++  /* go through the bit lengths (k already is bits in shortest code) */+  for (; k <= g; k++)+  {+    a = c[k];+    while (a--)+    {+      /* here i is the Huffman code of length k bits for value *p */+      /* make tables up to required level */+      while (k > w + l)+      {+        h++;+        w += l;                 /* previous table always l bits */++        /* compute minimum size table less than or equal to l bits */+        z = g - w;+        z = z > (uInt)l ? (uInt)l : z;        /* table size upper limit */+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */+        {                       /* too few codes for k-w bit table */+          f -= a + 1;           /* deduct codes from patterns left */+          xp = c + k;+          if (j < z)+            while (++j < z)     /* try smaller tables up to z bits */+            {+              if ((f <<= 1) <= *++xp)+                break;          /* enough codes to use up j bits */+              f -= *xp;         /* else deduct codes from patterns */+            }+        }+        z = 1 << j;             /* table entries for j-bit table */++        /* allocate new table */+        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */+          return Z_DATA_ERROR;  /* overflow of MANY */+        u[h] = q = hp + *hn;+        *hn += z;++        /* connect to last table, if there is one */+        if (h)+        {+          x[h] = i;             /* save pattern for backing up */+          r.bits = (Byte)l;     /* bits to dump before this table */+          r.exop = (Byte)j;     /* bits in this table */+          j = i >> (w - l);+          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */+          u[h-1][j] = r;        /* connect to last table */+        }+        else+          *t = q;               /* first table is returned result */+      }++      /* set up table entry in r */+      r.bits = (Byte)(k - w);+      if (p >= v + n)+        r.exop = 128 + 64;      /* out of values--invalid code */+      else if (*p < s)+      {+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */+        r.base = *p++;          /* simple code is just the value */+      }+      else+      {+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */+        r.base = d[*p++ - s];+      }++      /* fill code-like entries with r */+      f = 1 << (k - w);+      for (j = i >> w; j < z; j += f)+        q[j] = r;++      /* backwards increment the k-bit code i */+      for (j = 1 << (k - 1); i & j; j >>= 1)+        i ^= j;+      i ^= j;++      /* backup over finished tables */+      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */+      while ((i & mask) != x[h])+      {+        h--;                    /* don't need to update q */+        w -= l;+        mask = (1 << w) - 1;+      }+    }+  }+++  /* Return Z_BUF_ERROR if we were given an incomplete table */+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;+}+++local int inflate_trees_bits( /* c, bb, tb, hp, z) */+uIntf *c,               /* 19 code lengths */+uIntf *bb,              /* bits tree desired/actual depth */+inflate_huft * FAR *tb, /* bits tree result */+inflate_huft *hp,       /* space for trees */+z_streamp z             /* for messages */+)+{+  int r;+  uInt hn = 0;          /* hufts used in space */+  uIntf *v;             /* work area for huft_build */++  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)+    return Z_MEM_ERROR;+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,+                 tb, bb, hp, &hn, v);+  if (r == Z_DATA_ERROR)+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";+  else if (r == Z_BUF_ERROR || *bb == 0)+  {+    z->msg = (char*)"incomplete dynamic bit lengths tree";+    r = Z_DATA_ERROR;+  }+  ZFREE(z, v);+  return r;+}+++local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */+uInt nl,                /* number of literal/length codes */+uInt nd,                /* number of distance codes */+uIntf *c,               /* that many (total) code lengths */+uIntf *bl,              /* literal desired/actual bit depth */+uIntf *bd,              /* distance desired/actual bit depth */+inflate_huft * FAR *tl, /* literal/length tree result */+inflate_huft * FAR *td, /* distance tree result */+inflate_huft *hp,       /* space for trees */+z_streamp z             /* for messages */+)+{+  int r;+  uInt hn = 0;          /* hufts used in space */+  uIntf *v;             /* work area for huft_build */++  /* allocate work area */+  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)+    return Z_MEM_ERROR;++  /* build literal/length tree */+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);+  if (r != Z_OK || *bl == 0)+  {+    if (r == Z_DATA_ERROR)+      z->msg = (char*)"oversubscribed literal/length tree";+    else if (r != Z_MEM_ERROR)+    {+      z->msg = (char*)"incomplete literal/length tree";+      r = Z_DATA_ERROR;+    }+    ZFREE(z, v);+    return r;+  }++  /* build distance tree */+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);+  if (r != Z_OK || (*bd == 0 && nl > 257))+  {+    if (r == Z_DATA_ERROR)+      z->msg = (char*)"oversubscribed distance tree";+    else if (r == Z_BUF_ERROR) {+#if 0+    {+#endif+#ifdef PKZIP_BUG_WORKAROUND+      r = Z_OK;+    }+#else+      z->msg = (char*)"incomplete distance tree";+      r = Z_DATA_ERROR;+    }+    else if (r != Z_MEM_ERROR)+    {+      z->msg = (char*)"empty distance tree with lengths";+      r = Z_DATA_ERROR;+    }+    ZFREE(z, v);+    return r;+#endif+  }++  /* done */+  ZFREE(z, v);+  return Z_OK;+}+++/* build fixed tables only once--keep them here */+#ifdef BUILDFIXED+local int fixed_built = 0;+#define FIXEDH 544      /* number of hufts used by fixed tables */+local inflate_huft fixed_mem[FIXEDH];+local uInt fixed_bl;+local uInt fixed_bd;+local inflate_huft *fixed_tl;+local inflate_huft *fixed_td;+#else+#include "inffixed.h"+#endif+++local int inflate_trees_fixed( /* bl, bd, tl, td, z) */+uIntf *bl,                      /* literal desired/actual bit depth */+uIntf *bd,                      /* distance desired/actual bit depth */+const inflate_huft * FAR *tl,   /* literal/length tree result */+const inflate_huft * FAR *td,   /* distance tree result */+z_streamp z                     /* for memory allocation */+)+{+#ifdef BUILDFIXED+  /* build fixed tables if not already */+  if (!fixed_built)+  {+    int k;              /* temporary variable */+    uInt f = 0;         /* number of hufts used in fixed_mem */+    uIntf *c;           /* length list for huft_build */+    uIntf *v;           /* work area for huft_build */++    /* allocate memory */+    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)+      return Z_MEM_ERROR;+    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)+    {+      ZFREE(z, c);+      return Z_MEM_ERROR;+    }++    /* literal table */+    for (k = 0; k < 144; k++)+      c[k] = 8;+    for (; k < 256; k++)+      c[k] = 9;+    for (; k < 280; k++)+      c[k] = 7;+    for (; k < 288; k++)+      c[k] = 8;+    fixed_bl = 9;+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,+               fixed_mem, &f, v);++    /* distance table */+    for (k = 0; k < 30; k++)+      c[k] = 5;+    fixed_bd = 5;+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,+               fixed_mem, &f, v);++    /* done */+    ZFREE(z, v);+    ZFREE(z, c);+    fixed_built = 1;+  }+#else+  FT_UNUSED(z);+#endif+  *bl = fixed_bl;+  *bd = fixed_bd;+  *tl = fixed_tl;+  *td = fixed_td;+  return Z_OK;+}
+ src/gzip/inftrees.h view
@@ -0,0 +1,63 @@+/* inftrees.h -- header to use inftrees.c+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++/* Huffman code lookup table entry--this entry is four bytes for machines+   that have 16-bit pointers (e.g. PC's in the small or medium model). */++#ifndef _INFTREES_H+#define _INFTREES_H++typedef struct inflate_huft_s FAR inflate_huft;++struct inflate_huft_s {+  union {+    struct {+      Byte Exop;        /* number of extra bits or operation */+      Byte Bits;        /* number of bits in this code or subcode */+    } what;+    uInt pad;           /* pad structure to a power of 2 (4 bytes for */+  } word;               /*  16-bit, 8 bytes for 32-bit int's) */+  uInt base;            /* literal, length base, distance base,+                           or table offset */+};++/* Maximum size of dynamic tree.  The maximum found in a long but non-+   exhaustive search was 1004 huft structures (850 for length/literals+   and 154 for distances, the latter actually the result of an+   exhaustive search).  The actual maximum is not known, but the+   value below is more than safe. */+#define MANY 1440++local  int inflate_trees_bits OF((+    uIntf *,                    /* 19 code lengths */+    uIntf *,                    /* bits tree desired/actual depth */+    inflate_huft * FAR *,       /* bits tree result */+    inflate_huft *,             /* space for trees */+    z_streamp));                /* for messages */++local  int inflate_trees_dynamic OF((+    uInt,                       /* number of literal/length codes */+    uInt,                       /* number of distance codes */+    uIntf *,                    /* that many (total) code lengths */+    uIntf *,                    /* literal desired/actual bit depth */+    uIntf *,                    /* distance desired/actual bit depth */+    inflate_huft * FAR *,       /* literal/length tree result */+    inflate_huft * FAR *,       /* distance tree result */+    inflate_huft *,             /* space for trees */+    z_streamp));                /* for messages */++local  int inflate_trees_fixed OF((+    uIntf *,                    /* literal desired/actual bit depth */+    uIntf *,                    /* distance desired/actual bit depth */+    const inflate_huft * FAR *, /* literal/length tree result */+    const inflate_huft * FAR *, /* distance tree result */+    z_streamp));                /* for memory allocation */++#endif /* _INFTREES_H */
+ src/gzip/infutil.c view
@@ -0,0 +1,86 @@+/* inflate_util.c -- data and routines common to blocks and codes+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++#include "zutil.h"+#include "infblock.h"+#include "inftrees.h"+#include "infcodes.h"+#include "infutil.h"+++/* And'ing with mask[n] masks the lower n bits */+local const uInt inflate_mask[17] = {+    0x0000,+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff+};+++/* copy as much as possible from the sliding window to the output area */+local int inflate_flush( /* s, z, r) */+inflate_blocks_statef *s,+z_streamp z,+int r )+{+  uInt n;+  Bytef *p;+  Bytef *q;++  /* local copies of source and destination pointers */+  p = z->next_out;+  q = s->read;++  /* compute number of bytes to copy as far as end of window */+  n = (uInt)((q <= s->write ? s->write : s->end) - q);+  if (n > z->avail_out) n = z->avail_out;+  if (n && r == Z_BUF_ERROR) r = Z_OK;++  /* update counters */+  z->avail_out -= n;+  z->total_out += n;++  /* update check information */+  if (s->checkfn != Z_NULL)+    z->adler = s->check = (*s->checkfn)(s->check, q, n);++  /* copy as far as end of window */+  zmemcpy(p, q, n);+  p += n;+  q += n;++  /* see if more to copy at beginning of window */+  if (q == s->end)+  {+    /* wrap pointers */+    q = s->window;+    if (s->write == s->end)+      s->write = s->window;++    /* compute bytes to copy */+    n = (uInt)(s->write - q);+    if (n > z->avail_out) n = z->avail_out;+    if (n && r == Z_BUF_ERROR) r = Z_OK;++    /* update counters */+    z->avail_out -= n;+    z->total_out += n;++    /* update check information */+    if (s->checkfn != Z_NULL)+      z->adler = s->check = (*s->checkfn)(s->check, q, n);++    /* copy */+    zmemcpy(p, q, n);+    p += n;+    q += n;+  }++  /* update pointers */+  z->next_out = p;+  s->read = q;++  /* done */+  return r;+}
+ src/gzip/infutil.h view
@@ -0,0 +1,98 @@+/* infutil.h -- types and macros common to blocks and codes+ * Copyright (C) 1995-2002 Mark Adler+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++#ifndef _INFUTIL_H+#define _INFUTIL_H++typedef enum {+      TYPE,     /* get type bits (3, including end bit) */+      LENS,     /* get lengths for stored */+      STORED,   /* processing stored block */+      TABLE,    /* get table lengths */+      BTREE,    /* get bit lengths tree for a dynamic block */+      DTREE,    /* get length, distance trees for a dynamic block */+      CODES,    /* processing fixed or dynamic block */+      DRY,      /* output remaining window bytes */+      DONE,     /* finished last block, done */+      BAD}      /* got a data error--stuck here */+inflate_block_mode;++/* inflate blocks semi-private state */+struct inflate_blocks_state {++  /* mode */+  inflate_block_mode  mode;     /* current inflate_block mode */++  /* mode dependent information */+  union {+    uInt left;          /* if STORED, bytes left to copy */+    struct {+      uInt table;               /* table lengths (14 bits) */+      uInt index;               /* index into blens (or border) */+      uIntf *blens;             /* bit lengths of codes */+      uInt bb;                  /* bit length tree depth */+      inflate_huft *tb;         /* bit length decoding tree */+    } trees;            /* if DTREE, decoding info for trees */+    struct {+      inflate_codes_statef+         *codes;+    } decode;           /* if CODES, current state */+  } sub;                /* submode */+  uInt last;            /* true if this block is the last block */++  /* mode independent information */+  uInt bitk;            /* bits in bit buffer */+  uLong bitb;           /* bit buffer */+  inflate_huft *hufts;  /* single malloc for tree space */+  Bytef *window;        /* sliding window */+  Bytef *end;           /* one byte after sliding window */+  Bytef *read;          /* window read pointer */+  Bytef *write;         /* window write pointer */+  check_func checkfn;   /* check function */+  uLong check;          /* check on output */++};+++/* defines for inflate input/output */+/*   update pointers and return */+#define UPDBITS {s->bitb=b;s->bitk=k;}+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}+#define UPDOUT {s->write=q;}+#define UPDATE {UPDBITS UPDIN UPDOUT}+#define LEAVE {UPDATE return inflate_flush(s,z,r);}+/*   get bytes and bits */+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}+#define NEXTBYTE (n--,*p++)+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}+#define DUMPBITS(j) {b>>=(j);k-=(j);}+/*   output bytes */+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}+/*   load local pointers */+#define LOAD {LOADIN LOADOUT}++/* masks for lower bits (size given to avoid silly warnings with Visual C++) */+#ifndef NO_INFLATE_MASK+local uInt inflate_mask[17];+#endif++/* copy as much as possible from the sliding window to the output area */+local int inflate_flush OF((+    inflate_blocks_statef *,+    z_streamp ,+    int));++#endif
+ src/gzip/zconf.h view
@@ -0,0 +1,284 @@+/* zconf.h -- configuration of the zlib compression library+ * Copyright (C) 1995-2002 Jean-loup Gailly.+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* @(#) $Id$ */++#ifndef _ZCONF_H+#define _ZCONF_H++/*+ * If you *really* need a unique prefix for all types and library functions,+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.+ */+#ifdef Z_PREFIX+#  define deflateInit_         z_deflateInit_+#  define deflate              z_deflate+#  define deflateEnd           z_deflateEnd+#  define inflateInit_         z_inflateInit_+#  define inflate              z_inflate+#  define inflateEnd           z_inflateEnd+#  define deflateInit2_        z_deflateInit2_+#  define deflateSetDictionary z_deflateSetDictionary+#  define deflateCopy          z_deflateCopy+#  define deflateReset         z_deflateReset+#  define deflateParams        z_deflateParams+#  define inflateInit2_        z_inflateInit2_+#  define inflateSetDictionary z_inflateSetDictionary+#  define inflateSync          z_inflateSync+#  define inflateSyncPoint     z_inflateSyncPoint+#  define inflateReset         z_inflateReset+#  define compress             z_compress+#  define compress2            z_compress2+#  define uncompress           z_uncompress+#  define adler32              z_adler32+#  define crc32                z_crc32+#  define get_crc_table        z_get_crc_table++#  define Byte   z_Byte+#  define uInt   z_uInt+#  define uLong  z_uLong+#  define Bytef  z_Bytef+#  define charf  z_charf+#  define intf   z_intf+#  define uIntf  z_uIntf+#  define uLongf z_uLongf+#  define voidpf z_voidpf+#  define voidp  z_voidp+#endif++#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)+#  define WIN32+#endif+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)+#  ifndef __32BIT__+#    define __32BIT__+#  endif+#endif+#if defined(__MSDOS__) && !defined(MSDOS)+#  define MSDOS+#endif++/* WinCE doesn't have errno.h */+#ifdef _WIN32_WCE+#  define NO_ERRNO_H+#endif+++/*+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more+ * than 64k bytes at a time (needed on systems with 16-bit int).+ */+#if defined(MSDOS) && !defined(__32BIT__)+#  define MAXSEG_64K+#endif+#ifdef MSDOS+#  define UNALIGNED_OK+#endif++#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)+#  define STDC+#endif+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)+#  ifndef STDC+#    define STDC+#  endif+#endif++#ifndef STDC+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */+#    define const+#  endif+#endif++/* Some Mac compilers merge all .h files incorrectly: */+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)+#  define NO_DUMMY_DECL+#endif++/* Old Borland C and LCC incorrectly complains about missing returns: */+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)+#  define NEED_DUMMY_RETURN+#endif++#if defined(__LCC__)+#  define  NEED_DUMMY_RETURN+#endif++/* Maximum value for memLevel in deflateInit2 */+#ifndef MAX_MEM_LEVEL+#  ifdef MAXSEG_64K+#    define MAX_MEM_LEVEL 8+#  else+#    define MAX_MEM_LEVEL 9+#  endif+#endif++/* Maximum value for windowBits in deflateInit2 and inflateInit2.+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files+ * created by gzip. (Files created by minigzip can still be extracted by+ * gzip.)+ */+#ifndef MAX_WBITS+#  define MAX_WBITS   15 /* 32K LZ77 window */+#endif++/* The memory requirements for deflate are (in bytes):+            (1 << (windowBits+2)) +  (1 << (memLevel+9))+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)+ plus a few kilobytes for small objects. For example, if you want to reduce+ the default memory requirements from 256K to 128K, compile with+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"+ Of course this will generally degrade compression (there's no free lunch).++   The memory requirements for inflate are (in bytes) 1 << windowBits+ that is, 32K for windowBits=15 (default value) plus a few kilobytes+ for small objects.+*/++                        /* Type declarations */++#ifndef OF /* function prototypes */+#  ifdef STDC+#    define OF(args)  args+#  else+#    define OF(args)  ()+#  endif+#endif++/* The following definitions for FAR are needed only for MSDOS mixed+ * model programming (small or medium model with some far allocations).+ * This was tested only with MSC; for other MSDOS compilers you may have+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,+ * just define FAR to be empty.+ */+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)+   /* MSC small or medium model */+#  define SMALL_MEDIUM+#  ifdef _MSC_VER+#    define FAR _far+#  else+#    define FAR far+#  endif+#endif+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))+#  ifndef __32BIT__+#    define SMALL_MEDIUM+#    define FAR _far+#  endif+#endif++/* Compile with -DZLIB_DLL for Windows DLL support */+#if defined(ZLIB_DLL)+#  if defined(_WINDOWS) || defined(WINDOWS)+#    ifdef FAR+#      undef FAR+#    endif+#    include <windows.h>+#    define ZEXPORT(x)  x WINAPI+#    ifdef WIN32+#      define ZEXPORTVA(x)  x WINAPIV+#    else+#      define ZEXPORTVA(x)  x FAR _cdecl _export+#    endif+#  endif+#  if defined (__BORLANDC__)+#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)+#      include <windows.h>+#      define ZEXPORT(x) x __declspec(dllexport) WINAPI+#      define ZEXPORTRVA(x)  x __declspec(dllexport) WINAPIV+#    else+#      if defined (_Windows) && defined (__DLL__)+#        define ZEXPORT(x) x _export+#        define ZEXPORTVA(x) x _export+#      endif+#    endif+#  endif+#endif+++#ifndef ZEXPORT+#  define ZEXPORT(x)   static x+#endif+#ifndef ZEXPORTVA+#  define ZEXPORTVA(x)   static x+#endif+#ifndef ZEXTERN+#  define ZEXTERN(x) static x+#endif+#ifndef ZEXTERNDEF+#  define ZEXTERNDEF(x)  static x+#endif++#ifndef FAR+#   define FAR+#endif++#if !defined(MACOS) && !defined(TARGET_OS_MAC)+typedef unsigned char  Byte;  /* 8 bits */+#endif+typedef unsigned int   uInt;  /* 16 bits or more */+typedef unsigned long  uLong; /* 32 bits or more */++#ifdef SMALL_MEDIUM+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */+#  define Bytef Byte FAR+#else+   typedef Byte  FAR Bytef;+#endif+typedef char  FAR charf;+typedef int   FAR intf;+typedef uInt  FAR uIntf;+typedef uLong FAR uLongf;++#ifdef STDC+   typedef void FAR *voidpf;+   typedef void     *voidp;+#else+   typedef Byte FAR *voidpf;+   typedef Byte     *voidp;+#endif++#ifdef HAVE_UNISTD_H+#  include <sys/types.h> /* for off_t */+#  include <unistd.h>    /* for SEEK_* and off_t */+#  define z_off_t  off_t+#endif+#ifndef SEEK_SET+#  define SEEK_SET        0       /* Seek from beginning of file.  */+#  define SEEK_CUR        1       /* Seek from current position.  */+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */+#endif+#ifndef z_off_t+#  define  z_off_t long+#endif++/* MVS linker does not support external names larger than 8 bytes */+#if defined(__MVS__)+#   pragma map(deflateInit_,"DEIN")+#   pragma map(deflateInit2_,"DEIN2")+#   pragma map(deflateEnd,"DEEND")+#   pragma map(inflateInit_,"ININ")+#   pragma map(inflateInit2_,"ININ2")+#   pragma map(inflateEnd,"INEND")+#   pragma map(inflateSync,"INSY")+#   pragma map(inflateSetDictionary,"INSEDI")+#   pragma map(inflate_blocks,"INBL")+#   pragma map(inflate_blocks_new,"INBLNE")+#   pragma map(inflate_blocks_free,"INBLFR")+#   pragma map(inflate_blocks_reset,"INBLRE")+#   pragma map(inflate_codes_free,"INCOFR")+#   pragma map(inflate_codes,"INCO")+#   pragma map(inflate_fast,"INFA")+#   pragma map(inflate_flush,"INFLU")+#   pragma map(inflate_mask,"INMA")+#   pragma map(inflate_set_dictionary,"INSEDI2")+#   pragma map(inflate_copyright,"INCOPY")+#   pragma map(inflate_trees_bits,"INTRBI")+#   pragma map(inflate_trees_dynamic,"INTRDY")+#   pragma map(inflate_trees_fixed,"INTRFI")+#   pragma map(inflate_trees_free,"INTRFR")+#endif++#endif /* _ZCONF_H */
+ src/gzip/zlib.h view
@@ -0,0 +1,830 @@+/* zlib.h -- interface of the 'zlib' general purpose compression library+  version 1.1.4, March 11th, 2002++  Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler++  This software is provided 'as-is', without any express or implied+  warranty.  In no event will the authors be held liable for any damages+  arising from the use of this software.++  Permission is granted to anyone to use this software for any purpose,+  including commercial applications, and to alter it and redistribute it+  freely, subject to the following restrictions:++  1. The origin of this software must not be misrepresented; you must not+     claim that you wrote the original software. If you use this software+     in a product, an acknowledgment in the product documentation would be+     appreciated but is not required.+  2. Altered source versions must be plainly marked as such, and must not be+     misrepresented as being the original software.+  3. This notice may not be removed or altered from any source distribution.++  Jean-loup Gailly        Mark Adler+  jloup@gzip.org          madler@alumni.caltech.edu+++  The data format used by the zlib library is described by RFCs (Request for+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).+*/++#ifndef _ZLIB_H+#define _ZLIB_H++#include "zconf.h"++#ifdef __cplusplus+extern "C" {+#endif++#define ZLIB_VERSION "1.1.4"++/*+     The 'zlib' compression library provides in-memory compression and+  decompression functions, including integrity checks of the uncompressed+  data.  This version of the library supports only one compression method+  (deflation) but other algorithms will be added later and will have the same+  stream interface.++     Compression can be done in a single step if the buffers are large+  enough (for example if an input file is mmap'ed), or can be done by+  repeated calls of the compression function.  In the latter case, the+  application must provide more input and/or consume the output+  (providing more output space) before each call.++     The library also supports reading and writing files in gzip (.gz) format+  with an interface similar to that of stdio.++     The library does not install any signal handler. The decoder checks+  the consistency of the compressed data, so the library should never+  crash even in case of corrupted input.+*/++typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));++struct internal_state;++typedef struct z_stream_s {+    Bytef    *next_in;  /* next input byte */+    uInt     avail_in;  /* number of bytes available at next_in */+    uLong    total_in;  /* total nb of input bytes read so far */++    Bytef    *next_out; /* next output byte should be put there */+    uInt     avail_out; /* remaining free space at next_out */+    uLong    total_out; /* total nb of bytes output so far */++    char     *msg;      /* last error message, NULL if no error */+    struct internal_state FAR *state; /* not visible by applications */++    alloc_func zalloc;  /* used to allocate the internal state */+    free_func  zfree;   /* used to free the internal state */+    voidpf     opaque;  /* private data object passed to zalloc and zfree */++    int     data_type;  /* best guess about the data type: ascii or binary */+    uLong   adler;      /* adler32 value of the uncompressed data */+    uLong   reserved;   /* reserved for future use */+} z_stream;++typedef z_stream FAR *z_streamp;++/*+   The application must update next_in and avail_in when avail_in has+   dropped to zero. It must update next_out and avail_out when avail_out+   has dropped to zero. The application must initialize zalloc, zfree and+   opaque before calling the init function. All other fields are set by the+   compression library and must not be updated by the application.++   The opaque value provided by the application will be passed as the first+   parameter for calls of zalloc and zfree. This can be useful for custom+   memory management. The compression library attaches no meaning to the+   opaque value.++   zalloc must return Z_NULL if there is not enough memory for the object.+   If zlib is used in a multi-threaded application, zalloc and zfree must be+   thread safe.++   On 16-bit systems, the functions zalloc and zfree must be able to allocate+   exactly 65536 bytes, but will not be required to allocate more than this+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,+   pointers returned by zalloc for objects of exactly 65536 bytes *must*+   have their offset normalized to zero. The default allocation function+   provided by this library ensures this (see zutil.c). To reduce memory+   requirements and avoid any allocation of 64K objects, at the expense of+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).++   The fields total_in and total_out can be used for statistics or+   progress reports. After compression, total_in holds the total size of+   the uncompressed data and may be saved for use in the decompressor+   (particularly if the decompressor wants to decompress everything in+   a single step).+*/++                        /* constants */++#define Z_NO_FLUSH      0+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */+#define Z_SYNC_FLUSH    2+#define Z_FULL_FLUSH    3+#define Z_FINISH        4+/* Allowed flush values; see deflate() below for details */++#define Z_OK            0+#define Z_STREAM_END    1+#define Z_NEED_DICT     2+#define Z_ERRNO        (-1)+#define Z_STREAM_ERROR (-2)+#define Z_DATA_ERROR   (-3)+#define Z_MEM_ERROR    (-4)+#define Z_BUF_ERROR    (-5)+#define Z_VERSION_ERROR (-6)+/* Return codes for the compression/decompression functions. Negative+ * values are errors, positive values are used for special but normal events.+ */++#define Z_NO_COMPRESSION         0+#define Z_BEST_SPEED             1+#define Z_BEST_COMPRESSION       9+#define Z_DEFAULT_COMPRESSION  (-1)+/* compression levels */++#define Z_FILTERED            1+#define Z_HUFFMAN_ONLY        2+#define Z_DEFAULT_STRATEGY    0+/* compression strategy; see deflateInit2() below for details */++#define Z_BINARY   0+#define Z_ASCII    1+#define Z_UNKNOWN  2+/* Possible values of the data_type field */++#define Z_DEFLATED   8+/* The deflate compression method (the only one supported in this version) */++#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */+++                        /* basic functions */++/* The application can compare zlibVersion and ZLIB_VERSION for consistency.+   If the first character differs, the library code actually used is+   not compatible with the zlib.h header file used by the application.+   This check is automatically made by deflateInit and inflateInit.+ */++/*+ZEXTERN(int)  deflateInit OF((z_streamp strm, int level));++     Initializes the internal stream state for compression. The fields+   zalloc, zfree and opaque must be initialized before by the caller.+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to+   use default allocation functions.++     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:+   1 gives best speed, 9 gives best compression, 0 gives no compression at+   all (the input data is simply copied a block at a time).+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and+   compression (currently equivalent to level 6).++     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible+   with the version assumed by the caller (ZLIB_VERSION).+   msg is set to null if there is no error message.  deflateInit does not+   perform any compression: this will be done by deflate().+*/+++/*+    deflate compresses as much data as possible, and stops when the input+  buffer becomes empty or the output buffer becomes full. It may introduce some+  output latency (reading input without producing any output) except when+  forced to flush.++    The detailed semantics are as follows. deflate performs one or both of the+  following actions:++  - Compress more input starting at next_in and update next_in and avail_in+    accordingly. If not all input can be processed (because there is not+    enough room in the output buffer), next_in and avail_in are updated and+    processing will resume at this point for the next call of deflate().++  - Provide more output starting at next_out and update next_out and avail_out+    accordingly. This action is forced if the parameter flush is non zero.+    Forcing flush frequently degrades the compression ratio, so this parameter+    should be set only when necessary (in interactive applications).+    Some output may be provided even if flush is not set.++  Before the call of deflate(), the application should ensure that at least+  one of the actions is possible, by providing more input and/or consuming+  more output, and updating avail_in or avail_out accordingly; avail_out+  should never be zero before the call. The application can consume the+  compressed output when it wants, for example when the output buffer is full+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK+  and with zero avail_out, it must be called again after making room in the+  output buffer because there might be more output pending.++    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is+  flushed to the output buffer and the output is aligned on a byte boundary, so+  that the decompressor can get all input data available so far. (In particular+  avail_in is zero after the call if enough output space has been provided+  before the call.)  Flushing may degrade compression for some compression+  algorithms and so it should be used only when necessary.++    If flush is set to Z_FULL_FLUSH, all output is flushed as with+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can+  restart from this point if previous compressed data has been damaged or if+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade+  the compression.++    If deflate returns with avail_out == 0, this function must be called again+  with the same value of the flush parameter and more output space (updated+  avail_out), until the flush is complete (deflate returns with non-zero+  avail_out).++    If the parameter flush is set to Z_FINISH, pending input is processed,+  pending output is flushed and deflate returns with Z_STREAM_END if there+  was enough output space; if deflate returns with Z_OK, this function must be+  called again with Z_FINISH and more output space (updated avail_out) but no+  more input data, until it returns with Z_STREAM_END or an error. After+  deflate has returned Z_STREAM_END, the only possible operations on the+  stream are deflateReset or deflateEnd.++    Z_FINISH can be used immediately after deflateInit if all the compression+  is to be done in a single step. In this case, avail_out must be at least+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return+  Z_STREAM_END, then it must be called again as described above.++    deflate() sets strm->adler to the adler32 checksum of all input read+  so far (that is, total_in bytes).++    deflate() may update data_type if it can make a good guess about+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered+  binary. This field is only for information purposes and does not affect+  the compression algorithm in any manner.++    deflate() returns Z_OK if some progress has been made (more input+  processed or more output produced), Z_STREAM_END if all input has been+  consumed and all output has been produced (only when flush is set to+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible+  (for example avail_in or avail_out was zero).+*/+++/*+     All dynamically allocated data structures for this stream are freed.+   This function discards any unprocessed input and does not flush any+   pending output.++     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed+   prematurely (some input or output was discarded). In the error case,+   msg may be set but then points to a static string (which must not be+   deallocated).+*/+++/*+ZEXTERN(int)  inflateInit OF((z_streamp strm));++     Initializes the internal stream state for decompression. The fields+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact+   value depends on the compression method), inflateInit determines the+   compression method from the zlib header and allocates all data structures+   accordingly; otherwise the allocation will be deferred to the first call of+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to+   use default allocation functions.++     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the+   version assumed by the caller.  msg is set to null if there is no error+   message. inflateInit does not perform any decompression apart from reading+   the zlib header if present: this will be done by inflate().  (So next_in and+   avail_in may be modified, but next_out and avail_out are unchanged.)+*/+++ZEXTERN(int) inflate OF((z_streamp strm, int flush));+/*+    inflate decompresses as much data as possible, and stops when the input+  buffer becomes empty or the output buffer becomes full. It may some+  introduce some output latency (reading input without producing any output)+  except when forced to flush.++  The detailed semantics are as follows. inflate performs one or both of the+  following actions:++  - Decompress more input starting at next_in and update next_in and avail_in+    accordingly. If not all input can be processed (because there is not+    enough room in the output buffer), next_in is updated and processing+    will resume at this point for the next call of inflate().++  - Provide more output starting at next_out and update next_out and avail_out+    accordingly.  inflate() provides as much output as possible, until there+    is no more input data or no more space in the output buffer (see below+    about the flush parameter).++  Before the call of inflate(), the application should ensure that at least+  one of the actions is possible, by providing more input and/or consuming+  more output, and updating the next_* and avail_* values accordingly.+  The application can consume the uncompressed output when it wants, for+  example when the output buffer is full (avail_out == 0), or after each+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it+  must be called again after making room in the output buffer because there+  might be more output pending.++    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much+  output as possible to the output buffer. The flushing behavior of inflate is+  not specified for values of the flush parameter other than Z_SYNC_FLUSH+  and Z_FINISH, but the current implementation actually flushes as much output+  as possible anyway.++    inflate() should normally be called until it returns Z_STREAM_END or an+  error. However if all decompression is to be performed in a single step+  (a single call of inflate), the parameter flush should be set to+  Z_FINISH. In this case all pending input is processed and all pending+  output is flushed; avail_out must be large enough to hold all the+  uncompressed data. (The size of the uncompressed data may have been saved+  by the compressor for this purpose.) The next operation on this stream must+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH+  is never required, but can be used to inform inflate that a faster routine+  may be used for the single inflate() call.++     If a preset dictionary is needed at this point (see inflateSetDictionary+  below), inflate sets strm-adler to the adler32 checksum of the+  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise+  it sets strm->adler to the adler32 checksum of all output produced+  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or+  an error code as described below. At the end of the stream, inflate()+  checks that its computed adler32 checksum is equal to that saved by the+  compressor and returns Z_STREAM_END only if the checksum is correct.++    inflate() returns Z_OK if some progress has been made (more input processed+  or more output produced), Z_STREAM_END if the end of the compressed data has+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was+  corrupted (input stream not conforming to the zlib format or incorrect+  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent+  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not+  enough memory, Z_BUF_ERROR if no progress is possible or if there was not+  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR+  case, the application may then call inflateSync to look for a good+  compression block.+*/+++ZEXTERN(int)  inflateEnd OF((z_streamp strm));+/*+     All dynamically allocated data structures for this stream are freed.+   This function discards any unprocessed input and does not flush any+   pending output.++     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state+   was inconsistent. In the error case, msg may be set but then points to a+   static string (which must not be deallocated).+*/++                        /* Advanced functions */++/*+    The following functions are needed only in some special applications.+*/++/*+ZEXTERN(int)  deflateInit2 OF((z_streamp strm,+                                     int  level,+                                     int  method,+                                     int  windowBits,+                                     int  memLevel,+                                     int  strategy));++     This is another version of deflateInit with more compression options. The+   fields next_in, zalloc, zfree and opaque must be initialized before by+   the caller.++     The method parameter is the compression method. It must be Z_DEFLATED in+   this version of the library.++     The windowBits parameter is the base two logarithm of the window size+   (the size of the history buffer).  It should be in the range 8..15 for this+   version of the library. Larger values of this parameter result in better+   compression at the expense of memory usage. The default value is 15 if+   deflateInit is used instead.++     The memLevel parameter specifies how much memory should be allocated+   for the internal compression state. memLevel=1 uses minimum memory but+   is slow and reduces compression ratio; memLevel=9 uses maximum memory+   for optimal speed. The default value is 8. See zconf.h for total memory+   usage as a function of windowBits and memLevel.++     The strategy parameter is used to tune the compression algorithm. Use the+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no+   string match).  Filtered data consists mostly of small values with a+   somewhat random distribution. In this case, the compression algorithm is+   tuned to compress them better. The effect of Z_FILTERED is to force more+   Huffman coding and less string matching; it is somewhat intermediate+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects+   the compression ratio but not the correctness of the compressed output even+   if it is not set appropriately.++      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid+   method). msg is set to null if there is no error message.  deflateInit2 does+   not perform any compression: this will be done by deflate().+*/++/*+     Initializes the compression dictionary from the given byte sequence+   without producing any compressed output. This function must be called+   immediately after deflateInit, deflateInit2 or deflateReset, before any+   call of deflate. The compressor and decompressor must use exactly the same+   dictionary (see inflateSetDictionary).++     The dictionary should consist of strings (byte sequences) that are likely+   to be encountered later in the data to be compressed, with the most commonly+   used strings preferably put towards the end of the dictionary. Using a+   dictionary is most useful when the data to be compressed is short and can be+   predicted with good accuracy; the data can then be compressed better than+   with the default empty dictionary.++     Depending on the size of the compression data structures selected by+   deflateInit or deflateInit2, a part of the dictionary may in effect be+   discarded, for example if the dictionary is larger than the window size in+   deflate or deflate2. Thus the strings most likely to be useful should be+   put at the end of the dictionary, not at the front.++     Upon return of this function, strm->adler is set to the Adler32 value+   of the dictionary; the decompressor may later use this value to determine+   which dictionary has been used by the compressor. (The Adler32 value+   applies to the whole dictionary even if only a subset of the dictionary is+   actually used by the compressor.)++     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a+   parameter is invalid (such as NULL dictionary) or the stream state is+   inconsistent (for example if deflate has already been called for this stream+   or if the compression method is bsort). deflateSetDictionary does not+   perform any compression: this will be done by deflate().+*/++/*+     Sets the destination stream as a complete copy of the source stream.++     This function can be useful when several compression strategies will be+   tried, for example when there are several ways of pre-processing the input+   data with a filter. The streams that will be discarded should then be freed+   by calling deflateEnd.  Note that deflateCopy duplicates the internal+   compression state which can be quite large, so this strategy is slow and+   can consume lots of memory.++     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent+   (such as zalloc being NULL). msg is left unchanged in both source and+   destination.+*/++/*+     This function is equivalent to deflateEnd followed by deflateInit,+   but does not free and reallocate all the internal compression state.+   The stream will keep the same compression level and any other attributes+   that may have been set by deflateInit2.++      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source+   stream state was inconsistent (such as zalloc or state being NULL).+*/++/*+     Dynamically update the compression level and compression strategy.  The+   interpretation of level and strategy is as in deflateInit2.  This can be+   used to switch between compression and straight copy of the input data, or+   to switch to a different kind of input data requiring a different+   strategy. If the compression level is changed, the input available so far+   is compressed with the old level (and may be flushed); the new level will+   take effect only at the next call of deflate().++     Before the call of deflateParams, the stream state must be set as for+   a call of deflate(), since the currently available input may have to+   be compressed and flushed. In particular, strm->avail_out must be non-zero.++     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR+   if strm->avail_out was zero.+*/++/*+ZEXTERN(int)  inflateInit2 OF((z_streamp strm,+                                     int  windowBits));++     This is another version of inflateInit with an extra parameter. The+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized+   before by the caller.++     The windowBits parameter is the base two logarithm of the maximum window+   size (the size of the history buffer).  It should be in the range 8..15 for+   this version of the library. The default value is 15 if inflateInit is used+   instead. If a compressed stream with a larger window size is given as+   input, inflate() will return with the error code Z_DATA_ERROR instead of+   trying to allocate a larger window.++      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative+   memLevel). msg is set to null if there is no error message.  inflateInit2+   does not perform any decompression apart from reading the zlib header if+   present: this will be done by inflate(). (So next_in and avail_in may be+   modified, but next_out and avail_out are unchanged.)+*/++/*+     Initializes the decompression dictionary from the given uncompressed byte+   sequence. This function must be called immediately after a call of inflate+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor+   can be determined from the Adler32 value returned by this call of+   inflate. The compressor and decompressor must use exactly the same+   dictionary (see deflateSetDictionary).++     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a+   parameter is invalid (such as NULL dictionary) or the stream state is+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the+   expected one (incorrect Adler32 value). inflateSetDictionary does not+   perform any decompression: this will be done by subsequent calls of+   inflate().+*/++/*+    Skips invalid compressed data until a full flush point (see above the+  description of deflate with Z_FULL_FLUSH) can be found, or until all+  available input is skipped. No output is provided.++    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success+  case, the application may save the current current value of total_in which+  indicates where valid compressed data was found. In the error case, the+  application may repeatedly call inflateSync, providing more input each time,+  until success or end of the input data.+*/++ZEXTERN(int)  inflateReset OF((z_streamp strm));+/*+     This function is equivalent to inflateEnd followed by inflateInit,+   but does not free and reallocate all the internal decompression state.+   The stream will keep attributes that may have been set by inflateInit2.++      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source+   stream state was inconsistent (such as zalloc or state being NULL).+*/+++                        /* utility functions */++/*+     The following utility functions are implemented on top of the+   basic stream-oriented functions. To simplify the interface, some+   default options are assumed (compression level and memory usage,+   standard memory allocation functions). The source code of these+   utility functions can easily be modified if you need special options.+*/++/*+     Compresses the source buffer into the destination buffer.  sourceLen is+   the byte length of the source buffer. Upon entry, destLen is the total+   size of the destination buffer, which must be at least 0.1% larger than+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the+   compressed buffer.+     This function can be used to compress a whole file at once if the+   input file is mmap'ed.+     compress returns Z_OK if success, Z_MEM_ERROR if there was not+   enough memory, Z_BUF_ERROR if there was not enough room in the output+   buffer.+*/++/*+     Compresses the source buffer into the destination buffer. The level+   parameter has the same meaning as in deflateInit.  sourceLen is the byte+   length of the source buffer. Upon entry, destLen is the total size of the+   destination buffer, which must be at least 0.1% larger than sourceLen plus+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.++     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,+   Z_STREAM_ERROR if the level parameter is invalid.+*/++/*+     Decompresses the source buffer into the destination buffer.  sourceLen is+   the byte length of the source buffer. Upon entry, destLen is the total+   size of the destination buffer, which must be large enough to hold the+   entire uncompressed data. (The size of the uncompressed data must have+   been saved previously by the compressor and transmitted to the decompressor+   by some mechanism outside the scope of this compression library.)+   Upon exit, destLen is the actual size of the compressed buffer.+     This function can be used to decompress a whole file at once if the+   input file is mmap'ed.++     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not+   enough memory, Z_BUF_ERROR if there was not enough room in the output+   buffer, or Z_DATA_ERROR if the input data was corrupted.+*/+++/*+     Opens a gzip (.gz) file for reading or writing. The mode parameter+   is as in fopen ("rb" or "wb") but can also include a compression level+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for+   Huffman only compression as in "wb1h". (See the description+   of deflateInit2 for more information about the strategy parameter.)++     gzopen can be used to read a file which is not in gzip format; in this+   case gzread will directly read from the file without decompression.++     gzopen returns NULL if the file could not be opened or if there was+   insufficient memory to allocate the (de)compression state; errno+   can be checked to distinguish the two cases (if errno is zero, the+   zlib error is Z_MEM_ERROR).  */++/*+     gzdopen() associates a gzFile with the file descriptor fd.  File+   descriptors are obtained from calls like open, dup, creat, pipe or+   fileno (in the file has been previously opened with fopen).+   The mode parameter is as in gzopen.+     The next call of gzclose on the returned gzFile will also close the+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).+     gzdopen returns NULL if there was insufficient memory to allocate+   the (de)compression state.+*/++/*+     Dynamically update the compression level or strategy. See the description+   of deflateInit2 for the meaning of these parameters.+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not+   opened for writing.+*/++/*+     Reads the given number of uncompressed bytes from the compressed file.+   If the input file was not in gzip format, gzread copies the given number+   of bytes into the buffer.+     gzread returns the number of uncompressed bytes actually read (0 for+   end of file, -1 for error). */++/*+     Writes the given number of uncompressed bytes into the compressed file.+   gzwrite returns the number of uncompressed bytes actually written+   (0 in case of error).+*/++/*+     Converts, formats, and writes the args to the compressed file under+   control of the format string, as in fprintf. gzprintf returns the number of+   uncompressed bytes actually written (0 in case of error).+*/++/*+      Writes the given null-terminated string to the compressed file, excluding+   the terminating null character.+      gzputs returns the number of characters written, or -1 in case of error.+*/++/*+      Reads bytes from the compressed file until len-1 characters are read, or+   a newline character is read and transferred to buf, or an end-of-file+   condition is encountered.  The string is then terminated with a null+   character.+      gzgets returns buf, or Z_NULL in case of error.+*/++/*+      Writes c, converted to an unsigned char, into the compressed file.+   gzputc returns the value that was written, or -1 in case of error.+*/++/*+      Reads one byte from the compressed file. gzgetc returns this byte+   or -1 in case of end of file or error.+*/++/*+     Flushes all pending output into the compressed file. The parameter+   flush is as in the deflate() function. The return value is the zlib+   error number (see function gzerror below). gzflush returns Z_OK if+   the flush parameter is Z_FINISH and all output could be flushed.+     gzflush should be called only when strictly necessary because it can+   degrade compression.+*/++/*+      Sets the starting position for the next gzread or gzwrite on the+   given compressed file. The offset represents a number of bytes in the+   uncompressed data stream. The whence parameter is defined as in lseek(2);+   the value SEEK_END is not supported.+     If the file is opened for reading, this function is emulated but can be+   extremely slow. If the file is opened for writing, only forward seeks are+   supported; gzseek then compresses a sequence of zeroes up to the new+   starting position.++      gzseek returns the resulting offset location as measured in bytes from+   the beginning of the uncompressed stream, or -1 in case of error, in+   particular if the file is opened for writing and the new starting position+   would be before the current position.+*/++/*+     Rewinds the given file. This function is supported only for reading.++   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)+*/++/*+     Returns the starting position for the next gzread or gzwrite on the+   given compressed file. This position represents a number of bytes in the+   uncompressed data stream.++   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)+*/++/*+     Returns 1 when EOF has previously been detected reading the given+   input stream, otherwise zero.+*/++/*+     Flushes all pending output if necessary, closes the compressed file+   and deallocates all the (de)compression state. The return value is the zlib+   error number (see function gzerror below).+*/++/*+     Returns the error message for the last error which occurred on the+   given compressed file. errnum is set to zlib error number. If an+   error occurred in the file system and not in the compression library,+   errnum is set to Z_ERRNO and the application may consult errno+   to get the exact error code.+*/++                        /* checksum functions */++/*+     These functions are not related to compression but are exported+   anyway because they might be useful in applications using the+   compression library.+*/++ZEXTERN(uLong)  adler32 OF((uLong adler, const Bytef *buf, uInt len));++/*+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and+   return the updated checksum. If buf is NULL, this function returns+   the required initial value for the checksum.+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed+   much faster. Usage example:++     uLong adler = adler32(0L, Z_NULL, 0);++     while (read_buffer(buffer, length) != EOF) {+       adler = adler32(adler, buffer, length);+     }+     if (adler != original_adler) error();+*/++/*+     Update a running crc with the bytes buf[0..len-1] and return the updated+   crc. If buf is NULL, this function returns the required initial value+   for the crc. Pre- and post-conditioning (one's complement) is performed+   within this function so it shouldn't be done by the application.+   Usage example:++     uLong crc = crc32(0L, Z_NULL, 0);++     while (read_buffer(buffer, length) != EOF) {+       crc = crc32(crc, buffer, length);+     }+     if (crc != original_crc) error();+*/+++                        /* various hacks, don't look :) */++/* deflateInit and inflateInit are macros to allow checking the zlib version+ * and the compiler's view of z_stream:+ */+ZEXTERN(int)  inflateInit2_ OF((z_streamp strm, int  windowBits,+                                      const char *version, int stream_size));+#define deflateInit(strm, level) \+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))+#define inflateInit(strm) \+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))+#define inflateInit2(strm, windowBits) \+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))+++#ifdef __cplusplus+}+#endif++#endif /* _ZLIB_H */
+ src/gzip/zutil.c view
@@ -0,0 +1,181 @@+/* zutil.c -- target dependent utility functions for the compression library+ * Copyright (C) 1995-2002 Jean-loup Gailly.+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* @(#) $Id$ */++#include "zutil.h"++#ifndef STDC+extern void exit OF((int));+#endif+++#ifndef HAVE_MEMCPY++void zmemcpy(dest, source, len)+    Bytef* dest;+    const Bytef* source;+    uInt  len;+{+    if (len == 0) return;+    do {+        *dest++ = *source++; /* ??? to be unrolled */+    } while (--len != 0);+}++int zmemcmp(s1, s2, len)+    const Bytef* s1;+    const Bytef* s2;+    uInt  len;+{+    uInt j;++    for (j = 0; j < len; j++) {+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;+    }+    return 0;+}++void zmemzero(dest, len)+    Bytef* dest;+    uInt  len;+{+    if (len == 0) return;+    do {+        *dest++ = 0;  /* ??? to be unrolled */+    } while (--len != 0);+}+#endif++#if defined( MSDOS ) && defined( __TURBOC__ ) && !defined( MY_ZCALLOC )+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)+/* Small and medium model in Turbo C are for now limited to near allocation+ * with reduced MAX_WBITS and MAX_MEM_LEVEL+ */+#  define MY_ZCALLOC++/* Turbo C malloc() does not allow dynamic allocation of 64K bytes+ * and farmalloc(64K) returns a pointer with an offset of 8, so we+ * must fix the pointer. Warning: the pointer must be put back to its+ * original form in order to free it, use zcfree().+ */++#define MAX_PTR 10+/* 10*64K = 640K */++local int next_ptr = 0;++typedef struct ptr_table_s {+    voidpf org_ptr;+    voidpf new_ptr;+} ptr_table;++local ptr_table table[MAX_PTR];+/* This table is used to remember the original form of pointers+ * to large buffers (64K). Such pointers are normalized with a zero offset.+ * Since MSDOS is not a preemptive multitasking OS, this table is not+ * protected from concurrent access. This hack doesn't work anyway on+ * a protected system like OS/2. Use Microsoft C instead.+ */++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)+{+    voidpf buf = opaque; /* just to make some compilers happy */+    ulg bsize = (ulg)items*size;++    /* If we allocate less than 65520 bytes, we assume that farmalloc+     * will return a usable pointer which doesn't have to be normalized.+     */+    if (bsize < 65520L) {+        buf = farmalloc(bsize);+        if (*(ush*)&buf != 0) return buf;+    } else {+        buf = farmalloc(bsize + 16L);+    }+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;+    table[next_ptr].org_ptr = buf;++    /* Normalize the pointer to seg:0 */+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;+    *(ush*)&buf = 0;+    table[next_ptr++].new_ptr = buf;+    return buf;+}++void  zcfree (voidpf opaque, voidpf ptr)+{+    int n;+    if (*(ush*)&ptr != 0) { /* object < 64K */+        farfree(ptr);+        return;+    }+    /* Find the original pointer */+    for (n = 0; n < next_ptr; n++) {+        if (ptr != table[n].new_ptr) continue;++        farfree(table[n].org_ptr);+        while (++n < next_ptr) {+            table[n-1] = table[n];+        }+        next_ptr--;+        return;+    }+    ptr = opaque; /* just to make some compilers happy */+    Assert(0, "zcfree: ptr not found");+}+#endif+#endif /* MSDOS && __TURBOC__ */+++#if defined(M_I86) && !defined(__32BIT__) && !defined( MY_ZCALLOC )+/* Microsoft C in 16-bit mode */++#  define MY_ZCALLOC++#if (!defined(_MSC_VER) || (_MSC_VER <= 600))+#  define _halloc  halloc+#  define _hfree   hfree+#endif++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)+{+    if (opaque) opaque = 0; /* to make compiler happy */+    return _halloc((long)items, size);+}++void  zcfree (voidpf opaque, voidpf ptr)+{+    if (opaque) opaque = 0; /* to make compiler happy */+    _hfree(ptr);+}++#endif /* MSC */+++#ifndef MY_ZCALLOC /* Any system without a special alloc function */++#ifndef STDC+extern voidp  ft_scalloc OF((uInt items, uInt size));+extern void   ft_sfree   OF((voidpf ptr));+#endif++voidpf zcalloc (opaque, items, size)+    voidpf opaque;+    unsigned items;+    unsigned size;+{+    if (opaque) items += size - size; /* make compiler happy */+    return (voidpf)ft_scalloc(items, size);+}++void  zcfree (opaque, ptr)+    voidpf opaque;+    voidpf ptr;+{+    ft_sfree(ptr);+    if (opaque) return; /* make compiler happy */+}++#endif /* MY_ZCALLOC */
+ src/gzip/zutil.h view
@@ -0,0 +1,215 @@+/* zutil.h -- internal interface and configuration of the compression library+ * Copyright (C) 1995-2002 Jean-loup Gailly.+ * For conditions of distribution and use, see copyright notice in zlib.h+ */++/* WARNING: this file should *not* be used by applications. It is+   part of the implementation of the compression library and is+   subject to change. Applications should only use zlib.h.+ */++/* @(#) $Id$ */++#ifndef _Z_UTIL_H+#define _Z_UTIL_H++#include "zlib.h"++#ifdef STDC+#  include <stddef.h>+#  include <string.h>+#  include <stdlib.h>+#endif+#ifdef NO_ERRNO_H+    extern int errno;+#else+#   include <errno.h>+#endif++#ifndef local+#  define local static+#endif+/* compile with -Dlocal if your debugger can't find static symbols */++typedef unsigned char  uch;+typedef uch FAR uchf;+typedef unsigned short ush;+typedef ush FAR ushf;+typedef unsigned long  ulg;+++#define ERR_RETURN(strm,err) \+  return (strm->msg = (char*)ERR_MSG(err), (err))+/* To be used only when the state is known to be valid */++        /* common constants */++#ifndef DEF_WBITS+#  define DEF_WBITS MAX_WBITS+#endif+/* default windowBits for decompression. MAX_WBITS is for compression only */++#if MAX_MEM_LEVEL >= 8+#  define DEF_MEM_LEVEL 8+#else+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL+#endif+/* default memLevel */++#define STORED_BLOCK 0+#define STATIC_TREES 1+#define DYN_TREES    2+/* The three kinds of block type */++#define MIN_MATCH  3+#define MAX_MATCH  258+/* The minimum and maximum match lengths */++#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */++        /* target dependencies */++#ifdef MSDOS+#  define OS_CODE  0x00+#  if defined(__TURBOC__) || defined(__BORLANDC__)+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))+       /* Allow compilation with ANSI keywords only enabled */+       void _Cdecl farfree( void *block );+       void *_Cdecl farmalloc( unsigned long nbytes );+#    else+#     include <alloc.h>+#    endif+#  else /* MSC or DJGPP */+#  endif+#endif++#ifdef OS2+#  define OS_CODE  0x06+#endif++#ifdef WIN32 /* Window 95 & Windows NT */+#  define OS_CODE  0x0b+#endif++#if defined(VAXC) || defined(VMS)+#  define OS_CODE  0x02+#  define F_OPEN(name, mode) \+     ft_fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")+#endif++#ifdef AMIGA+#  define OS_CODE  0x01+#endif++#if defined(ATARI) || defined(atarist)+#  define OS_CODE  0x05+#endif++#if defined(MACOS) || defined(TARGET_OS_MAC)+#  define OS_CODE  0x07+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os+#    include <unix.h> /* for fdopen */+#  else+#    ifndef fdopen+#      define fdopen(fd,mode) NULL /* No fdopen() */+#    endif+#  endif+#endif++#ifdef __50SERIES /* Prime/PRIMOS */+#  define OS_CODE  0x0F+#endif++#ifdef TOPS20+#  define OS_CODE  0x0a+#endif++#if defined(_BEOS_) || defined(RISCOS)+#  define fdopen(fd,mode) NULL /* No fdopen() */+#endif++#if (defined(_MSC_VER) && (_MSC_VER > 600))+#  define fdopen(fd,type)  _fdopen(fd,type)+#endif+++        /* Common defaults */++#ifndef OS_CODE+#  define OS_CODE  0x03  /* assume Unix */+#endif++#ifndef F_OPEN+#  define F_OPEN(name, mode) ft_fopen((name), (mode))+#endif++         /* functions */++#ifdef HAVE_STRERROR+   extern char *strerror OF((int));+#  define zstrerror(errnum) strerror(errnum)+#else+#  define zstrerror(errnum) ""+#endif++#if defined(pyr)+#  define NO_MEMCPY+#endif+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)+ /* Use our own functions for small and medium model with MSC <= 5.0.+  * You may have to use the same strategy for Borland C (untested).+  * The __SC__ check is for Symantec.+  */+#  define NO_MEMCPY+#endif+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)+#  define HAVE_MEMCPY+#endif+#ifdef HAVE_MEMCPY+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */+#    define zmemcpy _fmemcpy+#    define zmemcmp _fmemcmp+#    define zmemzero(dest, len) _fmemset(dest, 0, len)+#  else+#    define zmemcpy ft_memcpy+#    define zmemcmp ft_memcmp+#    define zmemzero(dest, len) ft_memset(dest, 0, len)+#  endif+#else+   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));+   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));+   extern void zmemzero OF((Bytef* dest, uInt len));+#endif++/* Diagnostic functions */+#ifdef DEBUG+#  include <stdio.h>+   extern int z_verbose;+   extern void z_error    OF((char *m));+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}+#else+#  define Assert(cond,msg)+#  define Trace(x)+#  define Tracev(x)+#  define Tracevv(x)+#  define Tracec(c,x)+#  define Tracecv(c,x)+#endif+++typedef uLong (*check_func) OF((uLong check, const Bytef *buf,+                                uInt len));+local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));+local void   zcfree  OF((voidpf opaque, voidpf ptr));++#define ZALLOC(strm, items, size) \+           (*((strm)->zalloc))((strm)->opaque, (items), (size))+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}++#endif /* _Z_UTIL_H */
+ src/lzw/ftlzw.c view
@@ -0,0 +1,412 @@+/***************************************************************************/+/*                                                                         */+/*  ftlzw.c                                                                */+/*                                                                         */+/*    FreeType support for .Z compressed files.                            */+/*                                                                         */+/*  This optional component relies on NetBSD's zopen().  It should mainly  */+/*  be used to parse compressed PCF fonts, as found with many X11 server   */+/*  distributions.                                                         */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2009, 2010 by                              */+/*  Albert Chin-A-Young.                                                   */+/*                                                                         */+/*  Based on code in src/gzip/ftgzip.c, Copyright 2004 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_DEBUG_H+#include FT_LZW_H+#include FT_CONFIG_STANDARD_LIBRARY_H+++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  LZW_Err_+#define FT_ERR_BASE    FT_Mod_Err_LZW++#include FT_ERRORS_H+++#ifdef FT_CONFIG_OPTION_USE_LZW++#ifdef FT_CONFIG_OPTION_PIC+#error "lzw code does not support PIC yet"+#endif ++#include "ftzopen.h"+++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****                  M E M O R Y   M A N A G E M E N T              *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****                   F I L E   D E S C R I P T O R                 *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++#define FT_LZW_BUFFER_SIZE  4096++  typedef struct  FT_LZWFileRec_+  {+    FT_Stream       source;         /* parent/source stream        */+    FT_Stream       stream;         /* embedding stream            */+    FT_Memory       memory;         /* memory allocator            */+    FT_LzwStateRec  lzw;            /* lzw decompressor state      */++    FT_Byte         buffer[FT_LZW_BUFFER_SIZE]; /* output buffer      */+    FT_ULong        pos;                        /* position in output */+    FT_Byte*        cursor;+    FT_Byte*        limit;++  } FT_LZWFileRec, *FT_LZWFile;+++  /* check and skip .Z header */+  static FT_Error+  ft_lzw_check_header( FT_Stream  stream )+  {+    FT_Error  error;+    FT_Byte   head[2];+++    if ( FT_STREAM_SEEK( 0 )       ||+         FT_STREAM_READ( head, 2 ) )+      goto Exit;++    /* head[0] && head[1] are the magic numbers */+    if ( head[0] != 0x1f ||+         head[1] != 0x9d )+      error = LZW_Err_Invalid_File_Format;++  Exit:+    return error;+  }+++  static FT_Error+  ft_lzw_file_init( FT_LZWFile  zip,+                    FT_Stream   stream,+                    FT_Stream   source )+  {+    FT_LzwState  lzw   = &zip->lzw;+    FT_Error     error = LZW_Err_Ok;+++    zip->stream = stream;+    zip->source = source;+    zip->memory = stream->memory;++    zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;+    zip->cursor = zip->limit;+    zip->pos    = 0;++    /* check and skip .Z header */+    error = ft_lzw_check_header( source );+    if ( error )+      goto Exit;++    /* initialize internal lzw variable */+    ft_lzwstate_init( lzw, source );++  Exit:+    return error;+  }+++  static void+  ft_lzw_file_done( FT_LZWFile  zip )+  {+    /* clear the rest */+    ft_lzwstate_done( &zip->lzw );++    zip->memory = NULL;+    zip->source = NULL;+    zip->stream = NULL;+  }+++  static FT_Error+  ft_lzw_file_reset( FT_LZWFile  zip )+  {+    FT_Stream  stream = zip->source;+    FT_Error   error;+++    if ( !FT_STREAM_SEEK( 0 ) )+    {+      ft_lzwstate_reset( &zip->lzw );++      zip->limit  = zip->buffer + FT_LZW_BUFFER_SIZE;+      zip->cursor = zip->limit;+      zip->pos    = 0;+    }++    return error;+  }+++  static FT_Error+  ft_lzw_file_fill_output( FT_LZWFile  zip )+  {+    FT_LzwState  lzw = &zip->lzw;+    FT_ULong     count;+    FT_Error     error = LZW_Err_Ok;+++    zip->cursor = zip->buffer;++    count = ft_lzwstate_io( lzw, zip->buffer, FT_LZW_BUFFER_SIZE );++    zip->limit = zip->cursor + count;++    if ( count == 0 )+      error = LZW_Err_Invalid_Stream_Operation;++    return error;+  }+++  /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */+  static FT_Error+  ft_lzw_file_skip_output( FT_LZWFile  zip,+                           FT_ULong    count )+  {+    FT_Error  error = LZW_Err_Ok;+++    /* first, we skip what we can from the output buffer */+    {+      FT_ULong  delta = (FT_ULong)( zip->limit - zip->cursor );+++      if ( delta >= count )+        delta = count;++      zip->cursor += delta;+      zip->pos    += delta;++      count -= delta;+    }++    /* next, we skip as many bytes remaining as possible */+    while ( count > 0 )+    {+      FT_ULong  delta = FT_LZW_BUFFER_SIZE;+      FT_ULong  numread;+++      if ( delta > count )+        delta = count;++      numread = ft_lzwstate_io( &zip->lzw, NULL, delta );+      if ( numread < delta )+      {+        /* not enough bytes */+        error = LZW_Err_Invalid_Stream_Operation;+        break;+      }++      zip->pos += delta;+      count    -= delta;+    }++    return error;+  }+++  static FT_ULong+  ft_lzw_file_io( FT_LZWFile  zip,+                  FT_ULong    pos,+                  FT_Byte*    buffer,+                  FT_ULong    count )+  {+    FT_ULong  result = 0;+    FT_Error  error;+++    /* seeking backwards. */+    if ( pos < zip->pos )+    {+      /* If the new position is within the output buffer, simply       */+      /* decrement pointers, otherwise we reset the stream completely! */+      if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) )+      {+        zip->cursor -= zip->pos - pos;+        zip->pos     = pos;+      }+      else+      {+        error = ft_lzw_file_reset( zip );+        if ( error )+          goto Exit;+      }+    }++    /* skip unwanted bytes */+    if ( pos > zip->pos )+    {+      error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) );+      if ( error )+        goto Exit;+    }++    if ( count == 0 )+      goto Exit;++    /* now read the data */+    for (;;)+    {+      FT_ULong  delta;+++      delta = (FT_ULong)( zip->limit - zip->cursor );+      if ( delta >= count )+        delta = count;++      FT_MEM_COPY( buffer + result, zip->cursor, delta );+      result      += delta;+      zip->cursor += delta;+      zip->pos    += delta;++      count -= delta;+      if ( count == 0 )+        break;++      error = ft_lzw_file_fill_output( zip );+      if ( error )+        break;+    }++  Exit:+    return result;+  }+++/***************************************************************************/+/***************************************************************************/+/*****                                                                 *****/+/*****            L Z W   E M B E D D I N G   S T R E A M              *****/+/*****                                                                 *****/+/***************************************************************************/+/***************************************************************************/++  static void+  ft_lzw_stream_close( FT_Stream  stream )+  {+    FT_LZWFile  zip    = (FT_LZWFile)stream->descriptor.pointer;+    FT_Memory   memory = stream->memory;+++    if ( zip )+    {+      /* finalize lzw file descriptor */+      ft_lzw_file_done( zip );++      FT_FREE( zip );++      stream->descriptor.pointer = NULL;+    }+  }+++  static FT_ULong+  ft_lzw_stream_io( FT_Stream  stream,+                    FT_ULong   pos,+                    FT_Byte*   buffer,+                    FT_ULong   count )+  {+    FT_LZWFile  zip = (FT_LZWFile)stream->descriptor.pointer;+++    return ft_lzw_file_io( zip, pos, buffer, count );+  }+++  FT_EXPORT_DEF( FT_Error )+  FT_Stream_OpenLZW( FT_Stream  stream,+                     FT_Stream  source )+  {+    FT_Error    error;+    FT_Memory   memory = source->memory;+    FT_LZWFile  zip;+++    /*+     *  Check the header right now; this prevents allocation of a huge+     *  LZWFile object (400 KByte of heap memory) if not necessary.+     *+     *  Did I mention that you should never use .Z compressed font+     *  files?+     */+    error = ft_lzw_check_header( source );+    if ( error )+      goto Exit;++    FT_ZERO( stream );+    stream->memory = memory;++    if ( !FT_NEW( zip ) )+    {+      error = ft_lzw_file_init( zip, stream, source );+      if ( error )+      {+        FT_FREE( zip );+        goto Exit;+      }++      stream->descriptor.pointer = zip;+    }++    stream->size  = 0x7FFFFFFFL;  /* don't know the real size! */+    stream->pos   = 0;+    stream->base  = 0;+    stream->read  = ft_lzw_stream_io;+    stream->close = ft_lzw_stream_close;++  Exit:+    return error;+  }+++#include "ftzopen.c"+++#else  /* !FT_CONFIG_OPTION_USE_LZW */+++  FT_EXPORT_DEF( FT_Error )+  FT_Stream_OpenLZW( FT_Stream  stream,+                     FT_Stream  source )+  {+    FT_UNUSED( stream );+    FT_UNUSED( source );++    return LZW_Err_Unimplemented_Feature;+  }+++#endif /* !FT_CONFIG_OPTION_USE_LZW */+++/* END */
+ src/lzw/ftzopen.c view
@@ -0,0 +1,401 @@+/***************************************************************************/+/*                                                                         */+/*  ftzopen.c                                                              */+/*                                                                         */+/*    FreeType support for .Z compressed files.                            */+/*                                                                         */+/*  This optional component relies on NetBSD's zopen().  It should mainly  */+/*  be used to parse compressed PCF fonts, as found with many X11 server   */+/*  distributions.                                                         */+/*                                                                         */+/*  Copyright 2005, 2006, 2007, 2009 by David Turner.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include "ftzopen.h"+#include FT_INTERNAL_MEMORY_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_DEBUG_H+++  static int+  ft_lzwstate_refill( FT_LzwState  state )+  {+    FT_ULong  count;+++    if ( state->in_eof )+      return -1;++    count = FT_Stream_TryRead( state->source,+                               state->buf_tab,+                               state->num_bits );  /* WHY? */++    state->buf_size   = (FT_UInt)count;+    state->buf_total += count;+    state->in_eof     = FT_BOOL( count < state->num_bits );+    state->buf_offset = 0;+    state->buf_size   = ( state->buf_size << 3 ) - ( state->num_bits - 1 );++    if ( count == 0 )  /* end of file */+      return -1;++    return 0;+  }+++  static FT_Int32+  ft_lzwstate_get_code( FT_LzwState  state )+  {+    FT_UInt   num_bits = state->num_bits;+    FT_Int    offset   = state->buf_offset;+    FT_Byte*  p;+    FT_Int    result;+++    if ( state->buf_clear                    ||+         offset >= state->buf_size           ||+         state->free_ent >= state->free_bits )+    {+      if ( state->free_ent >= state->free_bits )+      {+        state->num_bits  = ++num_bits;+        state->free_bits = state->num_bits < state->max_bits+                           ? (FT_UInt)( ( 1UL << num_bits ) - 256 )+                           : state->max_free + 1;+      }++      if ( state->buf_clear )+      {+        state->num_bits  = num_bits = LZW_INIT_BITS;+        state->free_bits = (FT_UInt)( ( 1UL << num_bits ) - 256 );+        state->buf_clear = 0;+      }++      if ( ft_lzwstate_refill( state ) < 0 )+        return -1;++      offset = 0;+    }++    state->buf_offset = offset + num_bits;++    p         = &state->buf_tab[offset >> 3];+    offset   &= 7;+    result    = *p++ >> offset;+    offset    = 8 - offset;+    num_bits -= offset;++    if ( num_bits >= 8 )+    {+      result   |= *p++ << offset;+      offset   += 8;+      num_bits -= 8;+    }+    if ( num_bits > 0 )+      result |= ( *p & LZW_MASK( num_bits ) ) << offset;++    return result;+  }+++  /* grow the character stack */+  static int+  ft_lzwstate_stack_grow( FT_LzwState  state )+  {+    if ( state->stack_top >= state->stack_size )+    {+      FT_Memory  memory = state->memory;+      FT_Error   error;+      FT_Offset  old_size = state->stack_size;+      FT_Offset  new_size = old_size;++      new_size = new_size + ( new_size >> 1 ) + 4;++      if ( state->stack == state->stack_0 )+      {+        state->stack = NULL;+        old_size     = 0;+      }++      if ( FT_RENEW_ARRAY( state->stack, old_size, new_size ) )+        return -1;++      state->stack_size = new_size;+    }+    return 0;+  }+++  /* grow the prefix/suffix arrays */+  static int+  ft_lzwstate_prefix_grow( FT_LzwState  state )+  {+    FT_UInt    old_size = state->prefix_size;+    FT_UInt    new_size = old_size;+    FT_Memory  memory   = state->memory;+    FT_Error   error;+++    if ( new_size == 0 )  /* first allocation -> 9 bits */+      new_size = 512;+    else+      new_size += new_size >> 2;  /* don't grow too fast */++    /*+     *  Note that the `suffix' array is located in the same memory block+     *  pointed to by `prefix'.+     *+     *  I know that sizeof(FT_Byte) == 1 by definition, but it is clearer+     *  to write it literally.+     *+     */+    if ( FT_REALLOC_MULT( state->prefix, old_size, new_size,+                          sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) )+      return -1;++    /* now adjust `suffix' and move the data accordingly */+    state->suffix = (FT_Byte*)( state->prefix + new_size );++    FT_MEM_MOVE( state->suffix,+                 state->prefix + old_size,+                 old_size * sizeof ( FT_Byte ) );++    state->prefix_size = new_size;+    return 0;+  }+++  FT_LOCAL_DEF( void )+  ft_lzwstate_reset( FT_LzwState  state )+  {+    state->in_eof     = 0;+    state->buf_offset = 0;+    state->buf_size   = 0;+    state->buf_clear  = 0;+    state->buf_total  = 0;+    state->stack_top  = 0;+    state->num_bits   = LZW_INIT_BITS;+    state->phase      = FT_LZW_PHASE_START;+  }+++  FT_LOCAL_DEF( void )+  ft_lzwstate_init( FT_LzwState  state,+                    FT_Stream    source )+  {+    FT_ZERO( state );++    state->source = source;+    state->memory = source->memory;++    state->prefix      = NULL;+    state->suffix      = NULL;+    state->prefix_size = 0;++    state->stack      = state->stack_0;+    state->stack_size = sizeof ( state->stack_0 );++    ft_lzwstate_reset( state );+  }+++  FT_LOCAL_DEF( void )+  ft_lzwstate_done( FT_LzwState  state )+  {+    FT_Memory  memory = state->memory;+++    ft_lzwstate_reset( state );++    if ( state->stack != state->stack_0 )+      FT_FREE( state->stack );++    FT_FREE( state->prefix );+    state->suffix = NULL;++    FT_ZERO( state );+  }+++#define FTLZW_STACK_PUSH( c )                        \+  FT_BEGIN_STMNT                                     \+    if ( state->stack_top >= state->stack_size &&    \+         ft_lzwstate_stack_grow( state ) < 0   )     \+      goto Eof;                                      \+                                                     \+    state->stack[state->stack_top++] = (FT_Byte)(c); \+  FT_END_STMNT+++  FT_LOCAL_DEF( FT_ULong )+  ft_lzwstate_io( FT_LzwState  state,+                  FT_Byte*     buffer,+                  FT_ULong     out_size )+  {+    FT_ULong  result = 0;++    FT_UInt  old_char = state->old_char;+    FT_UInt  old_code = state->old_code;+    FT_UInt  in_code  = state->in_code;+++    if ( out_size == 0 )+      goto Exit;++    switch ( state->phase )+    {+    case FT_LZW_PHASE_START:+      {+        FT_Byte   max_bits;+        FT_Int32  c;+++        /* skip magic bytes, and read max_bits + block_flag */+        if ( FT_Stream_Seek( state->source, 2 ) != 0               ||+             FT_Stream_TryRead( state->source, &max_bits, 1 ) != 1 )+          goto Eof;++        state->max_bits   = max_bits & LZW_BIT_MASK;+        state->block_mode = max_bits & LZW_BLOCK_MASK;+        state->max_free   = (FT_UInt)( ( 1UL << state->max_bits ) - 256 );++        if ( state->max_bits > LZW_MAX_BITS )+          goto Eof;++        state->num_bits = LZW_INIT_BITS;+        state->free_ent = ( state->block_mode ? LZW_FIRST+                                              : LZW_CLEAR ) - 256;+        in_code  = 0;++        state->free_bits = state->num_bits < state->max_bits+                           ? (FT_UInt)( ( 1UL << state->num_bits ) - 256 )+                           : state->max_free + 1;++        c = ft_lzwstate_get_code( state );+        if ( c < 0 )+          goto Eof;++        old_code = old_char = (FT_UInt)c;++        if ( buffer )+          buffer[result] = (FT_Byte)old_char;++        if ( ++result >= out_size )+          goto Exit;++        state->phase = FT_LZW_PHASE_CODE;+      }+      /* fall-through */++    case FT_LZW_PHASE_CODE:+      {+        FT_Int32  c;+        FT_UInt   code;+++      NextCode:+        c = ft_lzwstate_get_code( state );+        if ( c < 0 )+          goto Eof;++        code = (FT_UInt)c;++        if ( code == LZW_CLEAR && state->block_mode )+        {+          /* why not LZW_FIRST-256 ? */+          state->free_ent  = ( LZW_FIRST - 1 ) - 256;+          state->buf_clear = 1;+          c = ft_lzwstate_get_code( state );+          if ( c < 0 )+            goto Eof;++          code = (FT_UInt)c;+        }++        in_code = code; /* save code for later */++        if ( code >= 256U )+        {+          /* special case for KwKwKwK */+          if ( code - 256U >= state->free_ent )+          {+            FTLZW_STACK_PUSH( old_char );+            code = old_code;+          }++          while ( code >= 256U )+          {+            if ( !state->prefix )+              goto Eof;++            FTLZW_STACK_PUSH( state->suffix[code - 256] );+            code = state->prefix[code - 256];+          }+        }++        old_char = code;+        FTLZW_STACK_PUSH( old_char );++        state->phase = FT_LZW_PHASE_STACK;+      }+      /* fall-through */++    case FT_LZW_PHASE_STACK:+      {+        while ( state->stack_top > 0 )+        {+          --state->stack_top;++          if ( buffer )+            buffer[result] = state->stack[state->stack_top];++          if ( ++result == out_size )+            goto Exit;+        }++        /* now create new entry */+        if ( state->free_ent < state->max_free )+        {+          if ( state->free_ent >= state->prefix_size &&+               ft_lzwstate_prefix_grow( state ) < 0  )+            goto Eof;++          FT_ASSERT( state->free_ent < state->prefix_size );++          state->prefix[state->free_ent] = (FT_UShort)old_code;+          state->suffix[state->free_ent] = (FT_Byte)  old_char;++          state->free_ent += 1;+        }++        old_code = in_code;++        state->phase = FT_LZW_PHASE_CODE;+        goto NextCode;+      }++    default:  /* state == EOF */+      ;+    }++  Exit:+    state->old_code = old_code;+    state->old_char = old_char;+    state->in_code  = in_code;++    return result;++  Eof:+    state->phase = FT_LZW_PHASE_EOF;+    goto Exit;+  }+++/* END */
+ src/lzw/ftzopen.h view
@@ -0,0 +1,171 @@+/***************************************************************************/+/*                                                                         */+/*  ftzopen.h                                                              */+/*                                                                         */+/*    FreeType support for .Z compressed files.                            */+/*                                                                         */+/*  This optional component relies on NetBSD's zopen().  It should mainly  */+/*  be used to parse compressed PCF fonts, as found with many X11 server   */+/*  distributions.                                                         */+/*                                                                         */+/*  Copyright 2005, 2006, 2007, 2008 by David Turner.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#ifndef __FT_ZOPEN_H__+#define __FT_ZOPEN_H__++#include <ft2build.h>+#include FT_FREETYPE_H+++  /*+   *  This is a complete re-implementation of the LZW file reader,+   *  since the old one was incredibly badly written, using+   *  400 KByte of heap memory before decompressing anything.+   *+   */++#define FT_LZW_IN_BUFF_SIZE        64+#define FT_LZW_DEFAULT_STACK_SIZE  64++#define LZW_INIT_BITS     9+#define LZW_MAX_BITS      16++#define LZW_CLEAR         256+#define LZW_FIRST         257++#define LZW_BIT_MASK      0x1f+#define LZW_BLOCK_MASK    0x80+#define LZW_MASK( n )     ( ( 1U << (n) ) - 1U )+++  typedef enum  FT_LzwPhase_+  {+    FT_LZW_PHASE_START = 0,+    FT_LZW_PHASE_CODE,+    FT_LZW_PHASE_STACK,+    FT_LZW_PHASE_EOF++  } FT_LzwPhase;+++  /*+   *  state of LZW decompressor+   *+   *  small technical note+   *  --------------------+   *+   *  We use a few tricks in this implementation that are explained here to+   *  ease debugging and maintenance.+   *+   *  - First of all, the `prefix' and `suffix' arrays contain the suffix+   *    and prefix for codes over 256; this means that+   *+   *      prefix_of(code) == state->prefix[code-256]+   *      suffix_of(code) == state->suffix[code-256]+   *+   *    Each prefix is a 16-bit code, and each suffix an 8-bit byte.+   *+   *    Both arrays are stored in a single memory block, pointed to by+   *    `state->prefix'.  This means that the following equality is always+   *    true:+   *+   *      state->suffix == (FT_Byte*)(state->prefix + state->prefix_size)+   *+   *    Of course, state->prefix_size is the number of prefix/suffix slots+   *    in the arrays, corresponding to codes 256..255+prefix_size.+   *+   *  - `free_ent' is the index of the next free entry in the `prefix'+   *    and `suffix' arrays.  This means that the corresponding `next free+   *    code' is really `256+free_ent'.+   *+   *    Moreover, `max_free' is the maximum value that `free_ent' can reach.+   *+   *    `max_free' corresponds to `(1 << max_bits) - 256'.  Note that this+   *    value is always <= 0xFF00, which means that both `free_ent' and+   *    `max_free' can be stored in an FT_UInt variable, even on 16-bit+   *    machines.+   *+   *    If `free_ent == max_free', you cannot add new codes to the+   *    prefix/suffix table.+   *+   *  - `num_bits' is the current number of code bits, starting at 9 and+   *    growing each time `free_ent' reaches the value of `free_bits'.  The+   *    latter is computed as follows+   *+   *      if num_bits < max_bits:+   *         free_bits = (1 << num_bits)-256+   *      else:+   *         free_bits = max_free + 1+   *+   *    Since the value of `max_free + 1' can never be reached by+   *    `free_ent', `num_bits' cannot grow larger than `max_bits'.+   */++  typedef struct  FT_LzwStateRec_+  {+    FT_LzwPhase  phase;+    FT_Int       in_eof;++    FT_Byte      buf_tab[16];+    FT_Int       buf_offset;+    FT_Int       buf_size;+    FT_Bool      buf_clear;+    FT_Offset    buf_total;++    FT_UInt      max_bits;    /* max code bits, from file header   */+    FT_Int       block_mode;  /* block mode flag, from file header */+    FT_UInt      max_free;    /* (1 << max_bits) - 256             */++    FT_UInt      num_bits;    /* current code bit number */+    FT_UInt      free_ent;    /* index of next free entry */+    FT_UInt      free_bits;   /* if reached by free_ent, increment num_bits */+    FT_UInt      old_code;+    FT_UInt      old_char;+    FT_UInt      in_code;++    FT_UShort*   prefix;      /* always dynamically allocated / reallocated */+    FT_Byte*     suffix;      /* suffix = (FT_Byte*)(prefix + prefix_size)  */+    FT_UInt      prefix_size; /* number of slots in `prefix' or `suffix'    */++    FT_Byte*     stack;       /* character stack */+    FT_UInt      stack_top;+    FT_Offset    stack_size;+    FT_Byte      stack_0[FT_LZW_DEFAULT_STACK_SIZE]; /* minimize heap alloc */++    FT_Stream    source;      /* source stream */+    FT_Memory    memory;++  } FT_LzwStateRec, *FT_LzwState;+++  FT_LOCAL( void )+  ft_lzwstate_init( FT_LzwState  state,+                    FT_Stream    source );++  FT_LOCAL( void )+  ft_lzwstate_done( FT_LzwState  state );+++  FT_LOCAL( void )+  ft_lzwstate_reset( FT_LzwState  state );+++  FT_LOCAL( FT_ULong )+  ft_lzwstate_io( FT_LzwState  state,+                  FT_Byte*     buffer,+                  FT_ULong     out_size );++/* */++#endif /* __FT_ZOPEN_H__ */+++/* END */
+ src/pcf/pcf.c view
@@ -0,0 +1,36 @@+/*  pcf.c++    FreeType font driver for pcf fonts++  Copyright 2000-2001, 2003 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#define FT_MAKE_OPTION_SINGLE_OBJECT+++#include <ft2build.h>+#include "pcfutil.c"+#include "pcfread.c"+#include "pcfdrivr.c"++/* END */
+ src/pcf/pcf.h view
@@ -0,0 +1,237 @@+/*  pcf.h++  FreeType font driver for pcf fonts++  Copyright (C) 2000, 2001, 2002, 2003, 2006 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __PCF_H__+#define __PCF_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+#include FT_INTERNAL_STREAM_H+++FT_BEGIN_HEADER++  typedef struct  PCF_TableRec_+  {+    FT_ULong  type;+    FT_ULong  format;+    FT_ULong  size;+    FT_ULong  offset;++  } PCF_TableRec, *PCF_Table;+++  typedef struct  PCF_TocRec_+  {+    FT_ULong   version;+    FT_ULong   count;+    PCF_Table  tables;++  } PCF_TocRec, *PCF_Toc;+++  typedef struct  PCF_ParsePropertyRec_+  {+    FT_Long  name;+    FT_Byte  isString;+    FT_Long  value;++  } PCF_ParsePropertyRec, *PCF_ParseProperty;+++  typedef struct  PCF_PropertyRec_+  {+    FT_String*  name;+    FT_Byte     isString;++    union+    {+      FT_String*  atom;+      FT_Long     l;+      FT_ULong    ul;++    } value;++  } PCF_PropertyRec, *PCF_Property;+++  typedef struct  PCF_Compressed_MetricRec_+  {+    FT_Byte  leftSideBearing;+    FT_Byte  rightSideBearing;+    FT_Byte  characterWidth;+    FT_Byte  ascent;+    FT_Byte  descent;++  } PCF_Compressed_MetricRec, *PCF_Compressed_Metric;+++  typedef struct  PCF_MetricRec_+  {+    FT_Short  leftSideBearing;+    FT_Short  rightSideBearing;+    FT_Short  characterWidth;+    FT_Short  ascent;+    FT_Short  descent;+    FT_Short  attributes;+    FT_ULong  bits;++  } PCF_MetricRec, *PCF_Metric;+++  typedef struct  PCF_AccelRec_+  {+    FT_Byte        noOverlap;+    FT_Byte        constantMetrics;+    FT_Byte        terminalFont;+    FT_Byte        constantWidth;+    FT_Byte        inkInside;+    FT_Byte        inkMetrics;+    FT_Byte        drawDirection;+    FT_Long        fontAscent;+    FT_Long        fontDescent;+    FT_Long        maxOverlap;+    PCF_MetricRec  minbounds;+    PCF_MetricRec  maxbounds;+    PCF_MetricRec  ink_minbounds;+    PCF_MetricRec  ink_maxbounds;++  } PCF_AccelRec, *PCF_Accel;+++  typedef struct  PCF_EncodingRec_+  {+    FT_Long    enc;+    FT_UShort  glyph;++  } PCF_EncodingRec, *PCF_Encoding;+++  typedef struct  PCF_FaceRec_+  {+    FT_FaceRec     root;++    FT_StreamRec   gzip_stream;+    FT_Stream      gzip_source;++    char*          charset_encoding;+    char*          charset_registry;++    PCF_TocRec     toc;+    PCF_AccelRec   accel;++    int            nprops;+    PCF_Property   properties;++    FT_Long        nmetrics;+    PCF_Metric     metrics;+    FT_Long        nencodings;+    PCF_Encoding   encodings;++    FT_Short       defaultChar;++    FT_ULong       bitmapsFormat;++    FT_CharMap     charmap_handle;+    FT_CharMapRec  charmap;  /* a single charmap per face */++  } PCF_FaceRec, *PCF_Face;+++  /* macros for pcf font format */++#define LSBFirst  0+#define MSBFirst  1++#define PCF_FILE_VERSION        ( ( 'p' << 24 ) | \+                                  ( 'c' << 16 ) | \+                                  ( 'f' <<  8 ) | 1 )+#define PCF_FORMAT_MASK         0xFFFFFF00UL++#define PCF_DEFAULT_FORMAT      0x00000000UL+#define PCF_INKBOUNDS           0x00000200UL+#define PCF_ACCEL_W_INKBOUNDS   0x00000100UL+#define PCF_COMPRESSED_METRICS  0x00000100UL++#define PCF_FORMAT_MATCH( a, b ) \+          ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) )++#define PCF_GLYPH_PAD_MASK  ( 3 << 0 )+#define PCF_BYTE_MASK       ( 1 << 2 )+#define PCF_BIT_MASK        ( 1 << 3 )+#define PCF_SCAN_UNIT_MASK  ( 3 << 4 )++#define PCF_BYTE_ORDER( f ) \+          ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst )+#define PCF_BIT_ORDER( f ) \+          ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst )+#define PCF_GLYPH_PAD_INDEX( f ) \+          ( (f) & PCF_GLYPH_PAD_MASK )+#define PCF_GLYPH_PAD( f ) \+          ( 1 << PCF_GLYPH_PAD_INDEX( f ) )+#define PCF_SCAN_UNIT_INDEX( f ) \+          ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 )+#define PCF_SCAN_UNIT( f ) \+          ( 1 << PCF_SCAN_UNIT_INDEX( f ) )+#define PCF_FORMAT_BITS( f )             \+          ( (f) & ( PCF_GLYPH_PAD_MASK | \+                    PCF_BYTE_MASK      | \+                    PCF_BIT_MASK       | \+                    PCF_SCAN_UNIT_MASK ) )++#define PCF_SIZE_TO_INDEX( s )  ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 )+#define PCF_INDEX_TO_SIZE( b )  ( 1 << b )++#define PCF_FORMAT( bit, byte, glyph, scan )          \+          ( ( PCF_SIZE_TO_INDEX( scan )      << 4 ) | \+            ( ( (bit)  == MSBFirst ? 1 : 0 ) << 3 ) | \+            ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \+            ( PCF_SIZE_TO_INDEX( glyph )     << 0 ) )++#define PCF_PROPERTIES        ( 1 << 0 )+#define PCF_ACCELERATORS      ( 1 << 1 )+#define PCF_METRICS           ( 1 << 2 )+#define PCF_BITMAPS           ( 1 << 3 )+#define PCF_INK_METRICS       ( 1 << 4 )+#define PCF_BDF_ENCODINGS     ( 1 << 5 )+#define PCF_SWIDTHS           ( 1 << 6 )+#define PCF_GLYPH_NAMES       ( 1 << 7 )+#define PCF_BDF_ACCELERATORS  ( 1 << 8 )++#define GLYPHPADOPTIONS  4 /* I'm not sure about this */++  FT_LOCAL( FT_Error )+  pcf_load_font( FT_Stream,+                 PCF_Face );++FT_END_HEADER++#endif /* __PCF_H__ */+++/* END */
+ src/pcf/pcfdrivr.c view
@@ -0,0 +1,698 @@+/*  pcfdrivr.c++    FreeType font driver for pcf files++    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by+    Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#include <ft2build.h>++#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_OBJECTS_H+#include FT_GZIP_H+#include FT_LZW_H+#include FT_ERRORS_H+#include FT_BDF_H+#include FT_TRUETYPE_IDS_H ++#include "pcf.h"+#include "pcfdrivr.h"+#include "pcfread.h"++#include "pcferror.h"+#include "pcfutil.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pcfread++#include FT_SERVICE_BDF_H+#include FT_SERVICE_XFREE86_NAME_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pcfdriver+++  typedef struct  PCF_CMapRec_+  {+    FT_CMapRec    root;+    FT_UInt       num_encodings;+    PCF_Encoding  encodings;++  } PCF_CMapRec, *PCF_CMap;+++  FT_CALLBACK_DEF( FT_Error )+  pcf_cmap_init( FT_CMap     pcfcmap,   /* PCF_CMap */+                 FT_Pointer  init_data )+  {+    PCF_CMap  cmap = (PCF_CMap)pcfcmap;+    PCF_Face  face = (PCF_Face)FT_CMAP_FACE( pcfcmap );++    FT_UNUSED( init_data );+++    cmap->num_encodings = (FT_UInt)face->nencodings;+    cmap->encodings     = face->encodings;++    return PCF_Err_Ok;+  }+++  FT_CALLBACK_DEF( void )+  pcf_cmap_done( FT_CMap  pcfcmap )         /* PCF_CMap */+  {+    PCF_CMap  cmap = (PCF_CMap)pcfcmap;+++    cmap->encodings     = NULL;+    cmap->num_encodings = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  pcf_cmap_char_index( FT_CMap    pcfcmap,  /* PCF_CMap */+                       FT_UInt32  charcode )+  {+    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;+    PCF_Encoding  encodings = cmap->encodings;+    FT_UInt       min, max, mid;+    FT_UInt       result    = 0;+++    min = 0;+    max = cmap->num_encodings;++    while ( min < max )+    {+      FT_ULong  code;+++      mid  = ( min + max ) >> 1;+      code = encodings[mid].enc;++      if ( charcode == code )+      {+        result = encodings[mid].glyph + 1;+        break;+      }++      if ( charcode < code )+        max = mid;+      else+        min = mid + 1;+    }++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  pcf_cmap_char_next( FT_CMap    pcfcmap,   /* PCF_CMap */+                      FT_UInt32  *acharcode )+  {+    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;+    PCF_Encoding  encodings = cmap->encodings;+    FT_UInt       min, max, mid;+    FT_ULong      charcode  = *acharcode + 1;+    FT_UInt       result    = 0;+++    min = 0;+    max = cmap->num_encodings;++    while ( min < max )+    {+      FT_ULong  code;+++      mid  = ( min + max ) >> 1;+      code = encodings[mid].enc;++      if ( charcode == code )+      {+        result = encodings[mid].glyph + 1;+        goto Exit;+      }++      if ( charcode < code )+        max = mid;+      else+        min = mid + 1;+    }++    charcode = 0;+    if ( min < cmap->num_encodings )+    {+      charcode = encodings[min].enc;+      result   = encodings[min].glyph + 1;+    }++  Exit:+    if ( charcode > 0xFFFFFFFFUL )+    {+      FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));+      *acharcode = 0;+      /* XXX: result should be changed to indicate an overflow error */+    }+    else+      *acharcode = (FT_UInt32)charcode;+    return result;+  }+++  FT_CALLBACK_TABLE_DEF+  const FT_CMap_ClassRec  pcf_cmap_class =+  {+    sizeof ( PCF_CMapRec ),+    pcf_cmap_init,+    pcf_cmap_done,+    pcf_cmap_char_index,+    pcf_cmap_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++  FT_CALLBACK_DEF( void )+  PCF_Face_Done( FT_Face  pcfface )         /* PCF_Face */+  {+    PCF_Face   face = (PCF_Face)pcfface;+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );++    FT_FREE( face->encodings );+    FT_FREE( face->metrics );++    /* free properties */+    {+      PCF_Property  prop;+      FT_Int        i;+++      if ( face->properties )+      {+        for ( i = 0; i < face->nprops; i++ )+        {+          prop = &face->properties[i];++          if ( prop )+          {+            FT_FREE( prop->name );+            if ( prop->isString )+              FT_FREE( prop->value.atom );+          }+        }+      }+      FT_FREE( face->properties );+    }++    FT_FREE( face->toc.tables );+    FT_FREE( pcfface->family_name );+    FT_FREE( pcfface->style_name );+    FT_FREE( pcfface->available_sizes );+    FT_FREE( face->charset_encoding );+    FT_FREE( face->charset_registry );++    FT_TRACE4(( "PCF_Face_Done: done face\n" ));++    /* close gzip/LZW stream if any */+    if ( pcfface->stream == &face->gzip_stream )+    {+      FT_Stream_Close( &face->gzip_stream );+      pcfface->stream = face->gzip_source;+    }+  }+++  FT_CALLBACK_DEF( FT_Error )+  PCF_Face_Init( FT_Stream      stream,+                 FT_Face        pcfface,        /* PCF_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    PCF_Face  face  = (PCF_Face)pcfface;+    FT_Error  error = PCF_Err_Ok;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+    FT_UNUSED( face_index );+++    error = pcf_load_font( stream, face );+    if ( error )+    {+      PCF_Face_Done( pcfface );++#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \+    defined( FT_CONFIG_OPTION_USE_LZW )++#ifdef FT_CONFIG_OPTION_USE_ZLIB+      {+        FT_Error  error2;+++        /* this didn't work, try gzip support! */+        error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );+        if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )+          goto Fail;++        error = error2;+      }+#endif /* FT_CONFIG_OPTION_USE_ZLIB */++#ifdef FT_CONFIG_OPTION_USE_LZW+      if ( error )+      {+        FT_Error  error3;+++        /* this didn't work, try LZW support! */+        error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream );+        if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )+          goto Fail;++        error = error3;+      }+#endif /* FT_CONFIG_OPTION_USE_LZW */++      if ( error )+        goto Fail;++      face->gzip_source = stream;+      pcfface->stream   = &face->gzip_stream;++      stream = pcfface->stream;++      error = pcf_load_font( stream, face );+      if ( error )+        goto Fail;++#else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */++      goto Fail;++#endif+    }++    /* set up charmap */+    {+      FT_String  *charset_registry = face->charset_registry;+      FT_String  *charset_encoding = face->charset_encoding;+      FT_Bool     unicode_charmap  = 0;+++      if ( charset_registry && charset_encoding )+      {+        char*  s = charset_registry;+++        /* Uh, oh, compare first letters manually to avoid dependency+           on locales. */+        if ( ( s[0] == 'i' || s[0] == 'I' ) &&+             ( s[1] == 's' || s[1] == 'S' ) &&+             ( s[2] == 'o' || s[2] == 'O' ) )+        {+          s += 3;+          if ( !ft_strcmp( s, "10646" )                      ||+               ( !ft_strcmp( s, "8859" ) &&+                 !ft_strcmp( face->charset_encoding, "1" ) ) )+          unicode_charmap = 1;+        }+      }++      {+        FT_CharMapRec  charmap;+++        charmap.face        = FT_FACE( face );+        charmap.encoding    = FT_ENCODING_NONE;+        /* initial platform/encoding should indicate unset status? */+        charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;+        charmap.encoding_id = TT_APPLE_ID_DEFAULT;++        if ( unicode_charmap )+        {+          charmap.encoding    = FT_ENCODING_UNICODE;+          charmap.platform_id = TT_PLATFORM_MICROSOFT;+          charmap.encoding_id = TT_MS_ID_UNICODE_CS;+        }++        error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );++#if 0+        /* Select default charmap */+        if ( pcfface->num_charmaps )+          pcfface->charmap = pcfface->charmaps[0];+#endif+      }+    }++  Exit:+    return error;++  Fail:+    FT_TRACE2(( "[not a valid PCF file]\n" ));+    PCF_Face_Done( pcfface );+    error = PCF_Err_Unknown_File_Format;  /* error */+    goto Exit;+  }+++  FT_CALLBACK_DEF( FT_Error )+  PCF_Size_Select( FT_Size   size,+                   FT_ULong  strike_index )+  {+    PCF_Accel  accel = &( (PCF_Face)size->face )->accel;+++    FT_Select_Metrics( size->face, strike_index );++    size->metrics.ascender    =  accel->fontAscent << 6;+    size->metrics.descender   = -accel->fontDescent << 6;+    size->metrics.max_advance =  accel->maxbounds.characterWidth << 6;++    return PCF_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  PCF_Size_Request( FT_Size          size,+                    FT_Size_Request  req )+  {+    PCF_Face         face  = (PCF_Face)size->face;+    FT_Bitmap_Size*  bsize = size->face->available_sizes;+    FT_Error         error = PCF_Err_Invalid_Pixel_Size;+    FT_Long          height;+++    height = FT_REQUEST_HEIGHT( req );+    height = ( height + 32 ) >> 6;++    switch ( req->type )+    {+    case FT_SIZE_REQUEST_TYPE_NOMINAL:+      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )+        error = PCF_Err_Ok;+      break;++    case FT_SIZE_REQUEST_TYPE_REAL_DIM:+      if ( height == ( face->accel.fontAscent ++                       face->accel.fontDescent ) )+        error = PCF_Err_Ok;+      break;++    default:+      error = PCF_Err_Unimplemented_Feature;+      break;+    }++    if ( error )+      return error;+    else+      return PCF_Size_Select( size, 0 );+  }+++  FT_CALLBACK_DEF( FT_Error )+  PCF_Glyph_Load( FT_GlyphSlot  slot,+                  FT_Size       size,+                  FT_UInt       glyph_index,+                  FT_Int32      load_flags )+  {+    PCF_Face    face   = (PCF_Face)FT_SIZE_FACE( size );+    FT_Stream   stream;+    FT_Error    error  = PCF_Err_Ok;+    FT_Bitmap*  bitmap = &slot->bitmap;+    PCF_Metric  metric;+    FT_Offset   bytes;++    FT_UNUSED( load_flags );+++    FT_TRACE4(( "load_glyph %d ---", glyph_index ));++    if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )+    {+      error = PCF_Err_Invalid_Argument;+      goto Exit;+    }++    stream = face->root.stream;++    if ( glyph_index > 0 )+      glyph_index--;++    metric = face->metrics + glyph_index;++    bitmap->rows       = metric->ascent + metric->descent;+    bitmap->width      = metric->rightSideBearing - metric->leftSideBearing;+    bitmap->num_grays  = 1;+    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;++    FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",+                  PCF_BIT_ORDER( face->bitmapsFormat ),+                  PCF_BYTE_ORDER( face->bitmapsFormat ),+                  PCF_GLYPH_PAD( face->bitmapsFormat ) ));++    switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )+    {+    case 1:+      bitmap->pitch = ( bitmap->width + 7 ) >> 3;+      break;++    case 2:+      bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;+      break;++    case 4:+      bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;+      break;++    case 8:+      bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;+      break;++    default:+      return PCF_Err_Invalid_File_Format;+    }++    /* XXX: to do: are there cases that need repadding the bitmap? */+    bytes = bitmap->pitch * bitmap->rows;++    error = ft_glyphslot_alloc_bitmap( slot, bytes );+    if ( error )+      goto Exit;++    if ( FT_STREAM_SEEK( metric->bits )          ||+         FT_STREAM_READ( bitmap->buffer, bytes ) )+      goto Exit;++    if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )+      BitOrderInvert( bitmap->buffer, bytes );++    if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=+           PCF_BIT_ORDER( face->bitmapsFormat )  ) )+    {+      switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )+      {+      case 1:+        break;++      case 2:+        TwoByteSwap( bitmap->buffer, bytes );+        break;++      case 4:+        FourByteSwap( bitmap->buffer, bytes );+        break;+      }+    }++    slot->format      = FT_GLYPH_FORMAT_BITMAP;+    slot->bitmap_left = metric->leftSideBearing;+    slot->bitmap_top  = metric->ascent;++    slot->metrics.horiAdvance  = metric->characterWidth << 6;+    slot->metrics.horiBearingX = metric->leftSideBearing << 6;+    slot->metrics.horiBearingY = metric->ascent << 6;+    slot->metrics.width        = ( metric->rightSideBearing -+                                   metric->leftSideBearing ) << 6;+    slot->metrics.height       = bitmap->rows << 6;++    ft_synthesize_vertical_metrics( &slot->metrics,+                                    ( face->accel.fontAscent ++                                      face->accel.fontDescent ) << 6 );++    FT_TRACE4(( " --- ok\n" ));++  Exit:+    return error;+  }+++ /*+  *+  *  BDF SERVICE+  *+  */++  static FT_Error+  pcf_get_bdf_property( PCF_Face          face,+                        const char*       prop_name,+                        BDF_PropertyRec  *aproperty )+  {+    PCF_Property  prop;+++    prop = pcf_find_property( face, prop_name );+    if ( prop != NULL )+    {+      if ( prop->isString )+      {+        aproperty->type   = BDF_PROPERTY_TYPE_ATOM;+        aproperty->u.atom = prop->value.atom;+      }+      else+      {+        if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )+        {+          FT_TRACE1(( "pcf_get_bdf_property: " ));+          FT_TRACE1(( "too large integer 0x%x is truncated\n" ));+        }+        /* Apparently, the PCF driver loads all properties as signed integers!+         * This really doesn't seem to be a problem, because this is+         * sufficient for any meaningful values.+         */+        aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;+        aproperty->u.integer = (FT_Int32)prop->value.l;+      }+      return 0;+    }++    return PCF_Err_Invalid_Argument;+  }+++  static FT_Error+  pcf_get_charset_id( PCF_Face      face,+                      const char*  *acharset_encoding,+                      const char*  *acharset_registry )+  {+    *acharset_encoding = face->charset_encoding;+    *acharset_registry = face->charset_registry;++    return 0;+  }+++  static const FT_Service_BDFRec  pcf_service_bdf =+  {+    (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,+    (FT_BDF_GetPropertyFunc) pcf_get_bdf_property+  };+++ /*+  *+  *  SERVICE LIST+  *+  */++  static const FT_ServiceDescRec  pcf_services[] =+  {+    { FT_SERVICE_ID_BDF,       &pcf_service_bdf },+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },+    { NULL, NULL }+  };+++  FT_CALLBACK_DEF( FT_Module_Interface )+  pcf_driver_requester( FT_Module    module,+                        const char*  name )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( pcf_services, name );+  }+++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  pcf_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER        |+      FT_MODULE_DRIVER_NO_OUTLINES,+      sizeof ( FT_DriverRec ),++      "pcf",+      0x10000L,+      0x20000L,++      0,++      0,+      0,+      pcf_driver_requester+    },++    sizeof ( PCF_FaceRec ),+    sizeof ( FT_SizeRec ),+    sizeof ( FT_GlyphSlotRec ),++    PCF_Face_Init,+    PCF_Face_Done,+    0,                      /* FT_Size_InitFunc */+    0,                      /* FT_Size_DoneFunc */+    0,                      /* FT_Slot_InitFunc */+    0,                      /* FT_Slot_DoneFunc */++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    PCF_Glyph_Load,++    0,                      /* FT_Face_GetKerningFunc  */+    0,                      /* FT_Face_AttachFunc      */+    0,                      /* FT_Face_GetAdvancesFunc */++    PCF_Size_Request,+    PCF_Size_Select+  };+++/* END */
+ src/pcf/pcfdrivr.h view
@@ -0,0 +1,48 @@+/*  pcfdrivr.h++    FreeType font driver for pcf fonts++  Copyright 2000-2001, 2002 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __PCFDRIVR_H__+#define __PCFDRIVR_H__++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif ++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  pcf_driver_class;++FT_END_HEADER+++#endif /* __PCFDRIVR_H__ */+++/* END */
+ src/pcf/pcferror.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  pcferror.h                                                             */+/*                                                                         */+/*    PCF error codes (specification only).                                */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the PCF error enumeration constants.      */+  /*                                                                       */+  /*************************************************************************/++#ifndef __PCFERROR_H__+#define __PCFERROR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  PCF_Err_+#define FT_ERR_BASE    FT_Mod_Err_PCF++#include FT_ERRORS_H++#endif /* __PCFERROR_H__ */+++/* END */
+ src/pcf/pcfread.c view
@@ -0,0 +1,1278 @@+/*  pcfread.c++    FreeType font driver for pcf fonts++  Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,+            2010 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#include <ft2build.h>++#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_OBJECTS_H++#include "pcf.h"+#include "pcfread.h"++#include "pcferror.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pcfread+++#ifdef FT_DEBUG_LEVEL_TRACE+  static const char* const  tableNames[] =+  {+    "prop", "accl", "mtrcs", "bmps", "imtrcs",+    "enc", "swidth", "names", "accel"+  };+#endif+++  static+  const FT_Frame_Field  pcf_toc_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_TocRec++    FT_FRAME_START( 8 ),+      FT_FRAME_ULONG_LE( version ),+      FT_FRAME_ULONG_LE( count ),+    FT_FRAME_END+  };+++  static+  const FT_Frame_Field  pcf_table_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_TableRec++    FT_FRAME_START( 16  ),+      FT_FRAME_ULONG_LE( type ),+      FT_FRAME_ULONG_LE( format ),+      FT_FRAME_ULONG_LE( size ),+      FT_FRAME_ULONG_LE( offset ),+    FT_FRAME_END+  };+++  static FT_Error+  pcf_read_TOC( FT_Stream  stream,+                PCF_Face   face )+  {+    FT_Error   error;+    PCF_Toc    toc = &face->toc;+    PCF_Table  tables;++    FT_Memory  memory = FT_FACE(face)->memory;+    FT_UInt    n;+++    if ( FT_STREAM_SEEK ( 0 )                          ||+         FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) )+      return PCF_Err_Cannot_Open_Resource;++    if ( toc->version != PCF_FILE_VERSION                 ||+         toc->count   >  FT_ARRAY_MAX( face->toc.tables ) ||+         toc->count   == 0                                )+      return PCF_Err_Invalid_File_Format;++    if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )+      return PCF_Err_Out_Of_Memory;++    tables = face->toc.tables;+    for ( n = 0; n < toc->count; n++ )+    {+      if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) )+        goto Exit;+      tables++;+    }++    /* Sort tables and check for overlaps.  Because they are almost      */+    /* always ordered already, an in-place bubble sort with simultaneous */+    /* boundary checking seems appropriate.                              */+    tables = face->toc.tables;++    for ( n = 0; n < toc->count - 1; n++ )+    {+      FT_UInt  i, have_change;+++      have_change = 0;++      for ( i = 0; i < toc->count - 1 - n; i++ )+      {+        PCF_TableRec  tmp;+++        if ( tables[i].offset > tables[i + 1].offset )+        {+          tmp           = tables[i];+          tables[i]     = tables[i + 1];+          tables[i + 1] = tmp;++          have_change = 1;+        }++        if ( ( tables[i].size   > tables[i + 1].offset )                  ||+             ( tables[i].offset > tables[i + 1].offset - tables[i].size ) )+          return PCF_Err_Invalid_Offset;+      }++      if ( !have_change )+        break;+    }++#ifdef FT_DEBUG_LEVEL_TRACE++    {+      FT_UInt      i, j;+      const char*  name = "?";+++      FT_TRACE4(( "pcf_read_TOC:\n" ));++      FT_TRACE4(( "  number of tables: %ld\n", face->toc.count ));++      tables = face->toc.tables;+      for ( i = 0; i < toc->count; i++ )+      {+        for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );+              j++ )+          if ( tables[i].type == (FT_UInt)( 1 << j ) )+            name = tableNames[j];++        FT_TRACE4(( "  %d: type=%s, format=0x%X, "+                    "size=%ld (0x%lX), offset=%ld (0x%lX)\n",+                    i, name,+                    tables[i].format,+                    tables[i].size, tables[i].size,+                    tables[i].offset, tables[i].offset ));+      }+    }++#endif++    return PCF_Err_Ok;++  Exit:+    FT_FREE( face->toc.tables );+    return error;+  }+++#define PCF_METRIC_SIZE  12++  static+  const FT_Frame_Field  pcf_metric_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_MetricRec++    FT_FRAME_START( PCF_METRIC_SIZE ),+      FT_FRAME_SHORT_LE( leftSideBearing ),+      FT_FRAME_SHORT_LE( rightSideBearing ),+      FT_FRAME_SHORT_LE( characterWidth ),+      FT_FRAME_SHORT_LE( ascent ),+      FT_FRAME_SHORT_LE( descent ),+      FT_FRAME_SHORT_LE( attributes ),+    FT_FRAME_END+  };+++  static+  const FT_Frame_Field  pcf_metric_msb_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_MetricRec++    FT_FRAME_START( PCF_METRIC_SIZE ),+      FT_FRAME_SHORT( leftSideBearing ),+      FT_FRAME_SHORT( rightSideBearing ),+      FT_FRAME_SHORT( characterWidth ),+      FT_FRAME_SHORT( ascent ),+      FT_FRAME_SHORT( descent ),+      FT_FRAME_SHORT( attributes ),+    FT_FRAME_END+  };+++#define PCF_COMPRESSED_METRIC_SIZE  5++  static+  const FT_Frame_Field  pcf_compressed_metric_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_Compressed_MetricRec++    FT_FRAME_START( PCF_COMPRESSED_METRIC_SIZE ),+      FT_FRAME_BYTE( leftSideBearing ),+      FT_FRAME_BYTE( rightSideBearing ),+      FT_FRAME_BYTE( characterWidth ),+      FT_FRAME_BYTE( ascent ),+      FT_FRAME_BYTE( descent ),+    FT_FRAME_END+  };+++  static FT_Error+  pcf_get_metric( FT_Stream   stream,+                  FT_ULong    format,+                  PCF_Metric  metric )+  {+    FT_Error  error = PCF_Err_Ok;+++    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+    {+      const FT_Frame_Field*  fields;+++      /* parsing normal metrics */+      fields = PCF_BYTE_ORDER( format ) == MSBFirst+               ? pcf_metric_msb_header+               : pcf_metric_header;++      /* the following sets `error' but doesn't return in case of failure */+      (void)FT_STREAM_READ_FIELDS( fields, metric );+    }+    else+    {+      PCF_Compressed_MetricRec  compr;+++      /* parsing compressed metrics */+      if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) )+        goto Exit;++      metric->leftSideBearing  = (FT_Short)( compr.leftSideBearing  - 0x80 );+      metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );+      metric->characterWidth   = (FT_Short)( compr.characterWidth   - 0x80 );+      metric->ascent           = (FT_Short)( compr.ascent           - 0x80 );+      metric->descent          = (FT_Short)( compr.descent          - 0x80 );+      metric->attributes       = 0;+    }++  Exit:+    return error;+  }+++  static FT_Error+  pcf_seek_to_table_type( FT_Stream  stream,+                          PCF_Table  tables,+                          FT_ULong   ntables, /* same as PCF_Toc->count */+                          FT_ULong   type,+                          FT_ULong  *aformat,+                          FT_ULong  *asize )+  {+    FT_Error  error = PCF_Err_Invalid_File_Format;+    FT_ULong  i;+++    for ( i = 0; i < ntables; i++ )+      if ( tables[i].type == type )+      {+        if ( stream->pos > tables[i].offset )+        {+          error = PCF_Err_Invalid_Stream_Skip;+          goto Fail;+        }++        if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )+        {+          error = PCF_Err_Invalid_Stream_Skip;+          goto Fail;+        }++        *asize   = tables[i].size;+        *aformat = tables[i].format;++        return PCF_Err_Ok;+      }++  Fail:+    *asize = 0;+    return error;+  }+++  static FT_Bool+  pcf_has_table_type( PCF_Table  tables,+                      FT_ULong   ntables, /* same as PCF_Toc->count */+                      FT_ULong   type )+  {+    FT_ULong  i;+++    for ( i = 0; i < ntables; i++ )+      if ( tables[i].type == type )+        return TRUE;++    return FALSE;+  }+++#define PCF_PROPERTY_SIZE  9++  static+  const FT_Frame_Field  pcf_property_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_ParsePropertyRec++    FT_FRAME_START( PCF_PROPERTY_SIZE ),+      FT_FRAME_LONG_LE( name ),+      FT_FRAME_BYTE   ( isString ),+      FT_FRAME_LONG_LE( value ),+    FT_FRAME_END+  };+++  static+  const FT_Frame_Field  pcf_property_msb_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_ParsePropertyRec++    FT_FRAME_START( PCF_PROPERTY_SIZE ),+      FT_FRAME_LONG( name ),+      FT_FRAME_BYTE( isString ),+      FT_FRAME_LONG( value ),+    FT_FRAME_END+  };+++  FT_LOCAL_DEF( PCF_Property )+  pcf_find_property( PCF_Face          face,+                     const FT_String*  prop )+  {+    PCF_Property  properties = face->properties;+    FT_Bool       found      = 0;+    int           i;+++    for ( i = 0 ; i < face->nprops && !found; i++ )+    {+      if ( !ft_strcmp( properties[i].name, prop ) )+        found = 1;+    }++    if ( found )+      return properties + i - 1;+    else+      return NULL;+  }+++  static FT_Error+  pcf_get_properties( FT_Stream  stream,+                      PCF_Face   face )+  {+    PCF_ParseProperty  props      = 0;+    PCF_Property       properties;+    FT_ULong           nprops, i;+    FT_ULong           format, size;+    FT_Error           error;+    FT_Memory          memory     = FT_FACE(face)->memory;+    FT_ULong           string_size;+    FT_String*         strings    = 0;+++    error = pcf_seek_to_table_type( stream,+                                    face->toc.tables,+                                    face->toc.count,+                                    PCF_PROPERTIES,+                                    &format,+                                    &size );+    if ( error )+      goto Bail;++    if ( FT_READ_ULONG_LE( format ) )+      goto Bail;++    FT_TRACE4(( "pcf_get_properties:\n" ));++    FT_TRACE4(( "  format = %ld\n", format ));++    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+      goto Bail;++    if ( PCF_BYTE_ORDER( format ) == MSBFirst )+      (void)FT_READ_ULONG( nprops );+    else+      (void)FT_READ_ULONG_LE( nprops );+    if ( error )+      goto Bail;++    FT_TRACE4(( "  nprop = %d (truncate %d props)\n",+                (int)nprops, nprops - (int)nprops ));++    nprops = (int)nprops;++    /* rough estimate */+    if ( nprops > size / PCF_PROPERTY_SIZE )+    {+      error = PCF_Err_Invalid_Table;+      goto Bail;+    }++    face->nprops = (int)nprops;++    if ( FT_NEW_ARRAY( props, nprops ) )+      goto Bail;++    for ( i = 0; i < nprops; i++ )+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+      {+        if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) )+          goto Bail;+      }+      else+      {+        if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) )+          goto Bail;+      }+    }++    /* pad the property array                                            */+    /*                                                                   */+    /* clever here - nprops is the same as the number of odd-units read, */+    /* as only isStringProp are odd length   (Keith Packard)             */+    /*                                                                   */+    if ( nprops & 3 )+    {+      i = 4 - ( nprops & 3 );+      if ( FT_STREAM_SKIP( i ) )+      {+        error = PCF_Err_Invalid_Stream_Skip;+        goto Bail;+      }+    }++    if ( PCF_BYTE_ORDER( format ) == MSBFirst )+      (void)FT_READ_ULONG( string_size );+    else+      (void)FT_READ_ULONG_LE( string_size );+    if ( error )+      goto Bail;++    FT_TRACE4(( "  string_size = %ld\n", string_size ));++    /* rough estimate */+    if ( string_size > size - nprops * PCF_PROPERTY_SIZE )+    {+      error = PCF_Err_Invalid_Table;+      goto Bail;+    }++    if ( FT_NEW_ARRAY( strings, string_size ) )+      goto Bail;++    error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size );+    if ( error )+      goto Bail;++    if ( FT_NEW_ARRAY( properties, nprops ) )+      goto Bail;++    face->properties = properties;++    for ( i = 0; i < nprops; i++ )+    {+      FT_Long  name_offset = props[i].name;+++      if ( ( name_offset < 0 )                     ||+           ( (FT_ULong)name_offset > string_size ) )+      {+        error = PCF_Err_Invalid_Offset;+        goto Bail;+      }++      if ( FT_STRDUP( properties[i].name, strings + name_offset ) )+        goto Bail;++      FT_TRACE4(( "  %s:", properties[i].name ));++      properties[i].isString = props[i].isString;++      if ( props[i].isString )+      {+        FT_Long  value_offset = props[i].value;+++        if ( ( value_offset < 0 )                     ||+             ( (FT_ULong)value_offset > string_size ) )+        {+          error = PCF_Err_Invalid_Offset;+          goto Bail;+        }++        if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) )+          goto Bail;++        FT_TRACE4(( " `%s'\n", properties[i].value.atom ));+      }+      else+      {+        properties[i].value.l = props[i].value;++        FT_TRACE4(( " %d\n", properties[i].value.l ));+      }+    }++    error = PCF_Err_Ok;++  Bail:+    FT_FREE( props );+    FT_FREE( strings );++    return error;+  }+++  static FT_Error+  pcf_get_metrics( FT_Stream  stream,+                   PCF_Face   face )+  {+    FT_Error    error    = PCF_Err_Ok;+    FT_Memory   memory   = FT_FACE(face)->memory;+    FT_ULong    format, size;+    PCF_Metric  metrics  = 0;+    FT_ULong    nmetrics, i;+++    error = pcf_seek_to_table_type( stream,+                                    face->toc.tables,+                                    face->toc.count,+                                    PCF_METRICS,+                                    &format,+                                    &size );+    if ( error )+      return error;++    if ( FT_READ_ULONG_LE( format ) )+      goto Bail;++    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )     &&+         !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )+      return PCF_Err_Invalid_File_Format;++    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+        (void)FT_READ_ULONG( nmetrics );+      else+        (void)FT_READ_ULONG_LE( nmetrics );+    }+    else+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+        (void)FT_READ_USHORT( nmetrics );+      else+        (void)FT_READ_USHORT_LE( nmetrics );+    }+    if ( error )+      return PCF_Err_Invalid_File_Format;++    face->nmetrics = nmetrics;++    if ( !nmetrics )+      return PCF_Err_Invalid_Table;++    FT_TRACE4(( "pcf_get_metrics:\n" ));++    FT_TRACE4(( "  number of metrics: %d\n", nmetrics ));++    /* rough estimate */+    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+    {+      if ( nmetrics > size / PCF_METRIC_SIZE )+        return PCF_Err_Invalid_Table;+    }+    else+    {+      if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )+        return PCF_Err_Invalid_Table;+    }++    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )+      return PCF_Err_Out_Of_Memory;++    metrics = face->metrics;+    for ( i = 0; i < nmetrics; i++ )+    {+      error = pcf_get_metric( stream, format, metrics + i );++      metrics[i].bits = 0;++      FT_TRACE5(( "  idx %d: width=%d, "+                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",+                  i,+                  ( metrics + i )->characterWidth,+                  ( metrics + i )->leftSideBearing,+                  ( metrics + i )->rightSideBearing,+                  ( metrics + i )->ascent,+                  ( metrics + i )->descent,+                  ( metrics + i )->attributes ));++      if ( error )+        break;+    }++    if ( error )+      FT_FREE( face->metrics );++  Bail:+    return error;+  }+++  static FT_Error+  pcf_get_bitmaps( FT_Stream  stream,+                   PCF_Face   face )+  {+    FT_Error   error  = PCF_Err_Ok;+    FT_Memory  memory = FT_FACE(face)->memory;+    FT_Long*   offsets;+    FT_Long    bitmapSizes[GLYPHPADOPTIONS];+    FT_ULong   format, size;+    FT_ULong   nbitmaps, i, sizebitmaps = 0;+++    error = pcf_seek_to_table_type( stream,+                                    face->toc.tables,+                                    face->toc.count,+                                    PCF_BITMAPS,+                                    &format,+                                    &size );+    if ( error )+      return error;++    error = FT_Stream_EnterFrame( stream, 8 );+    if ( error )+      return error;++    format = FT_GET_ULONG_LE();+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )+      nbitmaps  = FT_GET_ULONG();+    else+      nbitmaps  = FT_GET_ULONG_LE();++    FT_Stream_ExitFrame( stream );++    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+      return PCF_Err_Invalid_File_Format;++    FT_TRACE4(( "pcf_get_bitmaps:\n" ));++    FT_TRACE4(( "  number of bitmaps: %d\n", nbitmaps ));++    /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */+    if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics )+      return PCF_Err_Invalid_File_Format;++    if ( FT_NEW_ARRAY( offsets, nbitmaps ) )+      return error;++    for ( i = 0; i < nbitmaps; i++ )+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+        (void)FT_READ_LONG( offsets[i] );+      else+        (void)FT_READ_LONG_LE( offsets[i] );++      FT_TRACE5(( "  bitmap %d: offset %ld (0x%lX)\n",+                  i, offsets[i], offsets[i] ));+    }+    if ( error )+      goto Bail;++    for ( i = 0; i < GLYPHPADOPTIONS; i++ )+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+        (void)FT_READ_LONG( bitmapSizes[i] );+      else+        (void)FT_READ_LONG_LE( bitmapSizes[i] );+      if ( error )+        goto Bail;++      sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];++      FT_TRACE4(( "  padding %d implies a size of %ld\n", i, bitmapSizes[i] ));+    }++    FT_TRACE4(( "  %d bitmaps, padding index %ld\n",+                nbitmaps,+                PCF_GLYPH_PAD_INDEX( format ) ));+    FT_TRACE4(( "  bitmap size = %d\n", sizebitmaps ));++    FT_UNUSED( sizebitmaps );       /* only used for debugging */++    for ( i = 0; i < nbitmaps; i++ )+    {+      /* rough estimate */+      if ( ( offsets[i] < 0 )              ||+           ( (FT_ULong)offsets[i] > size ) )+      {+        FT_TRACE0(( "pcf_get_bitmaps:"+                    " invalid offset to bitmap data of glyph %d\n", i ));+      }+      else+        face->metrics[i].bits = stream->pos + offsets[i];+    }++    face->bitmapsFormat = format;++  Bail:+    FT_FREE( offsets );+    return error;+  }+++  static FT_Error+  pcf_get_encodings( FT_Stream  stream,+                     PCF_Face   face )+  {+    FT_Error      error  = PCF_Err_Ok;+    FT_Memory     memory = FT_FACE(face)->memory;+    FT_ULong      format, size;+    int           firstCol, lastCol;+    int           firstRow, lastRow;+    int           nencoding, encodingOffset;+    int           i, j;+    PCF_Encoding  tmpEncoding, encoding = 0;+++    error = pcf_seek_to_table_type( stream,+                                    face->toc.tables,+                                    face->toc.count,+                                    PCF_BDF_ENCODINGS,+                                    &format,+                                    &size );+    if ( error )+      return error;++    error = FT_Stream_EnterFrame( stream, 14 );+    if ( error )+      return error;++    format = FT_GET_ULONG_LE();++    if ( PCF_BYTE_ORDER( format ) == MSBFirst )+    {+      firstCol          = FT_GET_SHORT();+      lastCol           = FT_GET_SHORT();+      firstRow          = FT_GET_SHORT();+      lastRow           = FT_GET_SHORT();+      face->defaultChar = FT_GET_SHORT();+    }+    else+    {+      firstCol          = FT_GET_SHORT_LE();+      lastCol           = FT_GET_SHORT_LE();+      firstRow          = FT_GET_SHORT_LE();+      lastRow           = FT_GET_SHORT_LE();+      face->defaultChar = FT_GET_SHORT_LE();+    }++    FT_Stream_ExitFrame( stream );++    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )+      return PCF_Err_Invalid_File_Format;++    FT_TRACE4(( "pdf_get_encodings:\n" ));++    FT_TRACE4(( "  firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",+                firstCol, lastCol, firstRow, lastRow ));++    nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );++    if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) )+      return PCF_Err_Out_Of_Memory;++    error = FT_Stream_EnterFrame( stream, 2 * nencoding );+    if ( error )+      goto Bail;++    for ( i = 0, j = 0 ; i < nencoding; i++ )+    {+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )+        encodingOffset = FT_GET_SHORT();+      else+        encodingOffset = FT_GET_SHORT_LE();++      if ( encodingOffset != -1 )+      {+        tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) ++                                 firstRow ) * 256 ) ++                               ( ( i % ( lastCol - firstCol + 1 ) ) ++                                 firstCol );++        tmpEncoding[j].glyph = (FT_Short)encodingOffset;++        FT_TRACE5(( "  code %d (0x%04X): idx %d\n",+                    tmpEncoding[j].enc, tmpEncoding[j].enc,+                    tmpEncoding[j].glyph ));++        j++;+      }+    }+    FT_Stream_ExitFrame( stream );++    if ( FT_NEW_ARRAY( encoding, j ) )+      goto Bail;++    for ( i = 0; i < j; i++ )+    {+      encoding[i].enc   = tmpEncoding[i].enc;+      encoding[i].glyph = tmpEncoding[i].glyph;+    }++    face->nencodings = j;+    face->encodings  = encoding;+    FT_FREE( tmpEncoding );++    return error;++  Bail:+    FT_FREE( encoding );+    FT_FREE( tmpEncoding );+    return error;+  }+++  static+  const FT_Frame_Field  pcf_accel_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_AccelRec++    FT_FRAME_START( 20 ),+      FT_FRAME_BYTE      ( noOverlap ),+      FT_FRAME_BYTE      ( constantMetrics ),+      FT_FRAME_BYTE      ( terminalFont ),+      FT_FRAME_BYTE      ( constantWidth ),+      FT_FRAME_BYTE      ( inkInside ),+      FT_FRAME_BYTE      ( inkMetrics ),+      FT_FRAME_BYTE      ( drawDirection ),+      FT_FRAME_SKIP_BYTES( 1 ),+      FT_FRAME_LONG_LE   ( fontAscent ),+      FT_FRAME_LONG_LE   ( fontDescent ),+      FT_FRAME_LONG_LE   ( maxOverlap ),+    FT_FRAME_END+  };+++  static+  const FT_Frame_Field  pcf_accel_msb_header[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PCF_AccelRec++    FT_FRAME_START( 20 ),+      FT_FRAME_BYTE      ( noOverlap ),+      FT_FRAME_BYTE      ( constantMetrics ),+      FT_FRAME_BYTE      ( terminalFont ),+      FT_FRAME_BYTE      ( constantWidth ),+      FT_FRAME_BYTE      ( inkInside ),+      FT_FRAME_BYTE      ( inkMetrics ),+      FT_FRAME_BYTE      ( drawDirection ),+      FT_FRAME_SKIP_BYTES( 1 ),+      FT_FRAME_LONG      ( fontAscent ),+      FT_FRAME_LONG      ( fontDescent ),+      FT_FRAME_LONG      ( maxOverlap ),+    FT_FRAME_END+  };+++  static FT_Error+  pcf_get_accel( FT_Stream  stream,+                 PCF_Face   face,+                 FT_ULong   type )+  {+    FT_ULong   format, size;+    FT_Error   error = PCF_Err_Ok;+    PCF_Accel  accel = &face->accel;+++    error = pcf_seek_to_table_type( stream,+                                    face->toc.tables,+                                    face->toc.count,+                                    type,+                                    &format,+                                    &size );+    if ( error )+      goto Bail;++    if ( FT_READ_ULONG_LE( format ) )+      goto Bail;++    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )    &&+         !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )+      goto Bail;++    if ( PCF_BYTE_ORDER( format ) == MSBFirst )+    {+      if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) )+        goto Bail;+    }+    else+    {+      if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) )+        goto Bail;+    }++    error = pcf_get_metric( stream,+                            format & ( ~PCF_FORMAT_MASK ),+                            &(accel->minbounds) );+    if ( error )+      goto Bail;++    error = pcf_get_metric( stream,+                            format & ( ~PCF_FORMAT_MASK ),+                            &(accel->maxbounds) );+    if ( error )+      goto Bail;++    if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )+    {+      error = pcf_get_metric( stream,+                              format & ( ~PCF_FORMAT_MASK ),+                              &(accel->ink_minbounds) );+      if ( error )+        goto Bail;++      error = pcf_get_metric( stream,+                              format & ( ~PCF_FORMAT_MASK ),+                              &(accel->ink_maxbounds) );+      if ( error )+        goto Bail;+    }+    else+    {+      accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */+      accel->ink_maxbounds = accel->maxbounds;+    }++  Bail:+    return error;+  }+++  static FT_Error+  pcf_interpret_style( PCF_Face  pcf )+  {+    FT_Error   error  = PCF_Err_Ok;+    FT_Face    face   = FT_FACE( pcf );+    FT_Memory  memory = face->memory;++    PCF_Property  prop;++    size_t  nn, len;+    char*   strings[4] = { NULL, NULL, NULL, NULL };+    size_t  lengths[4];+++    face->style_flags = 0;++    prop = pcf_find_property( pcf, "SLANT" );+    if ( prop && prop->isString                                       &&+         ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||+           *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )+    {+      face->style_flags |= FT_STYLE_FLAG_ITALIC;+      strings[2] = ( *(prop->value.atom) == 'O' ||+                     *(prop->value.atom) == 'o' ) ? (char *)"Oblique"+                                                  : (char *)"Italic";+    }++    prop = pcf_find_property( pcf, "WEIGHT_NAME" );+    if ( prop && prop->isString                                       &&+         ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )+    {+      face->style_flags |= FT_STYLE_FLAG_BOLD;+      strings[1] = (char *)"Bold";+    }++    prop = pcf_find_property( pcf, "SETWIDTH_NAME" );+    if ( prop && prop->isString                                        &&+         *(prop->value.atom)                                           &&+         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )+      strings[3] = (char *)(prop->value.atom);++    prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );+    if ( prop && prop->isString                                        &&+         *(prop->value.atom)                                           &&+         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )+      strings[0] = (char *)(prop->value.atom);++    for ( len = 0, nn = 0; nn < 4; nn++ )+    {+      lengths[nn] = 0;+      if ( strings[nn] )+      {+        lengths[nn] = ft_strlen( strings[nn] );+        len        += lengths[nn] + 1;+      }+    }++    if ( len == 0 )+    {+      strings[0] = (char *)"Regular";+      lengths[0] = ft_strlen( strings[0] );+      len        = lengths[0] + 1;+    }++    {+      char*  s;+++      if ( FT_ALLOC( face->style_name, len ) )+        return error;++      s = face->style_name;++      for ( nn = 0; nn < 4; nn++ )+      {+        char*  src = strings[nn];+++        len = lengths[nn];++        if ( src == NULL )+          continue;++        /* separate elements with a space */+        if ( s != face->style_name )+          *s++ = ' ';++        ft_memcpy( s, src, len );++        /* need to convert spaces to dashes for */+        /* add_style_name and setwidth_name     */+        if ( nn == 0 || nn == 3 )+        {+          size_t  mm;+++          for ( mm = 0; mm < len; mm++ )+            if (s[mm] == ' ')+              s[mm] = '-';+        }++        s += len;+      }+      *s = 0;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  pcf_load_font( FT_Stream  stream,+                 PCF_Face   face )+  {+    FT_Error   error  = PCF_Err_Ok;+    FT_Memory  memory = FT_FACE(face)->memory;+    FT_Bool    hasBDFAccelerators;+++    error = pcf_read_TOC( stream, face );+    if ( error )+      goto Exit;++    error = pcf_get_properties( stream, face );+    if ( error )+      goto Exit;++    /* Use the old accelerators if no BDF accelerators are in the file. */+    hasBDFAccelerators = pcf_has_table_type( face->toc.tables,+                                             face->toc.count,+                                             PCF_BDF_ACCELERATORS );+    if ( !hasBDFAccelerators )+    {+      error = pcf_get_accel( stream, face, PCF_ACCELERATORS );+      if ( error )+        goto Exit;+    }++    /* metrics */+    error = pcf_get_metrics( stream, face );+    if ( error )+      goto Exit;++    /* bitmaps */+    error = pcf_get_bitmaps( stream, face );+    if ( error )+      goto Exit;++    /* encodings */+    error = pcf_get_encodings( stream, face );+    if ( error )+      goto Exit;++    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */+    if ( hasBDFAccelerators )+    {+      error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );+      if ( error )+        goto Exit;+    }++    /* XXX: TO DO: inkmetrics and glyph_names are missing */++    /* now construct the face object */+    {+      FT_Face       root = FT_FACE( face );+      PCF_Property  prop;+++      root->num_faces  = 1;+      root->face_index = 0;+      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |+                         FT_FACE_FLAG_HORIZONTAL  |+                         FT_FACE_FLAG_FAST_GLYPHS;++      if ( face->accel.constantWidth )+        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      if ( ( error = pcf_interpret_style( face ) ) != 0 )+         goto Exit;++      prop = pcf_find_property( face, "FAMILY_NAME" );+      if ( prop && prop->isString )+      {+        if ( FT_STRDUP( root->family_name, prop->value.atom ) )+          goto Exit;+      }+      else+        root->family_name = NULL;++      /*+       * Note: We shift all glyph indices by +1 since we must+       * respect the convention that glyph 0 always corresponds+       * to the `missing glyph'.+       *+       * This implies bumping the number of `available' glyphs by 1.+       */+      root->num_glyphs = face->nmetrics + 1;++      root->num_fixed_sizes = 1;+      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )+        goto Exit;++      {+        FT_Bitmap_Size*  bsize = root->available_sizes;+        FT_Short         resolution_x = 0, resolution_y = 0;+++        FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );++#if 0+        bsize->height = face->accel.maxbounds.ascent << 6;+#endif+        bsize->height = (FT_Short)( face->accel.fontAscent ++                                    face->accel.fontDescent );++        prop = pcf_find_property( face, "AVERAGE_WIDTH" );+        if ( prop )+          bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 );+        else+          bsize->width = (FT_Short)( bsize->height * 2/3 );++        prop = pcf_find_property( face, "POINT_SIZE" );+        if ( prop )+          /* convert from 722.7 decipoints to 72 points per inch */+          bsize->size =+            (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L );++        prop = pcf_find_property( face, "PIXEL_SIZE" );+        if ( prop )+          bsize->y_ppem = (FT_Short)prop->value.l << 6;++        prop = pcf_find_property( face, "RESOLUTION_X" );+        if ( prop )+          resolution_x = (FT_Short)prop->value.l;++        prop = pcf_find_property( face, "RESOLUTION_Y" );+        if ( prop )+          resolution_y = (FT_Short)prop->value.l;++        if ( bsize->y_ppem == 0 )+        {+          bsize->y_ppem = bsize->size;+          if ( resolution_y )+            bsize->y_ppem = bsize->y_ppem * resolution_y / 72;+        }+        if ( resolution_x && resolution_y )+          bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;+        else+          bsize->x_ppem = bsize->y_ppem;+      }++      /* set up charset */+      {+        PCF_Property  charset_registry = 0, charset_encoding = 0;+++        charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );+        charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );++        if ( charset_registry && charset_registry->isString &&+             charset_encoding && charset_encoding->isString )+        {+          if ( FT_STRDUP( face->charset_encoding,+                          charset_encoding->value.atom ) ||+               FT_STRDUP( face->charset_registry,+                          charset_registry->value.atom ) )+            goto Exit;+        }+      }+    }++  Exit:+    if ( error )+    {+      /* This is done to respect the behaviour of the original */+      /* PCF font driver.                                      */+      error = PCF_Err_Invalid_File_Format;+    }++    return error;+  }+++/* END */
+ src/pcf/pcfread.h view
@@ -0,0 +1,45 @@+/*  pcfread.h++    FreeType font driver for pcf fonts++  Copyright 2003 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __PCFREAD_H__+#define __PCFREAD_H__+++#include <ft2build.h>++FT_BEGIN_HEADER++  FT_LOCAL( PCF_Property )+  pcf_find_property( PCF_Face          face,+                     const FT_String*  prop );++FT_END_HEADER++#endif /* __PCFREAD_H__ */+++/* END */
+ src/pcf/pcfutil.c view
@@ -0,0 +1,104 @@+/*++Copyright 1990, 1994, 1998  The Open Group++Permission to use, copy, modify, distribute, and sell this software and its+documentation for any purpose is hereby granted without fee, provided that+the above copyright notice appear in all copies and that both that+copyright notice and this permission notice appear in supporting+documentation.++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.++Except as contained in this notice, the name of The Open Group shall not be+used in advertising or otherwise to promote the sale, use or other dealings+in this Software without prior written authorization from The Open Group.++*/+/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */++/*+ * Author:  Keith Packard, MIT X Consortium+ */++/* Modified for use with FreeType */+++#include <ft2build.h>+#include "pcfutil.h"+++  /*+   *  Invert bit order within each BYTE of an array.+   */++  FT_LOCAL_DEF( void )+  BitOrderInvert( unsigned char*  buf,+                  size_t          nbytes )+  {+    for ( ; nbytes > 0; nbytes--, buf++ )+    {+      unsigned int  val = *buf;+++      val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA );+      val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC );+      val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 );++      *buf = (unsigned char)val;+    }+  }+++  /*+   *  Invert byte order within each 16-bits of an array.+   */++  FT_LOCAL_DEF( void )+  TwoByteSwap( unsigned char*  buf,+               size_t          nbytes )+  {+    unsigned char  c;+++    for ( ; nbytes >= 2; nbytes -= 2, buf += 2 )+    {+      c      = buf[0];+      buf[0] = buf[1];+      buf[1] = c;+    }+  }++  /*+   *  Invert byte order within each 32-bits of an array.+   */++  FT_LOCAL_DEF( void )+  FourByteSwap( unsigned char*  buf,+                size_t          nbytes )+  {+    unsigned char  c;+++    for ( ; nbytes >= 4; nbytes -= 4, buf += 4 )+    {+      c      = buf[0];+      buf[0] = buf[3];+      buf[3] = c;++      c      = buf[1];+      buf[1] = buf[2];+      buf[2] = c;+    }+  }+++/* END */
+ src/pcf/pcfutil.h view
@@ -0,0 +1,55 @@+/*  pcfutil.h++    FreeType font driver for pcf fonts++  Copyright 2000, 2001, 2004 by+  Francesco Zappa Nardelli++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+*/+++#ifndef __PCFUTIL_H__+#define __PCFUTIL_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+++FT_BEGIN_HEADER++  FT_LOCAL( void )+  BitOrderInvert( unsigned char*  buf,+                  size_t          nbytes );++  FT_LOCAL( void )+  TwoByteSwap( unsigned char*  buf,+               size_t          nbytes );++  FT_LOCAL( void )+  FourByteSwap( unsigned char*  buf,+                size_t          nbytes );++FT_END_HEADER++#endif /* __PCFUTIL_H__ */+++/* END */
+ src/pfr/pfr.c view
@@ -0,0 +1,29 @@+/***************************************************************************/+/*                                                                         */+/*  pfr.c                                                                  */+/*                                                                         */+/*    FreeType PFR driver component.                                       */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>++#include "pfrload.c"+#include "pfrgload.c"+#include "pfrcmap.c"+#include "pfrobjs.c"+#include "pfrdrivr.c"+#include "pfrsbit.c"++/* END */
+ src/pfr/pfrcmap.c view
@@ -0,0 +1,166 @@+/***************************************************************************/+/*                                                                         */+/*  pfrcmap.c                                                              */+/*                                                                         */+/*    FreeType PFR cmap handling (body).                                   */+/*                                                                         */+/*  Copyright 2002, 2007, 2009 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "pfrcmap.h"+#include "pfrobjs.h"++#include "pfrerror.h"+++  FT_CALLBACK_DEF( FT_Error )+  pfr_cmap_init( PFR_CMap  cmap )+  {+    FT_Error  error = PFR_Err_Ok;+    PFR_Face  face  = (PFR_Face)FT_CMAP_FACE( cmap );+++    cmap->num_chars = face->phy_font.num_chars;+    cmap->chars     = face->phy_font.chars;++    /* just for safety, check that the character entries are correctly */+    /* sorted in increasing character code order                       */+    {+      FT_UInt  n;+++      for ( n = 1; n < cmap->num_chars; n++ )+      {+        if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )+        {+          error = PFR_Err_Invalid_Table;+          goto Exit;+        }+      }+    }++  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( void )+  pfr_cmap_done( PFR_CMap  cmap )+  {+    cmap->chars     = NULL;+    cmap->num_chars = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  pfr_cmap_char_index( PFR_CMap   cmap,+                       FT_UInt32  char_code )+  {+    FT_UInt   min = 0;+    FT_UInt   max = cmap->num_chars;+    FT_UInt   mid;+    PFR_Char  gchar;+++    while ( min < max )+    {+      mid   = min + ( max - min ) / 2;+      gchar = cmap->chars + mid;++      if ( gchar->char_code == char_code )+        return mid + 1;++      if ( gchar->char_code < char_code )+        min = mid + 1;+      else+        max = mid;+    }+    return 0;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  pfr_cmap_char_next( PFR_CMap    cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_UInt    result    = 0;+    FT_UInt32  char_code = *pchar_code + 1;+++  Restart:+    {+      FT_UInt   min = 0;+      FT_UInt   max = cmap->num_chars;+      FT_UInt   mid;+      PFR_Char  gchar;+++      while ( min < max )+      {+        mid   = min + ( ( max - min ) >> 1 );+        gchar = cmap->chars + mid;++        if ( gchar->char_code == char_code )+        {+          result = mid;+          if ( result != 0 )+          {+            result++;+            goto Exit;+          }++          char_code++;+          goto Restart;+        }++        if ( gchar->char_code < char_code )+          min = mid+1;+        else+          max = mid;+      }++      /* we didn't find it, but we have a pair just above it */+      char_code = 0;++      if ( min < cmap->num_chars )+      {+        gchar  = cmap->chars + min;+        result = min;+        if ( result != 0 )+        {+          result++;+          char_code = gchar->char_code;+        }+      }+    }++  Exit:+    *pchar_code = char_code;+    return result;+  }+++  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec+  pfr_cmap_class_rec =+  {+    sizeof ( PFR_CMapRec ),++    (FT_CMap_InitFunc)     pfr_cmap_init,+    (FT_CMap_DoneFunc)     pfr_cmap_done,+    (FT_CMap_CharIndexFunc)pfr_cmap_char_index,+    (FT_CMap_CharNextFunc) pfr_cmap_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++/* END */
+ src/pfr/pfrcmap.h view
@@ -0,0 +1,46 @@+/***************************************************************************/+/*                                                                         */+/*  pfrcmap.h                                                              */+/*                                                                         */+/*    FreeType PFR cmap handling (specification).                          */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRCMAP_H__+#define __PFRCMAP_H__++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include "pfrtypes.h"+++FT_BEGIN_HEADER++  typedef struct  PFR_CMapRec_+  {+    FT_CMapRec  cmap;+    FT_UInt     num_chars;+    PFR_Char    chars;++  } PFR_CMapRec, *PFR_CMap;+++  FT_CALLBACK_TABLE const FT_CMap_ClassRec  pfr_cmap_class_rec;++FT_END_HEADER+++#endif /* __PFRCMAP_H__ */+++/* END */
+ src/pfr/pfrdrivr.c view
@@ -0,0 +1,214 @@+/***************************************************************************/+/*                                                                         */+/*  pfrdrivr.c                                                             */+/*                                                                         */+/*    FreeType PFR driver interface (body).                                */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006, 2008, 2010 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_SERVICE_PFR_H+#include FT_SERVICE_XFREE86_NAME_H+#include "pfrdrivr.h"+#include "pfrobjs.h"++#include "pfrerror.h"+++  FT_CALLBACK_DEF( FT_Error )+  pfr_get_kerning( FT_Face     pfrface,     /* PFR_Face */+                   FT_UInt     left,+                   FT_UInt     right,+                   FT_Vector  *avector )+  {+    PFR_Face     face = (PFR_Face)pfrface;+    PFR_PhyFont  phys = &face->phy_font;+++    pfr_face_get_kerning( pfrface, left, right, avector );++    /* convert from metrics to outline units when necessary */+    if ( phys->outline_resolution != phys->metrics_resolution )+    {+      if ( avector->x != 0 )+        avector->x = FT_MulDiv( avector->x, phys->outline_resolution,+                                            phys->metrics_resolution );++      if ( avector->y != 0 )+        avector->y = FT_MulDiv( avector->x, phys->outline_resolution,+                                            phys->metrics_resolution );+    }++    return PFR_Err_Ok;+  }+++ /*+  *  PFR METRICS SERVICE+  *+  */++  FT_CALLBACK_DEF( FT_Error )+  pfr_get_advance( FT_Face   pfrface,       /* PFR_Face */+                   FT_UInt   gindex,+                   FT_Pos   *anadvance )+  {+    PFR_Face  face  = (PFR_Face)pfrface;+    FT_Error  error = PFR_Err_Invalid_Argument;+++    *anadvance = 0;++    if ( !gindex )+      goto Exit;++    gindex--;++    if ( face )+    {+      PFR_PhyFont  phys = &face->phy_font;+++      if ( gindex < phys->num_chars )+      {+        *anadvance = phys->chars[gindex].advance;+        error = PFR_Err_Ok;+      }+    }++  Exit:+    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  pfr_get_metrics( FT_Face    pfrface,      /* PFR_Face */+                   FT_UInt   *anoutline_resolution,+                   FT_UInt   *ametrics_resolution,+                   FT_Fixed  *ametrics_x_scale,+                   FT_Fixed  *ametrics_y_scale )+  {+    PFR_Face     face = (PFR_Face)pfrface;+    PFR_PhyFont  phys = &face->phy_font;+    FT_Fixed     x_scale, y_scale;+    FT_Size      size = face->root.size;+++    if ( anoutline_resolution )+      *anoutline_resolution = phys->outline_resolution;++    if ( ametrics_resolution )+      *ametrics_resolution = phys->metrics_resolution;++    x_scale = 0x10000L;+    y_scale = 0x10000L;++    if ( size )+    {+      x_scale = FT_DivFix( size->metrics.x_ppem << 6,+                           phys->metrics_resolution );++      y_scale = FT_DivFix( size->metrics.y_ppem << 6,+                           phys->metrics_resolution );+    }++    if ( ametrics_x_scale )+      *ametrics_x_scale = x_scale;++    if ( ametrics_y_scale )+      *ametrics_y_scale = y_scale;++    return PFR_Err_Ok;+  }+++  FT_CALLBACK_TABLE_DEF+  const FT_Service_PfrMetricsRec  pfr_metrics_service_rec =+  {+    pfr_get_metrics,+    pfr_face_get_kerning,+    pfr_get_advance+  };+++ /*+  *  SERVICE LIST+  *+  */++  static const FT_ServiceDescRec  pfr_services[] =+  {+    { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec },+    { FT_SERVICE_ID_XF86_NAME,   FT_XF86_FORMAT_PFR },+    { NULL, NULL }+  };+++  FT_CALLBACK_DEF( FT_Module_Interface )+  pfr_get_service( FT_Module         module,+                   const FT_String*  service_id )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( pfr_services, service_id );+  }+++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  pfr_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER     |+      FT_MODULE_DRIVER_SCALABLE,++      sizeof( FT_DriverRec ),++      "pfr",+      0x10000L,+      0x20000L,++      NULL,++      0,+      0,+      pfr_get_service+    },++    sizeof( PFR_FaceRec ),+    sizeof( PFR_SizeRec ),+    sizeof( PFR_SlotRec ),++    pfr_face_init,+    pfr_face_done,+    0,                  /* FT_Size_InitFunc */+    0,                  /* FT_Size_DoneFunc */+    pfr_slot_init,+    pfr_slot_done,++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    pfr_slot_load,++    pfr_get_kerning,+    0,                  /* FT_Face_AttachFunc      */+    0,                   /* FT_Face_GetAdvancesFunc */+    0,                  /* FT_Size_RequestFunc */+    0,                  /* FT_Size_SelectFunc  */+  };+++/* END */
+ src/pfr/pfrdrivr.h view
@@ -0,0 +1,43 @@+/***************************************************************************/+/*                                                                         */+/*  pfrdrivr.h                                                             */+/*                                                                         */+/*    High-level Type PFR driver interface (specification).                */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRDRIVR_H__+#define __PFRDRIVR_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  pfr_driver_class;+++FT_END_HEADER+++#endif /* __PFRDRIVR_H__ */+++/* END */
+ src/pfr/pfrerror.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  pfrerror.h                                                             */+/*                                                                         */+/*    PFR error codes (specification only).                                */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the PFR error enumeration constants.      */+  /*                                                                       */+  /*************************************************************************/++#ifndef __PFRERROR_H__+#define __PFRERROR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  PFR_Err_+#define FT_ERR_BASE    FT_Mod_Err_PFR++#include FT_ERRORS_H++#endif /* __PFRERROR_H__ */+++/* END */
+ src/pfr/pfrgload.c view
@@ -0,0 +1,844 @@+/***************************************************************************/+/*                                                                         */+/*  pfrgload.c                                                             */+/*                                                                         */+/*    FreeType PFR glyph loader (body).                                    */+/*                                                                         */+/*  Copyright 2002, 2003, 2005, 2007, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "pfrgload.h"+#include "pfrsbit.h"+#include "pfrload.h"            /* for macro definitions */+#include FT_INTERNAL_DEBUG_H++#include "pfrerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pfr+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      PFR GLYPH BUILDER                        *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( void )+  pfr_glyph_init( PFR_Glyph       glyph,+                  FT_GlyphLoader  loader )+  {+    FT_ZERO( glyph );++    glyph->loader     = loader;+    glyph->path_begun = 0;++    FT_GlyphLoader_Rewind( loader );+  }+++  FT_LOCAL_DEF( void )+  pfr_glyph_done( PFR_Glyph  glyph )+  {+    FT_Memory  memory = glyph->loader->memory;+++    FT_FREE( glyph->x_control );+    glyph->y_control = NULL;++    glyph->max_xy_control = 0;+#if 0+    glyph->num_x_control  = 0;+    glyph->num_y_control  = 0;+#endif++    FT_FREE( glyph->subs );++    glyph->max_subs = 0;+    glyph->num_subs = 0;++    glyph->loader     = NULL;+    glyph->path_begun = 0;+  }+++  /* close current contour, if any */+  static void+  pfr_glyph_close_contour( PFR_Glyph  glyph )+  {+    FT_GlyphLoader  loader  = glyph->loader;+    FT_Outline*     outline = &loader->current.outline;+    FT_Int          last, first;+++    if ( !glyph->path_begun )+      return;++    /* compute first and last point indices in current glyph outline */+    last  = outline->n_points - 1;+    first = 0;+    if ( outline->n_contours > 0 )+      first = outline->contours[outline->n_contours - 1];++    /* if the last point falls on the same location than the first one */+    /* we need to delete it                                            */+    if ( last > first )+    {+      FT_Vector*  p1 = outline->points + first;+      FT_Vector*  p2 = outline->points + last;+++      if ( p1->x == p2->x && p1->y == p2->y )+      {+        outline->n_points--;+        last--;+      }+    }++    /* don't add empty contours */+    if ( last >= first )+      outline->contours[outline->n_contours++] = (short)last;++    glyph->path_begun = 0;+  }+++  /* reset glyph to start the loading of a new glyph */+  static void+  pfr_glyph_start( PFR_Glyph  glyph )+  {+    glyph->path_begun = 0;+  }+++  static FT_Error+  pfr_glyph_line_to( PFR_Glyph   glyph,+                     FT_Vector*  to )+  {+    FT_GlyphLoader  loader  = glyph->loader;+    FT_Outline*     outline = &loader->current.outline;+    FT_Error        error;+++    /* check that we have begun a new path */+    if ( !glyph->path_begun )+    {+      error = PFR_Err_Invalid_Table;+      FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));+      goto Exit;+    }++    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );+    if ( !error )+    {+      FT_UInt  n = outline->n_points;+++      outline->points[n] = *to;+      outline->tags  [n] = FT_CURVE_TAG_ON;++      outline->n_points++;+    }++  Exit:+    return error;+  }+++  static FT_Error+  pfr_glyph_curve_to( PFR_Glyph   glyph,+                      FT_Vector*  control1,+                      FT_Vector*  control2,+                      FT_Vector*  to )+  {+    FT_GlyphLoader  loader  = glyph->loader;+    FT_Outline*     outline = &loader->current.outline;+    FT_Error        error;+++    /* check that we have begun a new path */+    if ( !glyph->path_begun )+    {+      error = PFR_Err_Invalid_Table;+      FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));+      goto Exit;+    }++    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );+    if ( !error )+    {+      FT_Vector*  vec = outline->points         + outline->n_points;+      FT_Byte*    tag = (FT_Byte*)outline->tags + outline->n_points;+++      vec[0] = *control1;+      vec[1] = *control2;+      vec[2] = *to;+      tag[0] = FT_CURVE_TAG_CUBIC;+      tag[1] = FT_CURVE_TAG_CUBIC;+      tag[2] = FT_CURVE_TAG_ON;++      outline->n_points = (FT_Short)( outline->n_points + 3 );+    }++  Exit:+    return error;+  }+++  static FT_Error+  pfr_glyph_move_to( PFR_Glyph   glyph,+                     FT_Vector*  to )+  {+    FT_GlyphLoader  loader  = glyph->loader;+    FT_Error        error;+++    /* close current contour if any */+    pfr_glyph_close_contour( glyph );++    /* indicate that a new contour has started */+    glyph->path_begun = 1;++    /* check that there is space for a new contour and a new point */+    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 );+    if ( !error )+      /* add new start point */+      error = pfr_glyph_line_to( glyph, to );++    return error;+  }+++  static void+  pfr_glyph_end( PFR_Glyph  glyph )+  {+    /* close current contour if any */+    pfr_glyph_close_contour( glyph );++    /* merge the current glyph into the stack */+    FT_GlyphLoader_Add( glyph->loader );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      PFR GLYPH LOADER                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* load a simple glyph */+  static FT_Error+  pfr_glyph_load_simple( PFR_Glyph  glyph,+                         FT_Byte*   p,+                         FT_Byte*   limit )+  {+    FT_Error   error  = PFR_Err_Ok;+    FT_Memory  memory = glyph->loader->memory;+    FT_UInt    flags, x_count, y_count, i, count, mask;+    FT_Int     x;+++    PFR_CHECK( 1 );+    flags = PFR_NEXT_BYTE( p );++    /* test for composite glyphs */+    if ( flags & PFR_GLYPH_IS_COMPOUND )+      goto Failure;++    x_count = 0;+    y_count = 0;++    if ( flags & PFR_GLYPH_1BYTE_XYCOUNT )+    {+      PFR_CHECK( 1 );+      count   = PFR_NEXT_BYTE( p );+      x_count = count & 15;+      y_count = count >> 4;+    }+    else+    {+      if ( flags & PFR_GLYPH_XCOUNT )+      {+        PFR_CHECK( 1 );+        x_count = PFR_NEXT_BYTE( p );+      }++      if ( flags & PFR_GLYPH_YCOUNT )+      {+        PFR_CHECK( 1 );+        y_count = PFR_NEXT_BYTE( p );+      }+    }++    count = x_count + y_count;++    /* re-allocate array when necessary */+    if ( count > glyph->max_xy_control )+    {+      FT_UInt  new_max = FT_PAD_CEIL( count, 8 );+++      if ( FT_RENEW_ARRAY( glyph->x_control,+                           glyph->max_xy_control,+                           new_max ) )+        goto Exit;++      glyph->max_xy_control = new_max;+    }++    glyph->y_control = glyph->x_control + x_count;++    mask  = 0;+    x     = 0;++    for ( i = 0; i < count; i++ )+    {+      if ( ( i & 7 ) == 0 )+      {+        PFR_CHECK( 1 );+        mask = PFR_NEXT_BYTE( p );+      }++      if ( mask & 1 )+      {+        PFR_CHECK( 2 );+        x = PFR_NEXT_SHORT( p );+      }+      else+      {+        PFR_CHECK( 1 );+        x += PFR_NEXT_BYTE( p );+      }++      glyph->x_control[i] = x;++      mask >>= 1;+    }++    /* XXX: for now we ignore the secondary stroke and edge definitions */+    /*      since we don't want to support native PFR hinting           */+    /*                                                                  */+    if ( flags & PFR_GLYPH_EXTRA_ITEMS )+    {+      error = pfr_extra_items_skip( &p, limit );+      if ( error )+        goto Exit;+    }++    pfr_glyph_start( glyph );++    /* now load a simple glyph */+    {+      FT_Vector   pos[4];+      FT_Vector*  cur;+++      pos[0].x = pos[0].y = 0;+      pos[3]   = pos[0];++      for (;;)+      {+        FT_UInt  format, format_low, args_format = 0, args_count, n;+++        /***************************************************************/+        /*  read instruction                                           */+        /*                                                             */+        PFR_CHECK( 1 );+        format     = PFR_NEXT_BYTE( p );+        format_low = format & 15;++        switch ( format >> 4 )+        {+        case 0:                             /* end glyph */+          FT_TRACE6(( "- end glyph" ));+          args_count = 0;+          break;++        case 1:                             /* general line operation */+          FT_TRACE6(( "- general line" ));+          goto Line1;++        case 4:                             /* move to inside contour  */+          FT_TRACE6(( "- move to inside" ));+          goto Line1;++        case 5:                             /* move to outside contour */+          FT_TRACE6(( "- move to outside" ));+        Line1:+          args_format = format_low;+          args_count  = 1;+          break;++        case 2:                             /* horizontal line to */+          FT_TRACE6(( "- horizontal line to cx.%d", format_low ));+          if ( format_low >= x_count )+            goto Failure;+          pos[0].x   = glyph->x_control[format_low];+          pos[0].y   = pos[3].y;+          pos[3]     = pos[0];+          args_count = 0;+          break;++        case 3:                             /* vertical line to */+          FT_TRACE6(( "- vertical line to cy.%d", format_low ));+          if ( format_low >= y_count )+            goto Failure;+          pos[0].x   = pos[3].x;+          pos[0].y   = glyph->y_control[format_low];+          pos[3]     = pos[0];+          args_count = 0;+          break;++        case 6:                             /* horizontal to vertical curve */+          FT_TRACE6(( "- hv curve " ));+          args_format = 0xB8E;+          args_count  = 3;+          break;++        case 7:                             /* vertical to horizontal curve */+          FT_TRACE6(( "- vh curve" ));+          args_format = 0xE2B;+          args_count  = 3;+          break;++        default:                            /* general curve to */+          FT_TRACE6(( "- general curve" ));+          args_count  = 4;+          args_format = format_low;+        }++        /***********************************************************/+        /*  now read arguments                                     */+        /*                                                         */+        cur = pos;+        for ( n = 0; n < args_count; n++ )+        {+          FT_UInt  idx;+          FT_Int   delta;+++          /* read the X argument */+          switch ( args_format & 3 )+          {+          case 0:                           /* 8-bit index */+            PFR_CHECK( 1 );+            idx  = PFR_NEXT_BYTE( p );+            if ( idx >= x_count )+              goto Failure;+            cur->x = glyph->x_control[idx];+            FT_TRACE7(( " cx#%d", idx ));+            break;++          case 1:                           /* 16-bit value */+            PFR_CHECK( 2 );+            cur->x = PFR_NEXT_SHORT( p );+            FT_TRACE7(( " x.%d", cur->x ));+            break;++          case 2:                           /* 8-bit delta */+            PFR_CHECK( 1 );+            delta  = PFR_NEXT_INT8( p );+            cur->x = pos[3].x + delta;+            FT_TRACE7(( " dx.%d", delta ));+            break;++          default:+            FT_TRACE7(( " |" ));+            cur->x = pos[3].x;+          }++          /* read the Y argument */+          switch ( ( args_format >> 2 ) & 3 )+          {+          case 0:                           /* 8-bit index */+            PFR_CHECK( 1 );+            idx  = PFR_NEXT_BYTE( p );+            if ( idx >= y_count )+              goto Failure;+            cur->y = glyph->y_control[idx];+            FT_TRACE7(( " cy#%d", idx ));+            break;++          case 1:                           /* 16-bit absolute value */+            PFR_CHECK( 2 );+            cur->y = PFR_NEXT_SHORT( p );+            FT_TRACE7(( " y.%d", cur->y ));+            break;++          case 2:                           /* 8-bit delta */+            PFR_CHECK( 1 );+            delta  = PFR_NEXT_INT8( p );+            cur->y = pos[3].y + delta;+            FT_TRACE7(( " dy.%d", delta ));+            break;++          default:+            FT_TRACE7(( " -" ));+            cur->y = pos[3].y;+          }++          /* read the additional format flag for the general curve */+          if ( n == 0 && args_count == 4 )+          {+            PFR_CHECK( 1 );+            args_format = PFR_NEXT_BYTE( p );+            args_count--;+          }+          else+            args_format >>= 4;++          /* save the previous point */+          pos[3] = cur[0];+          cur++;+        }++        FT_TRACE7(( "\n" ));++        /***********************************************************/+        /*  finally, execute instruction                           */+        /*                                                         */+        switch ( format >> 4 )+        {+        case 0:                             /* end glyph => EXIT */+          pfr_glyph_end( glyph );+          goto Exit;++        case 1:                             /* line operations */+        case 2:+        case 3:+          error = pfr_glyph_line_to( glyph, pos );+          goto Test_Error;++        case 4:                             /* move to inside contour  */+        case 5:                             /* move to outside contour */+          error = pfr_glyph_move_to( glyph, pos );+          goto Test_Error;++        default:                            /* curve operations */+          error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 );++        Test_Error:  /* test error condition */+          if ( error )+            goto Exit;+        }+      } /* for (;;) */+    }++  Exit:+    return error;++  Failure:+  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" ));+    goto Exit;+  }+++  /* load a composite/compound glyph */+  static FT_Error+  pfr_glyph_load_compound( PFR_Glyph  glyph,+                           FT_Byte*   p,+                           FT_Byte*   limit )+  {+    FT_Error        error  = PFR_Err_Ok;+    FT_GlyphLoader  loader = glyph->loader;+    FT_Memory       memory = loader->memory;+    PFR_SubGlyph    subglyph;+    FT_UInt         flags, i, count, org_count;+    FT_Int          x_pos, y_pos;+++    PFR_CHECK( 1 );+    flags = PFR_NEXT_BYTE( p );++    /* test for composite glyphs */+    if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )+      goto Failure;++    count = flags & 0x3F;++    /* ignore extra items when present */+    /*                                 */+    if ( flags & PFR_GLYPH_EXTRA_ITEMS )+    {+      error = pfr_extra_items_skip( &p, limit );+      if (error) goto Exit;+    }++    /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because   */+    /* the PFR format is dumb, using direct file offsets to point to the */+    /* sub-glyphs (instead of glyph indices).  Sigh.                     */+    /*                                                                   */+    /* For now, we load the list of sub-glyphs into a different array    */+    /* but this will prevent us from using the auto-hinter at its best   */+    /* quality.                                                          */+    /*                                                                   */+    org_count = glyph->num_subs;++    if ( org_count + count > glyph->max_subs )+    {+      FT_UInt  new_max = ( org_count + count + 3 ) & (FT_UInt)-4;+++      /* we arbitrarily limit the number of subglyphs */+      /* to avoid endless recursion                   */+      if ( new_max > 64 )+      {+        error = PFR_Err_Invalid_Table;+        FT_ERROR(( "pfr_glyph_load_compound:"+                   " too many compound glyphs components\n" ));+        goto Exit;+      }++      if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) )+        goto Exit;++      glyph->max_subs = new_max;+    }++    subglyph = glyph->subs + org_count;++    for ( i = 0; i < count; i++, subglyph++ )+    {+      FT_UInt  format;+++      x_pos = 0;+      y_pos = 0;++      PFR_CHECK( 1 );+      format = PFR_NEXT_BYTE( p );++      /* read scale when available */+      subglyph->x_scale = 0x10000L;+      if ( format & PFR_SUBGLYPH_XSCALE )+      {+        PFR_CHECK( 2 );+        subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4;+      }++      subglyph->y_scale = 0x10000L;+      if ( format & PFR_SUBGLYPH_YSCALE )+      {+        PFR_CHECK( 2 );+        subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4;+      }++      /* read offset */+      switch ( format & 3 )+      {+      case 1:+        PFR_CHECK( 2 );+        x_pos = PFR_NEXT_SHORT( p );+        break;++      case 2:+        PFR_CHECK( 1 );+        x_pos += PFR_NEXT_INT8( p );+        break;++      default:+        ;+      }++      switch ( ( format >> 2 ) & 3 )+      {+      case 1:+        PFR_CHECK( 2 );+        y_pos = PFR_NEXT_SHORT( p );+        break;++      case 2:+        PFR_CHECK( 1 );+        y_pos += PFR_NEXT_INT8( p );+        break;++      default:+        ;+      }++      subglyph->x_delta = x_pos;+      subglyph->y_delta = y_pos;++      /* read glyph position and size now */+      if ( format & PFR_SUBGLYPH_2BYTE_SIZE )+      {+        PFR_CHECK( 2 );+        subglyph->gps_size = PFR_NEXT_USHORT( p );+      }+      else+      {+        PFR_CHECK( 1 );+        subglyph->gps_size = PFR_NEXT_BYTE( p );+      }++      if ( format & PFR_SUBGLYPH_3BYTE_OFFSET )+      {+        PFR_CHECK( 3 );+        subglyph->gps_offset = PFR_NEXT_LONG( p );+      }+      else+      {+        PFR_CHECK( 2 );+        subglyph->gps_offset = PFR_NEXT_USHORT( p );+      }++      glyph->num_subs++;+    }++  Exit:+    return error;++  Failure:+  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));+    goto Exit;+  }+++  static FT_Error+  pfr_glyph_load_rec( PFR_Glyph  glyph,+                      FT_Stream  stream,+                      FT_ULong   gps_offset,+                      FT_ULong   offset,+                      FT_ULong   size )+  {+    FT_Error  error;+    FT_Byte*  p;+    FT_Byte*  limit;+++    if ( FT_STREAM_SEEK( gps_offset + offset ) ||+         FT_FRAME_ENTER( size )                )+      goto Exit;++    p     = (FT_Byte*)stream->cursor;+    limit = p + size;++    if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND )+    {+      FT_Int          n, old_count, count;+      FT_GlyphLoader  loader = glyph->loader;+      FT_Outline*     base   = &loader->base.outline;+++      old_count = glyph->num_subs;++      /* this is a compound glyph - load it */+      error = pfr_glyph_load_compound( glyph, p, limit );++      FT_FRAME_EXIT();++      if ( error )+        goto Exit;++      count = glyph->num_subs - old_count;++      FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n",+                  count, offset ));++      /* now, load each individual glyph */+      for ( n = 0; n < count; n++ )+      {+        FT_Int        i, old_points, num_points;+        PFR_SubGlyph  subglyph;+++        FT_TRACE4(( "subglyph %d:\n", n ));++        subglyph   = glyph->subs + old_count + n;+        old_points = base->n_points;++        error = pfr_glyph_load_rec( glyph, stream, gps_offset,+                                    subglyph->gps_offset,+                                    subglyph->gps_size );+        if ( error )+          break;++        /* note that `glyph->subs' might have been re-allocated */+        subglyph   = glyph->subs + old_count + n;+        num_points = base->n_points - old_points;++        /* translate and eventually scale the new glyph points */+        if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L )+        {+          FT_Vector*  vec = base->points + old_points;+++          for ( i = 0; i < num_points; i++, vec++ )+          {+            vec->x = FT_MulFix( vec->x, subglyph->x_scale ) ++                       subglyph->x_delta;+            vec->y = FT_MulFix( vec->y, subglyph->y_scale ) ++                       subglyph->y_delta;+          }+        }+        else+        {+          FT_Vector*  vec = loader->base.outline.points + old_points;+++          for ( i = 0; i < num_points; i++, vec++ )+          {+            vec->x += subglyph->x_delta;+            vec->y += subglyph->y_delta;+          }+        }++        /* proceed to next sub-glyph */+      }++      FT_TRACE4(( "end compound glyph with %d elements\n", count ));+    }+    else+    {+      FT_TRACE4(( "simple glyph (offset %lu)\n", offset ));++      /* load a simple glyph */+      error = pfr_glyph_load_simple( glyph, p, limit );++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_glyph_load( PFR_Glyph  glyph,+                  FT_Stream  stream,+                  FT_ULong   gps_offset,+                  FT_ULong   offset,+                  FT_ULong   size )+  {+    /* initialize glyph loader */+    FT_GlyphLoader_Rewind( glyph->loader );++    glyph->num_subs = 0;++    /* load the glyph, recursively when needed */+    return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size );+  }+++/* END */
+ src/pfr/pfrgload.h view
@@ -0,0 +1,49 @@+/***************************************************************************/+/*                                                                         */+/*  pfrgload.h                                                             */+/*                                                                         */+/*    FreeType PFR glyph loader (specification).                           */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRGLOAD_H__+#define __PFRGLOAD_H__++#include "pfrtypes.h"++FT_BEGIN_HEADER+++  FT_LOCAL( void )+  pfr_glyph_init( PFR_Glyph       glyph,+                  FT_GlyphLoader  loader );++  FT_LOCAL( void )+  pfr_glyph_done( PFR_Glyph  glyph );+++  FT_LOCAL( FT_Error )+  pfr_glyph_load( PFR_Glyph  glyph,+                  FT_Stream  stream,+                  FT_ULong   gps_offset,+                  FT_ULong   offset,+                  FT_ULong   size );+++FT_END_HEADER+++#endif /* __PFRGLOAD_H__ */+++/* END */
+ src/pfr/pfrload.c view
@@ -0,0 +1,941 @@+/***************************************************************************/+/*                                                                         */+/*  pfrload.c                                                              */+/*                                                                         */+/*    FreeType PFR loader (body).                                          */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2007, 2009, 2010 by                  */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "pfrload.h"+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H++#include "pfrerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pfr+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          EXTRA ITEMS                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  pfr_extra_items_skip( FT_Byte*  *pp,+                        FT_Byte*   limit )+  {+    return pfr_extra_items_parse( pp, limit, NULL, NULL );+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_extra_items_parse( FT_Byte*       *pp,+                         FT_Byte*        limit,+                         PFR_ExtraItem   item_list,+                         FT_Pointer      item_data )+  {+    FT_Error  error = PFR_Err_Ok;+    FT_Byte*  p     = *pp;+    FT_UInt   num_items, item_type, item_size;+++    PFR_CHECK( 1 );+    num_items = PFR_NEXT_BYTE( p );++    for ( ; num_items > 0; num_items-- )+    {+      PFR_CHECK( 2 );+      item_size = PFR_NEXT_BYTE( p );+      item_type = PFR_NEXT_BYTE( p );++      PFR_CHECK( item_size );++      if ( item_list )+      {+        PFR_ExtraItem  extra = item_list;+++        for ( extra = item_list; extra->parser != NULL; extra++ )+        {+          if ( extra->type == item_type )+          {+            error = extra->parser( p, p + item_size, item_data );+            if ( error ) goto Exit;++            break;+          }+        }+      }++      p += item_size;+    }++  Exit:+    *pp = p;+    return error;++  Too_Short:+    FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" ));+    error = PFR_Err_Invalid_Table;+    goto Exit;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          PFR HEADER                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++   static const FT_Frame_Field  pfr_header_fields[] =+   {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  PFR_HeaderRec++     FT_FRAME_START( 58 ),+       FT_FRAME_ULONG ( signature ),+       FT_FRAME_USHORT( version ),+       FT_FRAME_USHORT( signature2 ),+       FT_FRAME_USHORT( header_size ),++       FT_FRAME_USHORT( log_dir_size ),+       FT_FRAME_USHORT( log_dir_offset ),++       FT_FRAME_USHORT( log_font_max_size ),+       FT_FRAME_UOFF3 ( log_font_section_size ),+       FT_FRAME_UOFF3 ( log_font_section_offset ),++       FT_FRAME_USHORT( phy_font_max_size ),+       FT_FRAME_UOFF3 ( phy_font_section_size ),+       FT_FRAME_UOFF3 ( phy_font_section_offset ),++       FT_FRAME_USHORT( gps_max_size ),+       FT_FRAME_UOFF3 ( gps_section_size ),+       FT_FRAME_UOFF3 ( gps_section_offset ),++       FT_FRAME_BYTE  ( max_blue_values ),+       FT_FRAME_BYTE  ( max_x_orus ),+       FT_FRAME_BYTE  ( max_y_orus ),++       FT_FRAME_BYTE  ( phy_font_max_size_high ),+       FT_FRAME_BYTE  ( color_flags ),++       FT_FRAME_UOFF3 ( bct_max_size ),+       FT_FRAME_UOFF3 ( bct_set_max_size ),+       FT_FRAME_UOFF3 ( phy_bct_set_max_size ),++       FT_FRAME_USHORT( num_phy_fonts ),+       FT_FRAME_BYTE  ( max_vert_stem_snap ),+       FT_FRAME_BYTE  ( max_horz_stem_snap ),+       FT_FRAME_USHORT( max_chars ),+     FT_FRAME_END+   };+++  FT_LOCAL_DEF( FT_Error )+  pfr_header_load( PFR_Header  header,+                   FT_Stream   stream )+  {+    FT_Error  error;+++    /* read header directly */+    if ( !FT_STREAM_SEEK( 0 )                                &&+         !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) )+    {+      /* make a few adjustments to the header */+      header->phy_font_max_size +=+        (FT_UInt32)header->phy_font_max_size_high << 16;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Bool )+  pfr_header_check( PFR_Header  header )+  {+    FT_Bool  result = 1;+++    /* check signature and header size */+    if ( header->signature  != 0x50465230L ||   /* "PFR0" */+         header->version     > 4           ||+         header->header_size < 58          ||+         header->signature2 != 0x0d0a      )    /* CR/LF  */+    {+      result = 0;+    }+    return  result;+  }+++  /***********************************************************************/+  /***********************************************************************/+  /*****                                                             *****/+  /*****                    PFR LOGICAL FONTS                        *****/+  /*****                                                             *****/+  /***********************************************************************/+  /***********************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  pfr_log_font_count( FT_Stream  stream,+                      FT_UInt32  section_offset,+                      FT_UInt   *acount )+  {+    FT_Error  error;+    FT_UInt   count;+    FT_UInt   result = 0;+++    if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) )+      goto Exit;++    result = count;++  Exit:+    *acount = result;+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_log_font_load( PFR_LogFont  log_font,+                     FT_Stream    stream,+                     FT_UInt      idx,+                     FT_UInt32    section_offset,+                     FT_Bool      size_increment )+  {+    FT_UInt    num_log_fonts;+    FT_UInt    flags;+    FT_UInt32  offset;+    FT_UInt32  size;+    FT_Error   error;+++    if ( FT_STREAM_SEEK( section_offset ) ||+         FT_READ_USHORT( num_log_fonts )  )+      goto Exit;++    if ( idx >= num_log_fonts )+      return PFR_Err_Invalid_Argument;++    if ( FT_STREAM_SKIP( idx * 5 ) ||+         FT_READ_USHORT( size )    ||+         FT_READ_UOFF3 ( offset )  )+      goto Exit;++    /* save logical font size and offset */+    log_font->size   = size;+    log_font->offset = offset;++    /* now, check the rest of the table before loading it */+    {+      FT_Byte*  p;+      FT_Byte*  limit;+      FT_UInt   local;+++      if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )+        goto Exit;++      p     = stream->cursor;+      limit = p + size;++      PFR_CHECK(13);++      log_font->matrix[0] = PFR_NEXT_LONG( p );+      log_font->matrix[1] = PFR_NEXT_LONG( p );+      log_font->matrix[2] = PFR_NEXT_LONG( p );+      log_font->matrix[3] = PFR_NEXT_LONG( p );++      flags = PFR_NEXT_BYTE( p );++      local = 0;+      if ( flags & PFR_LOG_STROKE )+      {+        local++;+        if ( flags & PFR_LOG_2BYTE_STROKE )+          local++;++        if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER )+          local += 3;+      }+      if ( flags & PFR_LOG_BOLD )+      {+        local++;+        if ( flags & PFR_LOG_2BYTE_BOLD )+          local++;+      }++      PFR_CHECK( local );++      if ( flags & PFR_LOG_STROKE )+      {+        log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE )+                                     ? PFR_NEXT_SHORT( p )+                                     : PFR_NEXT_BYTE( p );++        if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER )+          log_font->miter_limit = PFR_NEXT_LONG( p );+      }++      if ( flags & PFR_LOG_BOLD )+      {+        log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD )+                                   ? PFR_NEXT_SHORT( p )+                                   : PFR_NEXT_BYTE( p );+      }++      if ( flags & PFR_LOG_EXTRA_ITEMS )+      {+        error = pfr_extra_items_skip( &p, limit );+        if (error) goto Fail;+      }++      PFR_CHECK(5);+      log_font->phys_size   = PFR_NEXT_USHORT( p );+      log_font->phys_offset = PFR_NEXT_ULONG( p );+      if ( size_increment )+      {+        PFR_CHECK( 1 );+        log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16;+      }+    }++  Fail:+    FT_FRAME_EXIT();++  Exit:+    return error;++  Too_Short:+    FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" ));+    error = PFR_Err_Invalid_Table;+    goto Fail;+  }+++  /***********************************************************************/+  /***********************************************************************/+  /*****                                                             *****/+  /*****                    PFR PHYSICAL FONTS                       *****/+  /*****                                                             *****/+  /***********************************************************************/+  /***********************************************************************/+++  /* load bitmap strikes lists */+  FT_CALLBACK_DEF( FT_Error )+  pfr_extra_item_load_bitmap_info( FT_Byte*     p,+                                   FT_Byte*     limit,+                                   PFR_PhyFont  phy_font )+  {+    FT_Memory   memory = phy_font->memory;+    PFR_Strike  strike;+    FT_UInt     flags0;+    FT_UInt     n, count, size1;+    FT_Error    error = PFR_Err_Ok;+++    PFR_CHECK( 5 );++    p += 3;  /* skip bctSize */+    flags0 = PFR_NEXT_BYTE( p );+    count  = PFR_NEXT_BYTE( p );++    /* re-allocate when needed */+    if ( phy_font->num_strikes + count > phy_font->max_strikes )+    {+      FT_UInt  new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 );+++      if ( FT_RENEW_ARRAY( phy_font->strikes,+                           phy_font->num_strikes,+                           new_max ) )+        goto Exit;++      phy_font->max_strikes = new_max;+    }++    size1 = 1 + 1 + 1 + 2 + 2 + 1;+    if ( flags0 & PFR_STRIKE_2BYTE_XPPM )+      size1++;++    if ( flags0 & PFR_STRIKE_2BYTE_YPPM )+      size1++;++    if ( flags0 & PFR_STRIKE_3BYTE_SIZE )+      size1++;++    if ( flags0 & PFR_STRIKE_3BYTE_OFFSET )+      size1++;++    if ( flags0 & PFR_STRIKE_2BYTE_COUNT )+      size1++;++    strike = phy_font->strikes + phy_font->num_strikes;++    PFR_CHECK( count * size1 );++    for ( n = 0; n < count; n++, strike++ )+    {+      strike->x_ppm       = ( flags0 & PFR_STRIKE_2BYTE_XPPM )+                            ? PFR_NEXT_USHORT( p )+                            : PFR_NEXT_BYTE( p );++      strike->y_ppm       = ( flags0 & PFR_STRIKE_2BYTE_YPPM )+                            ? PFR_NEXT_USHORT( p )+                            : PFR_NEXT_BYTE( p );++      strike->flags       = PFR_NEXT_BYTE( p );++      strike->bct_size    = ( flags0 & PFR_STRIKE_3BYTE_SIZE )+                            ? PFR_NEXT_ULONG( p )+                            : PFR_NEXT_USHORT( p );++      strike->bct_offset  = ( flags0 & PFR_STRIKE_3BYTE_OFFSET )+                            ? PFR_NEXT_ULONG( p )+                            : PFR_NEXT_USHORT( p );++      strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT )+                            ? PFR_NEXT_USHORT( p )+                            : PFR_NEXT_BYTE( p );+    }++    phy_font->num_strikes += count;++  Exit:+    return error;++  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_extra_item_load_bitmap_info:"+               " invalid bitmap info table\n" ));+    goto Exit;+  }+++  /* Load font ID.  This is a so-called "unique" name that is rather+   * long and descriptive (like "Tiresias ScreenFont v7.51").+   *+   * Note that a PFR font's family name is contained in an *undocumented*+   * string of the "auxiliary data" portion of a physical font record.  This+   * may also contain the "real" style name!+   *+   * If no family name is present, the font ID is used instead for the+   * family.+   */+  FT_CALLBACK_DEF( FT_Error )+  pfr_extra_item_load_font_id( FT_Byte*     p,+                               FT_Byte*     limit,+                               PFR_PhyFont  phy_font )+  {+    FT_Error    error  = PFR_Err_Ok;+    FT_Memory   memory = phy_font->memory;+    FT_PtrDist  len    = limit - p;+++    if ( phy_font->font_id != NULL )+      goto Exit;++    if ( FT_ALLOC( phy_font->font_id, len + 1 ) )+      goto Exit;++    /* copy font ID name, and terminate it for safety */+    FT_MEM_COPY( phy_font->font_id, p, len );+    phy_font->font_id[len] = 0;++  Exit:+    return error;+  }+++  /* load stem snap tables */+  FT_CALLBACK_DEF( FT_Error )+  pfr_extra_item_load_stem_snaps( FT_Byte*     p,+                                  FT_Byte*     limit,+                                  PFR_PhyFont  phy_font )+  {+    FT_UInt    count, num_vert, num_horz;+    FT_Int*    snaps;+    FT_Error   error  = PFR_Err_Ok;+    FT_Memory  memory = phy_font->memory;+++    if ( phy_font->vertical.stem_snaps != NULL )+      goto Exit;++    PFR_CHECK( 1 );+    count = PFR_NEXT_BYTE( p );++    num_vert = count & 15;+    num_horz = count >> 4;+    count    = num_vert + num_horz;++    PFR_CHECK( count * 2 );++    if ( FT_NEW_ARRAY( snaps, count ) )+      goto Exit;++    phy_font->vertical.stem_snaps = snaps;+    phy_font->horizontal.stem_snaps = snaps + num_vert;++    for ( ; count > 0; count--, snaps++ )+      *snaps = FT_NEXT_SHORT( p );++  Exit:+    return error;++  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_exta_item_load_stem_snaps:"+               " invalid stem snaps table\n" ));+    goto Exit;+  }++++  /* load kerning pair data */+  FT_CALLBACK_DEF( FT_Error )+  pfr_extra_item_load_kerning_pairs( FT_Byte*     p,+                                     FT_Byte*     limit,+                                     PFR_PhyFont  phy_font )+  {+    PFR_KernItem  item   = NULL;+    FT_Error      error  = PFR_Err_Ok;+    FT_Memory     memory = phy_font->memory;+++    FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));++    if ( FT_NEW( item ) )+      goto Exit;++    PFR_CHECK( 4 );++    item->pair_count = PFR_NEXT_BYTE( p );+    item->base_adj   = PFR_NEXT_SHORT( p );+    item->flags      = PFR_NEXT_BYTE( p );+    item->offset     = phy_font->offset + ( p - phy_font->cursor );++#ifndef PFR_CONFIG_NO_CHECKS+    item->pair_size = 3;++    if ( item->flags & PFR_KERN_2BYTE_CHAR )+      item->pair_size += 2;++    if ( item->flags & PFR_KERN_2BYTE_ADJ )+      item->pair_size += 1;++    PFR_CHECK( item->pair_count * item->pair_size );+#endif++    /* load first and last pairs into the item to speed up */+    /* lookup later...                                     */+    if ( item->pair_count > 0 )+    {+      FT_UInt   char1, char2;+      FT_Byte*  q;+++      if ( item->flags & PFR_KERN_2BYTE_CHAR )+      {+        q     = p;+        char1 = PFR_NEXT_USHORT( q );+        char2 = PFR_NEXT_USHORT( q );++        item->pair1 = PFR_KERN_INDEX( char1, char2 );++        q = p + item->pair_size * ( item->pair_count - 1 );+        char1 = PFR_NEXT_USHORT( q );+        char2 = PFR_NEXT_USHORT( q );++        item->pair2 = PFR_KERN_INDEX( char1, char2 );+      }+      else+      {+        q     = p;+        char1 = PFR_NEXT_BYTE( q );+        char2 = PFR_NEXT_BYTE( q );++        item->pair1 = PFR_KERN_INDEX( char1, char2 );++        q = p + item->pair_size * ( item->pair_count - 1 );+        char1 = PFR_NEXT_BYTE( q );+        char2 = PFR_NEXT_BYTE( q );++        item->pair2 = PFR_KERN_INDEX( char1, char2 );+      }++      /* add new item to the current list */+      item->next                 = NULL;+      *phy_font->kern_items_tail = item;+      phy_font->kern_items_tail  = &item->next;+      phy_font->num_kern_pairs  += item->pair_count;+    }+    else+    {+      /* empty item! */+      FT_FREE( item );+    }++  Exit:+    return error;++  Too_Short:+    FT_FREE( item );++    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_extra_item_load_kerning_pairs:"+               " invalid kerning pairs table\n" ));+    goto Exit;+  }++++  static const PFR_ExtraItemRec  pfr_phy_font_extra_items[] =+  {+    { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info },+    { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id },+    { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps },+    { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs },+    { 0, NULL }+  };+++  /* Loads a name from the auxiliary data.  Since this extracts undocumented+   * strings from the font file, we need to be careful here.+   */+  static FT_Error+  pfr_aux_name_load( FT_Byte*     p,+                     FT_UInt      len,+                     FT_Memory    memory,+                     FT_String*  *astring )+  {+    FT_Error    error = PFR_Err_Ok;+    FT_String*  result = NULL;+    FT_UInt     n, ok;+++    if ( len > 0 && p[len - 1] == 0 )+      len--;++    /* check that each character is ASCII for making sure not to+       load garbage+     */+    ok = ( len > 0 );+    for ( n = 0; n < len; n++ )+      if ( p[n] < 32 || p[n] > 127 )+      {+        ok = 0;+        break;+      }++    if ( ok )+    {+      if ( FT_ALLOC( result, len + 1 ) )+        goto Exit;++      FT_MEM_COPY( result, p, len );+      result[len] = 0;+    }+  Exit:+    *astring = result;+    return error;+  }+++  FT_LOCAL_DEF( void )+  pfr_phy_font_done( PFR_PhyFont  phy_font,+                     FT_Memory    memory )+  {+    FT_FREE( phy_font->font_id );+    FT_FREE( phy_font->family_name );+    FT_FREE( phy_font->style_name );++    FT_FREE( phy_font->vertical.stem_snaps );+    phy_font->vertical.num_stem_snaps = 0;++    phy_font->horizontal.stem_snaps     = NULL;+    phy_font->horizontal.num_stem_snaps = 0;++    FT_FREE( phy_font->strikes );+    phy_font->num_strikes = 0;+    phy_font->max_strikes = 0;++    FT_FREE( phy_font->chars );+    phy_font->num_chars    = 0;+    phy_font->chars_offset = 0;++    FT_FREE( phy_font->blue_values );+    phy_font->num_blue_values = 0;++    {+      PFR_KernItem  item, next;+++      item = phy_font->kern_items;+      while ( item )+      {+        next = item->next;+        FT_FREE( item );+        item = next;+      }+      phy_font->kern_items      = NULL;+      phy_font->kern_items_tail = NULL;+    }++    phy_font->num_kern_pairs = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_phy_font_load( PFR_PhyFont  phy_font,+                     FT_Stream    stream,+                     FT_UInt32    offset,+                     FT_UInt32    size )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;+    FT_UInt    flags;+    FT_ULong   num_aux;+    FT_Byte*   p;+    FT_Byte*   limit;+++    phy_font->memory = memory;+    phy_font->offset = offset;++    phy_font->kern_items      = NULL;+    phy_font->kern_items_tail = &phy_font->kern_items;++    if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )+      goto Exit;++    phy_font->cursor = stream->cursor;++    p     = stream->cursor;+    limit = p + size;++    PFR_CHECK( 15 );+    phy_font->font_ref_number    = PFR_NEXT_USHORT( p );+    phy_font->outline_resolution = PFR_NEXT_USHORT( p );+    phy_font->metrics_resolution = PFR_NEXT_USHORT( p );+    phy_font->bbox.xMin          = PFR_NEXT_SHORT( p );+    phy_font->bbox.yMin          = PFR_NEXT_SHORT( p );+    phy_font->bbox.xMax          = PFR_NEXT_SHORT( p );+    phy_font->bbox.yMax          = PFR_NEXT_SHORT( p );+    phy_font->flags      = flags = PFR_NEXT_BYTE( p );++    /* get the standard advance for non-proportional fonts */+    if ( !(flags & PFR_PHY_PROPORTIONAL) )+    {+      PFR_CHECK( 2 );+      phy_font->standard_advance = PFR_NEXT_SHORT( p );+    }++    /* load the extra items when present */+    if ( flags & PFR_PHY_EXTRA_ITEMS )+    {+      error =  pfr_extra_items_parse( &p, limit,+                                      pfr_phy_font_extra_items, phy_font );++      if ( error )+        goto Fail;+    }++    /* In certain fonts, the auxiliary bytes contain interesting  */+    /* information. These are not in the specification but can be */+    /* guessed by looking at the content of a few PFR0 fonts.     */+    PFR_CHECK( 3 );+    num_aux = PFR_NEXT_ULONG( p );++    if ( num_aux > 0 )+    {+      FT_Byte*  q = p;+      FT_Byte*  q2;+++      PFR_CHECK( num_aux );+      p += num_aux;++      while ( num_aux > 0 )+      {+        FT_UInt  length, type;+++        if ( q + 4 > p )+          break;++        length = PFR_NEXT_USHORT( q );+        if ( length < 4 || length > num_aux )+          break;++        q2   = q + length - 2;+        type = PFR_NEXT_USHORT( q );++        switch ( type )+        {+        case 1:+          /* this seems to correspond to the font's family name,+           * padded to 16-bits with one zero when necessary+           */+          error = pfr_aux_name_load( q, length - 4U, memory,+                                     &phy_font->family_name );+          if ( error )+            goto Exit;+          break;++        case 2:+          if ( q + 32 > q2 )+            break;++          q += 10;+          phy_font->ascent  = PFR_NEXT_SHORT( q );+          phy_font->descent = PFR_NEXT_SHORT( q );+          phy_font->leading = PFR_NEXT_SHORT( q );+          q += 16;+          break;++        case 3:+          /* this seems to correspond to the font's style name,+           * padded to 16-bits with one zero when necessary+           */+          error = pfr_aux_name_load( q, length - 4U, memory,+                                     &phy_font->style_name );+          if ( error )+            goto Exit;+          break;++        default:+          ;+        }++        q        = q2;+        num_aux -= length;+      }+    }++    /* read the blue values */+    {+      FT_UInt  n, count;+++      PFR_CHECK( 1 );+      phy_font->num_blue_values = count = PFR_NEXT_BYTE( p );++      PFR_CHECK( count * 2 );++      if ( FT_NEW_ARRAY( phy_font->blue_values, count ) )+        goto Fail;++      for ( n = 0; n < count; n++ )+        phy_font->blue_values[n] = PFR_NEXT_SHORT( p );+    }++    PFR_CHECK( 8 );+    phy_font->blue_fuzz  = PFR_NEXT_BYTE( p );+    phy_font->blue_scale = PFR_NEXT_BYTE( p );++    phy_font->vertical.standard   = PFR_NEXT_USHORT( p );+    phy_font->horizontal.standard = PFR_NEXT_USHORT( p );++    /* read the character descriptors */+    {+      FT_UInt  n, count, Size;+++      phy_font->num_chars    = count = PFR_NEXT_USHORT( p );+      phy_font->chars_offset = offset + ( p - stream->cursor );++      if ( FT_NEW_ARRAY( phy_font->chars, count ) )+        goto Fail;++      Size = 1 + 1 + 2;+      if ( flags & PFR_PHY_2BYTE_CHARCODE )+        Size += 1;++      if ( flags & PFR_PHY_PROPORTIONAL )+        Size += 2;++      if ( flags & PFR_PHY_ASCII_CODE )+        Size += 1;++      if ( flags & PFR_PHY_2BYTE_GPS_SIZE )+        Size += 1;++      if ( flags & PFR_PHY_3BYTE_GPS_OFFSET )+        Size += 1;++      PFR_CHECK( count * Size );++      for ( n = 0; n < count; n++ )+      {+        PFR_Char  cur = &phy_font->chars[n];+++        cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE )+                         ? PFR_NEXT_USHORT( p )+                         : PFR_NEXT_BYTE( p );++        cur->advance   = ( flags & PFR_PHY_PROPORTIONAL )+                         ? PFR_NEXT_SHORT( p )+                         : (FT_Int) phy_font->standard_advance;++#if 0+        cur->ascii     = ( flags & PFR_PHY_ASCII_CODE )+                         ? PFR_NEXT_BYTE( p )+                         : 0;+#else+        if ( flags & PFR_PHY_ASCII_CODE )+          p += 1;+#endif+        cur->gps_size  = ( flags & PFR_PHY_2BYTE_GPS_SIZE )+                         ? PFR_NEXT_USHORT( p )+                         : PFR_NEXT_BYTE( p );++        cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET )+                          ? PFR_NEXT_ULONG( p )+                          : PFR_NEXT_USHORT( p );+      }+    }++    /* that's it! */++  Fail:+    FT_FRAME_EXIT();++    /* save position of bitmap info */+    phy_font->bct_offset = FT_STREAM_POS();+    phy_font->cursor     = NULL;++  Exit:+    return error;++  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));+    goto Fail;+  }+++/* END */
+ src/pfr/pfrload.h view
@@ -0,0 +1,118 @@+/***************************************************************************/+/*                                                                         */+/*  pfrload.h                                                              */+/*                                                                         */+/*    FreeType PFR loader (specification).                                 */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRLOAD_H__+#define __PFRLOAD_H__++#include "pfrobjs.h"+#include FT_INTERNAL_STREAM_H+++FT_BEGIN_HEADER++#ifdef PFR_CONFIG_NO_CHECKS+#define PFR_CHECK( x )  do { } while ( 0 )+#else+#define PFR_CHECK( x )  do                       \+                        {                        \+                          if ( p + (x) > limit ) \+                            goto Too_Short;      \+                        } while ( 0 )+#endif++#define PFR_NEXT_BYTE( p )    FT_NEXT_BYTE( p )+#define PFR_NEXT_INT8( p )    FT_NEXT_CHAR( p )+#define PFR_NEXT_SHORT( p )   FT_NEXT_SHORT( p )+#define PFR_NEXT_USHORT( p )  FT_NEXT_USHORT( p )+#define PFR_NEXT_LONG( p )    FT_NEXT_OFF3( p )+#define PFR_NEXT_ULONG( p )   FT_NEXT_UOFF3( p )+++ /* handling extra items */++  typedef FT_Error+  (*PFR_ExtraItem_ParseFunc)( FT_Byte*    p,+                              FT_Byte*    limit,+                              FT_Pointer  data );++  typedef struct  PFR_ExtraItemRec_+  {+    FT_UInt                  type;+    PFR_ExtraItem_ParseFunc  parser;++  } PFR_ExtraItemRec;++  typedef const struct PFR_ExtraItemRec_*  PFR_ExtraItem;+++  FT_LOCAL( FT_Error )+  pfr_extra_items_skip( FT_Byte*  *pp,+                        FT_Byte*  limit );++  FT_LOCAL( FT_Error )+  pfr_extra_items_parse( FT_Byte*      *pp,+                         FT_Byte*       limit,+                         PFR_ExtraItem  item_list,+                         FT_Pointer     item_data );+++  /* load a PFR header */+  FT_LOCAL( FT_Error )+  pfr_header_load( PFR_Header  header,+                   FT_Stream   stream );++  /* check a PFR header */+  FT_LOCAL( FT_Bool )+  pfr_header_check( PFR_Header  header );+++  /* return number of logical fonts in this file */+  FT_LOCAL( FT_Error )+  pfr_log_font_count( FT_Stream   stream,+                      FT_UInt32   log_section_offset,+                      FT_UInt    *acount );++  /* load a pfr logical font entry */+  FT_LOCAL( FT_Error )+  pfr_log_font_load( PFR_LogFont  log_font,+                     FT_Stream    stream,+                     FT_UInt      face_index,+                     FT_UInt32    section_offset,+                     FT_Bool      size_increment );+++  /* load a physical font entry */+  FT_LOCAL( FT_Error )+  pfr_phy_font_load( PFR_PhyFont  phy_font,+                     FT_Stream    stream,+                     FT_UInt32    offset,+                     FT_UInt32    size );++  /* finalize a physical font */+  FT_LOCAL( void )+  pfr_phy_font_done( PFR_PhyFont  phy_font,+                     FT_Memory    memory );++  /* */++FT_END_HEADER++#endif /* __PFRLOAD_H__ */+++/* END */
+ src/pfr/pfrobjs.c view
@@ -0,0 +1,591 @@+/***************************************************************************/+/*                                                                         */+/*  pfrobjs.c                                                              */+/*                                                                         */+/*    FreeType PFR object methods (body).                                  */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by            */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "pfrobjs.h"+#include "pfrload.h"+#include "pfrgload.h"+#include "pfrcmap.h"+#include "pfrsbit.h"+#include FT_OUTLINE_H+#include FT_INTERNAL_DEBUG_H+#include FT_TRUETYPE_IDS_H ++#include "pfrerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pfr+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     FACE OBJECT METHODS                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  pfr_face_done( FT_Face  pfrface )     /* PFR_Face */+  {+    PFR_Face   face = (PFR_Face)pfrface;+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = pfrface->driver->root.memory;++    /* we don't want dangling pointers */+    pfrface->family_name = NULL;+    pfrface->style_name  = NULL;++    /* finalize the physical font record */+    pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );++    /* no need to finalize the logical font or the header */+    FT_FREE( pfrface->available_sizes );+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_face_init( FT_Stream      stream,+                 FT_Face        pfrface,+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    PFR_Face  face = (PFR_Face)pfrface;+    FT_Error  error;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+++    /* load the header and check it */+    error = pfr_header_load( &face->header, stream );+    if ( error )+      goto Exit;++    if ( !pfr_header_check( &face->header ) )+    {+      FT_TRACE4(( "pfr_face_init: not a valid PFR font\n" ));+      error = PFR_Err_Unknown_File_Format;+      goto Exit;+    }++    /* check face index */+    {+      FT_UInt  num_faces;+++      error = pfr_log_font_count( stream,+                                  face->header.log_dir_offset,+                                  &num_faces );+      if ( error )+        goto Exit;++      pfrface->num_faces = num_faces;+    }++    if ( face_index < 0 )+      goto Exit;++    if ( face_index >= pfrface->num_faces )+    {+      FT_ERROR(( "pfr_face_init: invalid face index\n" ));+      error = PFR_Err_Invalid_Argument;+      goto Exit;+    }++    /* load the face */+    error = pfr_log_font_load(+               &face->log_font, stream, face_index,+               face->header.log_dir_offset,+               FT_BOOL( face->header.phy_font_max_size_high != 0 ) );+    if ( error )+      goto Exit;++    /* now load the physical font descriptor */+    error = pfr_phy_font_load( &face->phy_font, stream,+                               face->log_font.phys_offset,+                               face->log_font.phys_size );+    if ( error )+      goto Exit;++    /* now set up all root face fields */+    {+      PFR_PhyFont  phy_font = &face->phy_font;+++      pfrface->face_index = face_index;+      pfrface->num_glyphs = phy_font->num_chars + 1;+      pfrface->face_flags = FT_FACE_FLAG_SCALABLE;++      /* if all characters point to the same gps_offset 0, we */+      /* assume that the font only contains bitmaps           */+      {+        FT_UInt  nn;+++        for ( nn = 0; nn < phy_font->num_chars; nn++ )+          if ( phy_font->chars[nn].gps_offset != 0 )+            break;++        if ( nn == phy_font->num_chars )+        {+          if ( phy_font->num_strikes > 0 )+            pfrface->face_flags = 0;        /* not scalable */+          else+          {+            FT_ERROR(( "pfr_face_init: font doesn't contain glyphs\n" ));+            error = PFR_Err_Invalid_File_Format;+            goto Exit;+          }+        }+      }++      if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 )+        pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      if ( phy_font->flags & PFR_PHY_VERTICAL )+        pfrface->face_flags |= FT_FACE_FLAG_VERTICAL;+      else+        pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL;++      if ( phy_font->num_strikes > 0 )+        pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES;++      if ( phy_font->num_kern_pairs > 0 )+        pfrface->face_flags |= FT_FACE_FLAG_KERNING;++      /* If no family name was found in the "undocumented" auxiliary+       * data, use the font ID instead.  This sucks but is better than+       * nothing.+       */+      pfrface->family_name = phy_font->family_name;+      if ( pfrface->family_name == NULL )+        pfrface->family_name = phy_font->font_id;++      /* note that the style name can be NULL in certain PFR fonts,+       * probably meaning "Regular"+       */+      pfrface->style_name = phy_font->style_name;++      pfrface->num_fixed_sizes = 0;+      pfrface->available_sizes = 0;++      pfrface->bbox         = phy_font->bbox;+      pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution;+      pfrface->ascender     = (FT_Short) phy_font->bbox.yMax;+      pfrface->descender    = (FT_Short) phy_font->bbox.yMin;++      pfrface->height = (FT_Short)( ( pfrface->units_per_EM * 12 ) / 10 );+      if ( pfrface->height < pfrface->ascender - pfrface->descender )+        pfrface->height = (FT_Short)(pfrface->ascender - pfrface->descender);++      if ( phy_font->num_strikes > 0 )+      {+        FT_UInt          n, count = phy_font->num_strikes;+        FT_Bitmap_Size*  size;+        PFR_Strike       strike;+        FT_Memory        memory = pfrface->stream->memory;+++        if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) )+          goto Exit;++        size   = pfrface->available_sizes;+        strike = phy_font->strikes;+        for ( n = 0; n < count; n++, size++, strike++ )+        {+          size->height = (FT_UShort)strike->y_ppm;+          size->width  = (FT_UShort)strike->x_ppm;+          size->size   = strike->y_ppm << 6;+          size->x_ppem = strike->x_ppm << 6;+          size->y_ppem = strike->y_ppm << 6;+        }+        pfrface->num_fixed_sizes = count;+      }++      /* now compute maximum advance width */+      if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )+        pfrface->max_advance_width = (FT_Short)phy_font->standard_advance;+      else+      {+        FT_Int    max = 0;+        FT_UInt   count = phy_font->num_chars;+        PFR_Char  gchar = phy_font->chars;+++        for ( ; count > 0; count--, gchar++ )+        {+          if ( max < gchar->advance )+            max = gchar->advance;+        }++        pfrface->max_advance_width = (FT_Short)max;+      }++      pfrface->max_advance_height = pfrface->height;++      pfrface->underline_position  = (FT_Short)( -pfrface->units_per_EM / 10 );+      pfrface->underline_thickness = (FT_Short)(  pfrface->units_per_EM / 30 );++      /* create charmap */+      {+        FT_CharMapRec  charmap;+++        charmap.face        = pfrface;+        charmap.platform_id = TT_PLATFORM_MICROSOFT;+        charmap.encoding_id = TT_MS_ID_UNICODE_CS;+        charmap.encoding    = FT_ENCODING_UNICODE;++        error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL );++#if 0+        /* Select default charmap */+        if ( pfrface->num_charmaps )+          pfrface->charmap = pfrface->charmaps[0];+#endif+      }++      /* check whether we've loaded any kerning pairs */+      if ( phy_font->num_kern_pairs )+        pfrface->face_flags |= FT_FACE_FLAG_KERNING;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    SLOT OBJECT METHOD                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( FT_Error )+  pfr_slot_init( FT_GlyphSlot  pfrslot )        /* PFR_Slot */+  {+    PFR_Slot        slot   = (PFR_Slot)pfrslot;+    FT_GlyphLoader  loader = pfrslot->internal->loader;+++    pfr_glyph_init( &slot->glyph, loader );++    return 0;+  }+++  FT_LOCAL_DEF( void )+  pfr_slot_done( FT_GlyphSlot  pfrslot )        /* PFR_Slot */+  {+    PFR_Slot  slot = (PFR_Slot)pfrslot;+++    pfr_glyph_done( &slot->glyph );+  }+++  FT_LOCAL_DEF( FT_Error )+  pfr_slot_load( FT_GlyphSlot  pfrslot,         /* PFR_Slot */+                 FT_Size       pfrsize,         /* PFR_Size */+                 FT_UInt       gindex,+                 FT_Int32      load_flags )+  {+    PFR_Slot     slot    = (PFR_Slot)pfrslot;+    PFR_Size     size    = (PFR_Size)pfrsize;+    FT_Error     error;+    PFR_Face     face    = (PFR_Face)pfrslot->face;+    PFR_Char     gchar;+    FT_Outline*  outline = &pfrslot->outline;+    FT_ULong     gps_offset;+++    if ( gindex > 0 )+      gindex--;++    if ( !face || gindex >= face->phy_font.num_chars )+    {+      error = PFR_Err_Invalid_Argument;+      goto Exit;+    }++    /* try to load an embedded bitmap */+    if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )+    {+      error = pfr_slot_load_bitmap( slot, size, gindex );+      if ( error == 0 )+        goto Exit;+    }++    if ( load_flags & FT_LOAD_SBITS_ONLY )+    {+      error = PFR_Err_Invalid_Argument;+      goto Exit;+    }++    gchar               = face->phy_font.chars + gindex;+    pfrslot->format     = FT_GLYPH_FORMAT_OUTLINE;+    outline->n_points   = 0;+    outline->n_contours = 0;+    gps_offset          = face->header.gps_section_offset;++    /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */+    error = pfr_glyph_load( &slot->glyph, face->root.stream,+                            gps_offset, gchar->gps_offset, gchar->gps_size );++    if ( !error )+    {+      FT_BBox            cbox;+      FT_Glyph_Metrics*  metrics = &pfrslot->metrics;+      FT_Pos             advance;+      FT_Int             em_metrics, em_outline;+      FT_Bool            scaling;+++      scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );++      /* copy outline data */+      *outline = slot->glyph.loader->base.outline;++      outline->flags &= ~FT_OUTLINE_OWNER;+      outline->flags |= FT_OUTLINE_REVERSE_FILL;++      if ( size && pfrsize->metrics.y_ppem < 24 )+        outline->flags |= FT_OUTLINE_HIGH_PRECISION;++      /* compute the advance vector */+      metrics->horiAdvance = 0;+      metrics->vertAdvance = 0;++      advance    = gchar->advance;+      em_metrics = face->phy_font.metrics_resolution;+      em_outline = face->phy_font.outline_resolution;++      if ( em_metrics != em_outline )+        advance = FT_MulDiv( advance, em_outline, em_metrics );++      if ( face->phy_font.flags & PFR_PHY_VERTICAL )+        metrics->vertAdvance = advance;+      else+        metrics->horiAdvance = advance;++      pfrslot->linearHoriAdvance = metrics->horiAdvance;+      pfrslot->linearVertAdvance = metrics->vertAdvance;++      /* make-up vertical metrics(?) */+      metrics->vertBearingX = 0;+      metrics->vertBearingY = 0;++#if 0 /* some fonts seem to be broken here! */++      /* Apply the font matrix, if any.                 */+      /* TODO: Test existing fonts with unusual matrix  */+      /* whether we have to adjust Units per EM.        */+      {+        FT_Matrix font_matrix;+++        font_matrix.xx = face->log_font.matrix[0] << 8;+        font_matrix.yx = face->log_font.matrix[1] << 8;+        font_matrix.xy = face->log_font.matrix[2] << 8;+        font_matrix.yy = face->log_font.matrix[3] << 8;++        FT_Outline_Transform( outline, &font_matrix );+      }+#endif++      /* scale when needed */+      if ( scaling )+      {+        FT_Int      n;+        FT_Fixed    x_scale = pfrsize->metrics.x_scale;+        FT_Fixed    y_scale = pfrsize->metrics.y_scale;+        FT_Vector*  vec     = outline->points;+++        /* scale outline points */+        for ( n = 0; n < outline->n_points; n++, vec++ )+        {+          vec->x = FT_MulFix( vec->x, x_scale );+          vec->y = FT_MulFix( vec->y, y_scale );+        }++        /* scale the advance */+        metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );+        metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );+      }++      /* compute the rest of the metrics */+      FT_Outline_Get_CBox( outline, &cbox );++      metrics->width        = cbox.xMax - cbox.xMin;+      metrics->height       = cbox.yMax - cbox.yMin;+      metrics->horiBearingX = cbox.xMin;+      metrics->horiBearingY = cbox.yMax - metrics->height;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      KERNING METHOD                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( FT_Error )+  pfr_face_get_kerning( FT_Face     pfrface,        /* PFR_Face */+                        FT_UInt     glyph1,+                        FT_UInt     glyph2,+                        FT_Vector*  kerning )+  {+    PFR_Face     face     = (PFR_Face)pfrface;+    FT_Error     error    = PFR_Err_Ok;+    PFR_PhyFont  phy_font = &face->phy_font;+    FT_UInt32    code1, code2, pair;+++    kerning->x = 0;+    kerning->y = 0;++    if ( glyph1 > 0 )+      glyph1--;++    if ( glyph2 > 0 )+      glyph2--;++    /* convert glyph indices to character codes */+    if ( glyph1 > phy_font->num_chars ||+         glyph2 > phy_font->num_chars )+      goto Exit;++    code1 = phy_font->chars[glyph1].char_code;+    code2 = phy_font->chars[glyph2].char_code;+    pair  = PFR_KERN_INDEX( code1, code2 );++    /* now search the list of kerning items */+    {+      PFR_KernItem  item   = phy_font->kern_items;+      FT_Stream     stream = pfrface->stream;+++      for ( ; item; item = item->next )+      {+        if ( pair >= item->pair1 && pair <= item->pair2 )+          goto FoundPair;+      }+      goto Exit;++    FoundPair: /* we found an item, now parse it and find the value if any */+      if ( FT_STREAM_SEEK( item->offset )                       ||+           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )+        goto Exit;++      {+        FT_UInt    count       = item->pair_count;+        FT_UInt    size        = item->pair_size;+        FT_UInt    power       = (FT_UInt)ft_highpow2( (FT_UInt32)count );+        FT_UInt    probe       = power * size;+        FT_UInt    extra       = count - power;+        FT_Byte*   base        = stream->cursor;+        FT_Bool    twobytes    = FT_BOOL( item->flags & 1 );+        FT_Bool    twobyte_adj = FT_BOOL( item->flags & 2 );+        FT_Byte*   p;+        FT_UInt32  cpair;+++        if ( extra > 0 )+        {+          p = base + extra * size;++          if ( twobytes )+            cpair = FT_NEXT_ULONG( p );+          else+            cpair = PFR_NEXT_KPAIR( p );++          if ( cpair == pair )+            goto Found;++          if ( cpair < pair )+          {+            if ( twobyte_adj )+              p += 2;+            else+              p++;+            base = p;+          }+        }++        while ( probe > size )+        {+          probe >>= 1;+          p       = base + probe;++          if ( twobytes )+            cpair = FT_NEXT_ULONG( p );+          else+            cpair = PFR_NEXT_KPAIR( p );++          if ( cpair == pair )+            goto Found;++          if ( cpair < pair )+            base += probe;+        }++        p = base;++        if ( twobytes )+          cpair = FT_NEXT_ULONG( p );+        else+          cpair = PFR_NEXT_KPAIR( p );++        if ( cpair == pair )+        {+          FT_Int  value;+++        Found:+          if ( twobyte_adj )+            value = FT_PEEK_SHORT( p );+          else+            value = p[0];++          kerning->x = item->base_adj + value;+        }+      }++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }++/* END */
+ src/pfr/pfrobjs.h view
@@ -0,0 +1,96 @@+/***************************************************************************/+/*                                                                         */+/*  pfrobjs.h                                                              */+/*                                                                         */+/*    FreeType PFR object methods (specification).                         */+/*                                                                         */+/*  Copyright 2002, 2003, 2004 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFROBJS_H__+#define __PFROBJS_H__++#include "pfrtypes.h"+++FT_BEGIN_HEADER++  typedef struct PFR_FaceRec_*  PFR_Face;++  typedef struct PFR_SizeRec_*  PFR_Size;++  typedef struct PFR_SlotRec_*  PFR_Slot;+++  typedef struct  PFR_FaceRec_+  {+    FT_FaceRec      root;+    PFR_HeaderRec   header;+    PFR_LogFontRec  log_font;+    PFR_PhyFontRec  phy_font;++  } PFR_FaceRec;+++  typedef struct  PFR_SizeRec_+  {+    FT_SizeRec  root;++  } PFR_SizeRec;+++  typedef struct  PFR_SlotRec_+  {+    FT_GlyphSlotRec  root;+    PFR_GlyphRec     glyph;++  } PFR_SlotRec;+++  FT_LOCAL( FT_Error )+  pfr_face_init( FT_Stream      stream,+                 FT_Face        face,           /* PFR_Face */+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params );++  FT_LOCAL( void )+  pfr_face_done( FT_Face  face );               /* PFR_Face */+++  FT_LOCAL( FT_Error )+  pfr_face_get_kerning( FT_Face     face,       /* PFR_Face */+                        FT_UInt     glyph1,+                        FT_UInt     glyph2,+                        FT_Vector*  kerning );+++  FT_LOCAL( FT_Error )+  pfr_slot_init( FT_GlyphSlot  slot );          /* PFR_Slot */++  FT_LOCAL( void )+  pfr_slot_done( FT_GlyphSlot  slot );          /* PFR_Slot */+++  FT_LOCAL( FT_Error )+  pfr_slot_load( FT_GlyphSlot  slot,            /* PFR_Slot */+                 FT_Size       size,            /* PFR_Size */+                 FT_UInt       gindex,+                 FT_Int32      load_flags );+++FT_END_HEADER++#endif /* __PFROBJS_H__ */+++/* END */
+ src/pfr/pfrsbit.c view
@@ -0,0 +1,698 @@+/***************************************************************************/+/*                                                                         */+/*  pfrsbit.c                                                              */+/*                                                                         */+/*    FreeType PFR bitmap loader (body).                                   */+/*                                                                         */+/*  Copyright 2002, 2003, 2006, 2009, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "pfrsbit.h"+#include "pfrload.h"+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H++#include "pfrerror.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pfr+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      PFR BIT WRITER                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct  PFR_BitWriter_+  {+    FT_Byte*  line;      /* current line start                    */+    FT_Int    pitch;     /* line size in bytes                    */+    FT_Int    width;     /* width in pixels/bits                  */+    FT_Int    rows;      /* number of remaining rows to scan      */+    FT_Int    total;     /* total number of bits to draw          */++  } PFR_BitWriterRec, *PFR_BitWriter;+++  static void+  pfr_bitwriter_init( PFR_BitWriter  writer,+                      FT_Bitmap*     target,+                      FT_Bool        decreasing )+  {+    writer->line   = target->buffer;+    writer->pitch  = target->pitch;+    writer->width  = target->width;+    writer->rows   = target->rows;+    writer->total  = writer->width * writer->rows;++    if ( !decreasing )+    {+      writer->line += writer->pitch * ( target->rows-1 );+      writer->pitch = -writer->pitch;+    }+  }+++  static void+  pfr_bitwriter_decode_bytes( PFR_BitWriter  writer,+                              FT_Byte*       p,+                              FT_Byte*       limit )+  {+    FT_Int    n, reload;+    FT_Int    left = writer->width;+    FT_Byte*  cur  = writer->line;+    FT_UInt   mask = 0x80;+    FT_UInt   val  = 0;+    FT_UInt   c    = 0;+++    n = (FT_Int)( limit - p ) * 8;+    if ( n > writer->total )+      n = writer->total;++    reload = n & 7;++    for ( ; n > 0; n-- )+    {+      if ( ( n & 7 ) == reload )+        val = *p++;++      if ( val & 0x80 )+        c |= mask;++      val  <<= 1;+      mask >>= 1;++      if ( --left <= 0 )+      {+        cur[0] = (FT_Byte)c;+        left   = writer->width;+        mask   = 0x80;++        writer->line += writer->pitch;+        cur           = writer->line;+        c             = 0;+      }+      else if ( mask == 0 )+      {+        cur[0] = (FT_Byte)c;+        mask   = 0x80;+        c      = 0;+        cur ++;+      }+    }++    if ( mask != 0x80 )+      cur[0] = (FT_Byte)c;+  }+++  static void+  pfr_bitwriter_decode_rle1( PFR_BitWriter  writer,+                             FT_Byte*       p,+                             FT_Byte*       limit )+  {+    FT_Int    n, phase, count, counts[2], reload;+    FT_Int    left = writer->width;+    FT_Byte*  cur  = writer->line;+    FT_UInt   mask = 0x80;+    FT_UInt   c    = 0;+++    n = writer->total;++    phase     = 1;+    counts[0] = 0;+    counts[1] = 0;+    count     = 0;+    reload    = 1;++    for ( ; n > 0; n-- )+    {+      if ( reload )+      {+        do+        {+          if ( phase )+          {+            FT_Int  v;+++            if ( p >= limit )+              break;++            v         = *p++;+            counts[0] = v >> 4;+            counts[1] = v & 15;+            phase     = 0;+            count     = counts[0];+          }+          else+          {+            phase = 1;+            count = counts[1];+          }++        } while ( count == 0 );+      }++      if ( phase )+        c |= mask;++      mask >>= 1;++      if ( --left <= 0 )+      {+        cur[0] = (FT_Byte) c;+        left   = writer->width;+        mask   = 0x80;++        writer->line += writer->pitch;+        cur           = writer->line;+        c             = 0;+      }+      else if ( mask == 0 )+      {+        cur[0] = (FT_Byte)c;+        mask   = 0x80;+        c      = 0;+        cur ++;+      }++      reload = ( --count <= 0 );+    }++    if ( mask != 0x80 )+      cur[0] = (FT_Byte) c;+  }+++  static void+  pfr_bitwriter_decode_rle2( PFR_BitWriter  writer,+                             FT_Byte*       p,+                             FT_Byte*       limit )+  {+    FT_Int    n, phase, count, reload;+    FT_Int    left = writer->width;+    FT_Byte*  cur  = writer->line;+    FT_UInt   mask = 0x80;+    FT_UInt   c    = 0;+++    n = writer->total;++    phase  = 1;+    count  = 0;+    reload = 1;++    for ( ; n > 0; n-- )+    {+      if ( reload )+      {+        do+        {+          if ( p >= limit )+            break;++          count = *p++;+          phase = phase ^ 1;++        } while ( count == 0 );+      }++      if ( phase )+        c |= mask;++      mask >>= 1;++      if ( --left <= 0 )+      {+        cur[0] = (FT_Byte) c;+        c      = 0;+        mask   = 0x80;+        left   = writer->width;++        writer->line += writer->pitch;+        cur           = writer->line;+      }+      else if ( mask == 0 )+      {+        cur[0] = (FT_Byte)c;+        c      = 0;+        mask   = 0x80;+        cur ++;+      }++      reload = ( --count <= 0 );+    }++    if ( mask != 0x80 )+      cur[0] = (FT_Byte) c;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                  BITMAP DATA DECODING                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  pfr_lookup_bitmap_data( FT_Byte*   base,+                          FT_Byte*   limit,+                          FT_UInt    count,+                          FT_UInt    flags,+                          FT_UInt    char_code,+                          FT_ULong*  found_offset,+                          FT_ULong*  found_size )+  {+    FT_UInt   left, right, char_len;+    FT_Bool   two = FT_BOOL( flags & 1 );+    FT_Byte*  buff;+++    char_len = 4;+    if ( two )       char_len += 1;+    if ( flags & 2 ) char_len += 1;+    if ( flags & 4 ) char_len += 1;++    left  = 0;+    right = count;++    while ( left < right )+    {+      FT_UInt  middle, code;+++      middle = ( left + right ) >> 1;+      buff   = base + middle * char_len;++      /* check that we are not outside of the table -- */+      /* this is possible with broken fonts...         */+      if ( buff + char_len > limit )+        goto Fail;++      if ( two )+        code = PFR_NEXT_USHORT( buff );+      else+        code = PFR_NEXT_BYTE( buff );++      if ( code == char_code )+        goto Found_It;++      if ( code < char_code )+        left = middle;+      else+        right = middle;+    }++  Fail:+    /* Not found */+    *found_size   = 0;+    *found_offset = 0;+    return;++  Found_It:+    if ( flags & 2 )+      *found_size = PFR_NEXT_USHORT( buff );+    else+      *found_size = PFR_NEXT_BYTE( buff );++    if ( flags & 4 )+      *found_offset = PFR_NEXT_ULONG( buff );+    else+      *found_offset = PFR_NEXT_USHORT( buff );+  }+++  /* load bitmap metrics.  "*padvance" must be set to the default value */+  /* before calling this function...                                    */+  /*                                                                    */+  static FT_Error+  pfr_load_bitmap_metrics( FT_Byte**  pdata,+                           FT_Byte*   limit,+                           FT_Long    scaled_advance,+                           FT_Long   *axpos,+                           FT_Long   *aypos,+                           FT_UInt   *axsize,+                           FT_UInt   *aysize,+                           FT_Long   *aadvance,+                           FT_UInt   *aformat )+  {+    FT_Error  error = PFR_Err_Ok;+    FT_Byte   flags;+    FT_Char   b;+    FT_Byte*  p = *pdata;+    FT_Long   xpos, ypos, advance;+    FT_UInt   xsize, ysize;+++    PFR_CHECK( 1 );+    flags = PFR_NEXT_BYTE( p );++    xpos    = 0;+    ypos    = 0;+    xsize   = 0;+    ysize   = 0;+    advance = 0;++    switch ( flags & 3 )+    {+    case 0:+      PFR_CHECK( 1 );+      b    = PFR_NEXT_INT8( p );+      xpos = b >> 4;+      ypos = ( (FT_Char)( b << 4 ) ) >> 4;+      break;++    case 1:+      PFR_CHECK( 2 );+      xpos = PFR_NEXT_INT8( p );+      ypos = PFR_NEXT_INT8( p );+      break;++    case 2:+      PFR_CHECK( 4 );+      xpos = PFR_NEXT_SHORT( p );+      ypos = PFR_NEXT_SHORT( p );+      break;++    case 3:+      PFR_CHECK( 6 );+      xpos = PFR_NEXT_LONG( p );+      ypos = PFR_NEXT_LONG( p );+      break;++    default:+      ;+    }++    flags >>= 2;+    switch ( flags & 3 )+    {+    case 0:+      /* blank image */+      xsize = 0;+      ysize = 0;+      break;++    case 1:+      PFR_CHECK( 1 );+      b     = PFR_NEXT_BYTE( p );+      xsize = ( b >> 4 ) & 0xF;+      ysize = b & 0xF;+      break;++    case 2:+      PFR_CHECK( 2 );+      xsize = PFR_NEXT_BYTE( p );+      ysize = PFR_NEXT_BYTE( p );+      break;++    case 3:+      PFR_CHECK( 4 );+      xsize = PFR_NEXT_USHORT( p );+      ysize = PFR_NEXT_USHORT( p );+      break;++    default:+      ;+    }++    flags >>= 2;+    switch ( flags & 3 )+    {+    case 0:+      advance = scaled_advance;+      break;++    case 1:+      PFR_CHECK( 1 );+      advance = PFR_NEXT_INT8( p ) << 8;+      break;++    case 2:+      PFR_CHECK( 2 );+      advance = PFR_NEXT_SHORT( p );+      break;++    case 3:+      PFR_CHECK( 3 );+      advance = PFR_NEXT_LONG( p );+      break;++    default:+      ;+    }++    *axpos    = xpos;+    *aypos    = ypos;+    *axsize   = xsize;+    *aysize   = ysize;+    *aadvance = advance;+    *aformat  = flags >> 2;+    *pdata    = p;++  Exit:+    return error;++  Too_Short:+    error = PFR_Err_Invalid_Table;+    FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));+    goto Exit;+  }+++  static FT_Error+  pfr_load_bitmap_bits( FT_Byte*    p,+                        FT_Byte*    limit,+                        FT_UInt     format,+                        FT_Bool     decreasing,+                        FT_Bitmap*  target )+  {+    FT_Error          error = PFR_Err_Ok;+    PFR_BitWriterRec  writer;+++    if ( target->rows > 0 && target->width > 0 )+    {+      pfr_bitwriter_init( &writer, target, decreasing );++      switch ( format )+      {+      case 0: /* packed bits */+        pfr_bitwriter_decode_bytes( &writer, p, limit );+        break;++      case 1: /* RLE1 */+        pfr_bitwriter_decode_rle1( &writer, p, limit );+        break;++      case 2: /* RLE2 */+        pfr_bitwriter_decode_rle2( &writer, p, limit );+        break;++      default:+        FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" ));+        error = PFR_Err_Invalid_File_Format;+      }+    }++    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     BITMAP LOADING                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL( FT_Error )+  pfr_slot_load_bitmap( PFR_Slot  glyph,+                        PFR_Size  size,+                        FT_UInt   glyph_index )+  {+    FT_Error     error;+    PFR_Face     face   = (PFR_Face) glyph->root.face;+    FT_Stream    stream = face->root.stream;+    PFR_PhyFont  phys   = &face->phy_font;+    FT_ULong     gps_offset;+    FT_ULong     gps_size;+    PFR_Char     character;+    PFR_Strike   strike;+++    character = &phys->chars[glyph_index];++    /* Look-up a bitmap strike corresponding to the current */+    /* character dimensions                                 */+    {+      FT_UInt  n;+++      strike = phys->strikes;+      for ( n = 0; n < phys->num_strikes; n++ )+      {+        if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&+             strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )+        {+          goto Found_Strike;+        }++        strike++;+      }++      /* couldn't find it */+      return PFR_Err_Invalid_Argument;+    }++  Found_Strike:++    /* Now lookup the glyph's position within the file */+    {+      FT_UInt  char_len;+++      char_len = 4;+      if ( strike->flags & 1 ) char_len += 1;+      if ( strike->flags & 2 ) char_len += 1;+      if ( strike->flags & 4 ) char_len += 1;++      /* Access data directly in the frame to speed lookups */+      if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||+           FT_FRAME_ENTER( char_len * strike->num_bitmaps )        )+        goto Exit;++      pfr_lookup_bitmap_data( stream->cursor,+                              stream->limit,+                              strike->num_bitmaps,+                              strike->flags,+                              character->char_code,+                              &gps_offset,+                              &gps_size );++      FT_FRAME_EXIT();++      if ( gps_size == 0 )+      {+        /* Could not find a bitmap program string for this glyph */+        error = PFR_Err_Invalid_Argument;+        goto Exit;+      }+    }++    /* get the bitmap metrics */+    {+      FT_Long   xpos = 0, ypos = 0, advance = 0;+      FT_UInt   xsize = 0, ysize = 0, format = 0;+      FT_Byte*  p;+++      /* compute linear advance */+      advance = character->advance;+      if ( phys->metrics_resolution != phys->outline_resolution )+        advance = FT_MulDiv( advance,+                             phys->outline_resolution,+                             phys->metrics_resolution );++      glyph->root.linearHoriAdvance = advance;++      /* compute default advance, i.e., scaled advance.  This can be */+      /* overridden in the bitmap header of certain glyphs.          */+      advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,+                           character->advance,+                           phys->metrics_resolution );++      if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||+           FT_FRAME_ENTER( gps_size )                                     )+        goto Exit;++      p     = stream->cursor;+      error = pfr_load_bitmap_metrics( &p, stream->limit,+                                       advance,+                                       &xpos, &ypos,+                                       &xsize, &ysize,+                                       &advance, &format );++      /*+       * XXX: on 16bit system, we return an error for huge bitmap+       *      which causes a size truncation, because truncated+       *      size properties makes bitmap glyph broken.+       */+      if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX )+      {+        FT_TRACE1(( "pfr_slot_load_bitmap:" ));+        FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",+                     xpos, ypos ));+        error = PFR_Err_Invalid_Pixel_Size;+      }++      if ( !error )+      {+        glyph->root.format = FT_GLYPH_FORMAT_BITMAP;++        /* Set up glyph bitmap and metrics */++        /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */+        glyph->root.bitmap.width      = (FT_Int)xsize;+        glyph->root.bitmap.rows       = (FT_Int)ysize;+        glyph->root.bitmap.pitch      = (FT_Int)( xsize + 7 ) >> 3;+        glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;++        /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */+        glyph->root.metrics.width        = (FT_Pos)xsize << 6;+        glyph->root.metrics.height       = (FT_Pos)ysize << 6;+        glyph->root.metrics.horiBearingX = xpos << 6;+        glyph->root.metrics.horiBearingY = ypos << 6;+        glyph->root.metrics.horiAdvance  = FT_PIX_ROUND( ( advance >> 2 ) );+        glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;+        glyph->root.metrics.vertBearingY = 0;+        glyph->root.metrics.vertAdvance  = size->root.metrics.height;++        /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */+        glyph->root.bitmap_left = (FT_Int)xpos;+        glyph->root.bitmap_top  = (FT_Int)(ypos + ysize);++        /* Allocate and read bitmap data */+        {+          FT_ULong  len = glyph->root.bitmap.pitch * ysize;+++          error = ft_glyphslot_alloc_bitmap( &glyph->root, len );+          if ( !error )+          {+            error = pfr_load_bitmap_bits(+                      p,+                      stream->limit,+                      format,+                      FT_BOOL(face->header.color_flags & 2),+                      &glyph->root.bitmap );+          }+        }+      }++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }++/* END */
+ src/pfr/pfrsbit.h view
@@ -0,0 +1,36 @@+/***************************************************************************/+/*                                                                         */+/*  pfrsbit.h                                                              */+/*                                                                         */+/*    FreeType PFR bitmap loader (specification).                          */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRSBIT_H__+#define __PFRSBIT_H__++#include "pfrobjs.h"++FT_BEGIN_HEADER++  FT_LOCAL( FT_Error )+  pfr_slot_load_bitmap( PFR_Slot  glyph,+                        PFR_Size  size,+                        FT_UInt   glyph_index );++FT_END_HEADER++#endif /* __PFR_SBIT_H__ */+++/* END */
+ src/pfr/pfrtypes.h view
@@ -0,0 +1,362 @@+/***************************************************************************/+/*                                                                         */+/*  pfrtypes.h                                                             */+/*                                                                         */+/*    FreeType PFR data structures (specification only).                   */+/*                                                                         */+/*  Copyright 2002, 2003, 2005, 2007 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PFRTYPES_H__+#define __PFRTYPES_H__++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H++FT_BEGIN_HEADER++  /************************************************************************/++  /* the PFR Header structure */+  typedef struct  PFR_HeaderRec_+  {+    FT_UInt32  signature;+    FT_UInt    version;+    FT_UInt    signature2;+    FT_UInt    header_size;++    FT_UInt    log_dir_size;+    FT_UInt    log_dir_offset;++    FT_UInt    log_font_max_size;+    FT_UInt32  log_font_section_size;+    FT_UInt32  log_font_section_offset;++    FT_UInt32  phy_font_max_size;+    FT_UInt32  phy_font_section_size;+    FT_UInt32  phy_font_section_offset;++    FT_UInt    gps_max_size;+    FT_UInt32  gps_section_size;+    FT_UInt32  gps_section_offset;++    FT_UInt    max_blue_values;+    FT_UInt    max_x_orus;+    FT_UInt    max_y_orus;++    FT_UInt    phy_font_max_size_high;+    FT_UInt    color_flags;++    FT_UInt32  bct_max_size;+    FT_UInt32  bct_set_max_size;+    FT_UInt32  phy_bct_set_max_size;++    FT_UInt    num_phy_fonts;+    FT_UInt    max_vert_stem_snap;+    FT_UInt    max_horz_stem_snap;+    FT_UInt    max_chars;++  } PFR_HeaderRec, *PFR_Header;+++  /* used in `color_flags' field of the PFR_Header */+  typedef enum  PFR_HeaderFlags_+  {+    PFR_FLAG_BLACK_PIXEL   = 1,+    PFR_FLAG_INVERT_BITMAP = 2++  } PFR_HeaderFlags;+++  /************************************************************************/++  typedef struct  PFR_LogFontRec_+  {+    FT_UInt32  size;+    FT_UInt32  offset;++    FT_Int32   matrix[4];+    FT_UInt    stroke_flags;+    FT_Int     stroke_thickness;+    FT_Int     bold_thickness;+    FT_Int32   miter_limit;++    FT_UInt32  phys_size;+    FT_UInt32  phys_offset;++  } PFR_LogFontRec, *PFR_LogFont;+++  typedef enum  PFR_LogFlags_+  {+    PFR_LOG_EXTRA_ITEMS  = 0x40,+    PFR_LOG_2BYTE_BOLD   = 0x20,+    PFR_LOG_BOLD         = 0x10,+    PFR_LOG_2BYTE_STROKE = 8,+    PFR_LOG_STROKE       = 4,+    PFR_LINE_JOIN_MASK   = 3++  } PFR_LogFlags;+++  typedef enum  PFR_LineJoinFlags_+  {+    PFR_LINE_JOIN_MITER = 0,+    PFR_LINE_JOIN_ROUND = 1,+    PFR_LINE_JOIN_BEVEL = 2++  } PFR_LineJoinFlags;+++  /************************************************************************/++  typedef enum  PFR_BitmapFlags_+  {+    PFR_BITMAP_3BYTE_OFFSET   = 4,+    PFR_BITMAP_2BYTE_SIZE     = 2,+    PFR_BITMAP_2BYTE_CHARCODE = 1++  } PFR_BitmapFlags;+++  typedef struct  PFR_BitmapCharRec_+  {+    FT_UInt    char_code;+    FT_UInt    gps_size;+    FT_UInt32  gps_offset;++  } PFR_BitmapCharRec, *PFR_BitmapChar;+++  typedef enum  PFR_StrikeFlags_+  {+    PFR_STRIKE_2BYTE_COUNT  = 0x10,+    PFR_STRIKE_3BYTE_OFFSET = 0x08,+    PFR_STRIKE_3BYTE_SIZE   = 0x04,+    PFR_STRIKE_2BYTE_YPPM   = 0x02,+    PFR_STRIKE_2BYTE_XPPM   = 0x01++  } PFR_StrikeFlags;+++  typedef struct  PFR_StrikeRec_+  {+    FT_UInt         x_ppm;+    FT_UInt         y_ppm;+    FT_UInt         flags;++    FT_UInt32       gps_size;+    FT_UInt32       gps_offset;++    FT_UInt32       bct_size;+    FT_UInt32       bct_offset;++    /* optional */+    FT_UInt         num_bitmaps;+    PFR_BitmapChar  bitmaps;++  } PFR_StrikeRec, *PFR_Strike;+++  /************************************************************************/++  typedef struct  PFR_CharRec_+  {+    FT_UInt    char_code;+    FT_Int     advance;+    FT_UInt    gps_size;+    FT_UInt32  gps_offset;++  } PFR_CharRec, *PFR_Char;+++  /************************************************************************/++  typedef struct  PFR_DimensionRec_+  {+    FT_UInt  standard;+    FT_UInt  num_stem_snaps;+    FT_Int*  stem_snaps;++  } PFR_DimensionRec, *PFR_Dimension;++  /************************************************************************/++  typedef struct PFR_KernItemRec_*  PFR_KernItem;++  typedef struct  PFR_KernItemRec_+  {+    PFR_KernItem  next;+    FT_Byte       pair_count;+    FT_Byte       flags;+    FT_Short      base_adj;+    FT_UInt       pair_size;+    FT_Offset     offset;+    FT_UInt32     pair1;+    FT_UInt32     pair2;++  } PFR_KernItemRec;+++#define PFR_KERN_INDEX( g1, g2 )                          \+          ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) )++#define PFR_KERN_PAIR_INDEX( pair )                        \+          PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 )++#define PFR_NEXT_KPAIR( p )  ( p += 2,                              \+                               ( (FT_UInt32)p[-2] << 16 ) | p[-1] )+++  /************************************************************************/++  typedef struct  PFR_PhyFontRec_+  {+    FT_Memory          memory;+    FT_UInt32          offset;++    FT_UInt            font_ref_number;+    FT_UInt            outline_resolution;+    FT_UInt            metrics_resolution;+    FT_BBox            bbox;+    FT_UInt            flags;+    FT_UInt            standard_advance;++    FT_Int             ascent;   /* optional, bbox.yMax if not present */+    FT_Int             descent;  /* optional, bbox.yMin if not present */+    FT_Int             leading;  /* optional, 0 if not present         */++    PFR_DimensionRec   horizontal;+    PFR_DimensionRec   vertical;++    FT_String*         font_id;+    FT_String*         family_name;+    FT_String*         style_name;++    FT_UInt            num_strikes;+    FT_UInt            max_strikes;+    PFR_StrikeRec*     strikes;++    FT_UInt            num_blue_values;+    FT_Int            *blue_values;+    FT_UInt            blue_fuzz;+    FT_UInt            blue_scale;++    FT_UInt            num_chars;+    FT_Offset          chars_offset;+    PFR_Char           chars;++    FT_UInt            num_kern_pairs;+    PFR_KernItem       kern_items;+    PFR_KernItem*      kern_items_tail;++    /* not part of the spec, but used during load */+    FT_Long            bct_offset;+    FT_Byte*           cursor;++  } PFR_PhyFontRec, *PFR_PhyFont;+++  typedef enum  PFR_PhyFlags_+  {+    PFR_PHY_EXTRA_ITEMS      = 0x80,+    PFR_PHY_3BYTE_GPS_OFFSET = 0x20,+    PFR_PHY_2BYTE_GPS_SIZE   = 0x10,+    PFR_PHY_ASCII_CODE       = 0x08,+    PFR_PHY_PROPORTIONAL     = 0x04,+    PFR_PHY_2BYTE_CHARCODE   = 0x02,+    PFR_PHY_VERTICAL         = 0x01++  } PFR_PhyFlags;+++  typedef enum PFR_KernFlags_+  {+    PFR_KERN_2BYTE_CHAR  = 0x01,+    PFR_KERN_2BYTE_ADJ   = 0x02++  } PFR_KernFlags;+++  /************************************************************************/++  typedef enum  PFR_GlyphFlags_+  {+    PFR_GLYPH_IS_COMPOUND   = 0x80,+    PFR_GLYPH_EXTRA_ITEMS   = 0x08,+    PFR_GLYPH_1BYTE_XYCOUNT = 0x04,+    PFR_GLYPH_XCOUNT        = 0x02,+    PFR_GLYPH_YCOUNT        = 0x01++  } PFR_GlyphFlags;+++  /* controlled coordinate */+  typedef struct  PFR_CoordRec_+  {+    FT_UInt  org;+    FT_UInt  cur;++  } PFR_CoordRec, *PFR_Coord;+++  typedef struct  PFR_SubGlyphRec_+  {+    FT_Fixed   x_scale;+    FT_Fixed   y_scale;+    FT_Int     x_delta;+    FT_Int     y_delta;+    FT_UInt32  gps_offset;+    FT_UInt    gps_size;++  } PFR_SubGlyphRec, *PFR_SubGlyph;+++  typedef enum  PFR_SubgGlyphFlags_+  {+    PFR_SUBGLYPH_3BYTE_OFFSET = 0x80,+    PFR_SUBGLYPH_2BYTE_SIZE   = 0x40,+    PFR_SUBGLYPH_YSCALE       = 0x20,+    PFR_SUBGLYPH_XSCALE       = 0x10++  } PFR_SubGlyphFlags;+++  typedef struct  PFR_GlyphRec_+  {+    FT_Byte           format;++#if 0+    FT_UInt           num_x_control;+    FT_UInt           num_y_control;+#endif+    FT_UInt           max_xy_control;+    FT_Pos*           x_control;+    FT_Pos*           y_control;+++    FT_UInt           num_subs;+    FT_UInt           max_subs;+    PFR_SubGlyphRec*  subs;++    FT_GlyphLoader    loader;+    FT_Bool           path_begun;++  } PFR_GlyphRec, *PFR_Glyph;+++FT_END_HEADER++#endif /* __PFRTYPES_H__ */+++/* END */
+ src/psaux/afmparse.c view
@@ -0,0 +1,964 @@+/***************************************************************************/+/*                                                                         */+/*  afmparse.c                                                             */+/*                                                                         */+/*    AFM parser (body).                                                   */+/*                                                                         */+/*  Copyright 2006, 2007, 2008, 2009, 2010 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H++#include "afmparse.h"+#include "psconv.h"++#include "psauxerr.h"+++/***************************************************************************/+/*                                                                         */+/*    AFM_Stream                                                           */+/*                                                                         */+/* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib.  */+/*                                                                         */+/*                                                                         */++  enum+  {+    AFM_STREAM_STATUS_NORMAL,+    AFM_STREAM_STATUS_EOC,+    AFM_STREAM_STATUS_EOL,+    AFM_STREAM_STATUS_EOF+  };+++  typedef struct  AFM_StreamRec_+  {+    FT_Byte*  cursor;+    FT_Byte*  base;+    FT_Byte*  limit;++    FT_Int    status;++  } AFM_StreamRec;+++#ifndef EOF+#define EOF -1+#endif+++  /* this works because empty lines are ignored */+#define AFM_IS_NEWLINE( ch )  ( (ch) == '\r' || (ch) == '\n' )++#define AFM_IS_EOF( ch )      ( (ch) == EOF  || (ch) == '\x1a' )+#define AFM_IS_SPACE( ch )    ( (ch) == ' '  || (ch) == '\t' )++  /* column separator; there is no `column' in the spec actually */+#define AFM_IS_SEP( ch )      ( (ch) == ';' )++#define AFM_GETC()                                                       \+          ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \+                                                   : EOF )++#define AFM_STREAM_KEY_BEGIN( stream )    \+          (char*)( (stream)->cursor - 1 )++#define AFM_STREAM_KEY_LEN( stream, key )       \+          ( (char*)(stream)->cursor - key - 1 )++#define AFM_STATUS_EOC( stream ) \+          ( (stream)->status >= AFM_STREAM_STATUS_EOC )++#define AFM_STATUS_EOL( stream ) \+          ( (stream)->status >= AFM_STREAM_STATUS_EOL )++#define AFM_STATUS_EOF( stream ) \+          ( (stream)->status >= AFM_STREAM_STATUS_EOF )+++  static int+  afm_stream_skip_spaces( AFM_Stream  stream )+  {+    int  ch = 0;  /* make stupid compiler happy */+++    if ( AFM_STATUS_EOC( stream ) )+      return ';';++    while ( 1 )+    {+      ch = AFM_GETC();+      if ( !AFM_IS_SPACE( ch ) )+        break;+    }++    if ( AFM_IS_NEWLINE( ch ) )+      stream->status = AFM_STREAM_STATUS_EOL;+    else if ( AFM_IS_SEP( ch ) )+      stream->status = AFM_STREAM_STATUS_EOC;+    else if ( AFM_IS_EOF( ch ) )+      stream->status = AFM_STREAM_STATUS_EOF;++    return ch;+  }+++  /* read a key or value in current column */+  static char*+  afm_stream_read_one( AFM_Stream  stream )+  {+    char*  str;+    int    ch;+++    afm_stream_skip_spaces( stream );+    if ( AFM_STATUS_EOC( stream ) )+      return NULL;++    str = AFM_STREAM_KEY_BEGIN( stream );++    while ( 1 )+    {+      ch = AFM_GETC();+      if ( AFM_IS_SPACE( ch ) )+        break;+      else if ( AFM_IS_NEWLINE( ch ) )+      {+        stream->status = AFM_STREAM_STATUS_EOL;+        break;+      }+      else if ( AFM_IS_SEP( ch ) )+      {+        stream->status = AFM_STREAM_STATUS_EOC;+        break;+      }+      else if ( AFM_IS_EOF( ch ) )+      {+        stream->status = AFM_STREAM_STATUS_EOF;+        break;+      }+    }++    return str;+  }+++  /* read a string (i.e., read to EOL) */+  static char*+  afm_stream_read_string( AFM_Stream  stream )+  {+    char*  str;+    int    ch;+++    afm_stream_skip_spaces( stream );+    if ( AFM_STATUS_EOL( stream ) )+      return NULL;++    str = AFM_STREAM_KEY_BEGIN( stream );++    /* scan to eol */+    while ( 1 )+    {+      ch = AFM_GETC();+      if ( AFM_IS_NEWLINE( ch ) )+      {+        stream->status = AFM_STREAM_STATUS_EOL;+        break;+      }+      else if ( AFM_IS_EOF( ch ) )+      {+        stream->status = AFM_STREAM_STATUS_EOF;+        break;+      }+    }++    return str;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*    AFM_Parser                                                         */+  /*                                                                       */+  /*                                                                       */++  /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */+  typedef enum  AFM_Token_+  {+    AFM_TOKEN_ASCENDER,+    AFM_TOKEN_AXISLABEL,+    AFM_TOKEN_AXISTYPE,+    AFM_TOKEN_B,+    AFM_TOKEN_BLENDAXISTYPES,+    AFM_TOKEN_BLENDDESIGNMAP,+    AFM_TOKEN_BLENDDESIGNPOSITIONS,+    AFM_TOKEN_C,+    AFM_TOKEN_CC,+    AFM_TOKEN_CH,+    AFM_TOKEN_CAPHEIGHT,+    AFM_TOKEN_CHARWIDTH,+    AFM_TOKEN_CHARACTERSET,+    AFM_TOKEN_CHARACTERS,+    AFM_TOKEN_DESCENDER,+    AFM_TOKEN_ENCODINGSCHEME,+    AFM_TOKEN_ENDAXIS,+    AFM_TOKEN_ENDCHARMETRICS,+    AFM_TOKEN_ENDCOMPOSITES,+    AFM_TOKEN_ENDDIRECTION,+    AFM_TOKEN_ENDFONTMETRICS,+    AFM_TOKEN_ENDKERNDATA,+    AFM_TOKEN_ENDKERNPAIRS,+    AFM_TOKEN_ENDTRACKKERN,+    AFM_TOKEN_ESCCHAR,+    AFM_TOKEN_FAMILYNAME,+    AFM_TOKEN_FONTBBOX,+    AFM_TOKEN_FONTNAME,+    AFM_TOKEN_FULLNAME,+    AFM_TOKEN_ISBASEFONT,+    AFM_TOKEN_ISCIDFONT,+    AFM_TOKEN_ISFIXEDPITCH,+    AFM_TOKEN_ISFIXEDV,+    AFM_TOKEN_ITALICANGLE,+    AFM_TOKEN_KP,+    AFM_TOKEN_KPH,+    AFM_TOKEN_KPX,+    AFM_TOKEN_KPY,+    AFM_TOKEN_L,+    AFM_TOKEN_MAPPINGSCHEME,+    AFM_TOKEN_METRICSSETS,+    AFM_TOKEN_N,+    AFM_TOKEN_NOTICE,+    AFM_TOKEN_PCC,+    AFM_TOKEN_STARTAXIS,+    AFM_TOKEN_STARTCHARMETRICS,+    AFM_TOKEN_STARTCOMPOSITES,+    AFM_TOKEN_STARTDIRECTION,+    AFM_TOKEN_STARTFONTMETRICS,+    AFM_TOKEN_STARTKERNDATA,+    AFM_TOKEN_STARTKERNPAIRS,+    AFM_TOKEN_STARTKERNPAIRS0,+    AFM_TOKEN_STARTKERNPAIRS1,+    AFM_TOKEN_STARTTRACKKERN,+    AFM_TOKEN_STDHW,+    AFM_TOKEN_STDVW,+    AFM_TOKEN_TRACKKERN,+    AFM_TOKEN_UNDERLINEPOSITION,+    AFM_TOKEN_UNDERLINETHICKNESS,+    AFM_TOKEN_VV,+    AFM_TOKEN_VVECTOR,+    AFM_TOKEN_VERSION,+    AFM_TOKEN_W,+    AFM_TOKEN_W0,+    AFM_TOKEN_W0X,+    AFM_TOKEN_W0Y,+    AFM_TOKEN_W1,+    AFM_TOKEN_W1X,+    AFM_TOKEN_W1Y,+    AFM_TOKEN_WX,+    AFM_TOKEN_WY,+    AFM_TOKEN_WEIGHT,+    AFM_TOKEN_WEIGHTVECTOR,+    AFM_TOKEN_XHEIGHT,+    N_AFM_TOKENS,+    AFM_TOKEN_UNKNOWN++  } AFM_Token;+++  static const char*  const afm_key_table[N_AFM_TOKENS] =+  {+    "Ascender",+    "AxisLabel",+    "AxisType",+    "B",+    "BlendAxisTypes",+    "BlendDesignMap",+    "BlendDesignPositions",+    "C",+    "CC",+    "CH",+    "CapHeight",+    "CharWidth",+    "CharacterSet",+    "Characters",+    "Descender",+    "EncodingScheme",+    "EndAxis",+    "EndCharMetrics",+    "EndComposites",+    "EndDirection",+    "EndFontMetrics",+    "EndKernData",+    "EndKernPairs",+    "EndTrackKern",+    "EscChar",+    "FamilyName",+    "FontBBox",+    "FontName",+    "FullName",+    "IsBaseFont",+    "IsCIDFont",+    "IsFixedPitch",+    "IsFixedV",+    "ItalicAngle",+    "KP",+    "KPH",+    "KPX",+    "KPY",+    "L",+    "MappingScheme",+    "MetricsSets",+    "N",+    "Notice",+    "PCC",+    "StartAxis",+    "StartCharMetrics",+    "StartComposites",+    "StartDirection",+    "StartFontMetrics",+    "StartKernData",+    "StartKernPairs",+    "StartKernPairs0",+    "StartKernPairs1",+    "StartTrackKern",+    "StdHW",+    "StdVW",+    "TrackKern",+    "UnderlinePosition",+    "UnderlineThickness",+    "VV",+    "VVector",+    "Version",+    "W",+    "W0",+    "W0X",+    "W0Y",+    "W1",+    "W1X",+    "W1Y",+    "WX",+    "WY",+    "Weight",+    "WeightVector",+    "XHeight"+  };+++  /*+   * `afm_parser_read_vals' and `afm_parser_next_key' provide+   * high-level operations to an AFM_Stream.  The rest of the+   * parser functions should use them without accessing the+   * AFM_Stream directly.+   */++  FT_LOCAL_DEF( FT_Int )+  afm_parser_read_vals( AFM_Parser  parser,+                        AFM_Value   vals,+                        FT_UInt     n )+  {+    AFM_Stream  stream = parser->stream;+    char*       str;+    FT_UInt     i;+++    if ( n > AFM_MAX_ARGUMENTS )+      return 0;++    for ( i = 0; i < n; i++ )+    {+      FT_Offset  len;+      AFM_Value  val = vals + i;+++      if ( val->type == AFM_VALUE_TYPE_STRING )+        str = afm_stream_read_string( stream );+      else+        str = afm_stream_read_one( stream );++      if ( !str )+        break;++      len = AFM_STREAM_KEY_LEN( stream, str );++      switch ( val->type )+      {+      case AFM_VALUE_TYPE_STRING:+      case AFM_VALUE_TYPE_NAME:+        {+          FT_Memory  memory = parser->memory;+          FT_Error   error;+++          if ( !FT_QALLOC( val->u.s, len + 1 ) )+          {+            ft_memcpy( val->u.s, str, len );+            val->u.s[len] = '\0';+          }+        }+        break;++      case AFM_VALUE_TYPE_FIXED:+        val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str,+                                    (FT_Byte*)str + len, 0 );+        break;++      case AFM_VALUE_TYPE_INTEGER:+        val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str,+                                  (FT_Byte*)str + len );+        break;++      case AFM_VALUE_TYPE_BOOL:+        val->u.b = FT_BOOL( len == 4                      &&+                            !ft_strncmp( str, "true", 4 ) );+        break;++      case AFM_VALUE_TYPE_INDEX:+        if ( parser->get_index )+          val->u.i = parser->get_index( str, len, parser->user_data );+        else+          val->u.i = 0;+        break;+      }+    }++    return i;+  }+++  FT_LOCAL_DEF( char* )+  afm_parser_next_key( AFM_Parser  parser,+                       FT_Bool     line,+                       FT_Offset*  len )+  {+    AFM_Stream  stream = parser->stream;+    char*       key    = 0;  /* make stupid compiler happy */+++    if ( line )+    {+      while ( 1 )+      {+        /* skip current line */+        if ( !AFM_STATUS_EOL( stream ) )+          afm_stream_read_string( stream );++        stream->status = AFM_STREAM_STATUS_NORMAL;+        key = afm_stream_read_one( stream );++        /* skip empty line */+        if ( !key                      &&+             !AFM_STATUS_EOF( stream ) &&+             AFM_STATUS_EOL( stream )  )+          continue;++        break;+      }+    }+    else+    {+      while ( 1 )+      {+        /* skip current column */+        while ( !AFM_STATUS_EOC( stream ) )+          afm_stream_read_one( stream );++        stream->status = AFM_STREAM_STATUS_NORMAL;+        key = afm_stream_read_one( stream );++        /* skip empty column */+        if ( !key                      &&+             !AFM_STATUS_EOF( stream ) &&+             AFM_STATUS_EOC( stream )  )+          continue;++        break;+      }+    }++    if ( len )+      *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )+                     : 0;++    return key;+  }+++  static AFM_Token+  afm_tokenize( const char*  key,+                FT_Offset    len )+  {+    int  n;+++    for ( n = 0; n < N_AFM_TOKENS; n++ )+    {+      if ( *( afm_key_table[n] ) == *key )+      {+        for ( ; n < N_AFM_TOKENS; n++ )+        {+          if ( *( afm_key_table[n] ) != *key )+            return AFM_TOKEN_UNKNOWN;++          if ( ft_strncmp( afm_key_table[n], key, len ) == 0 )+            return (AFM_Token) n;+        }+      }+    }++    return AFM_TOKEN_UNKNOWN;+  }+++  FT_LOCAL_DEF( FT_Error )+  afm_parser_init( AFM_Parser  parser,+                   FT_Memory   memory,+                   FT_Byte*    base,+                   FT_Byte*    limit )+  {+    AFM_Stream  stream = NULL;+    FT_Error    error;+++    if ( FT_NEW( stream ) )+      return error;++    stream->cursor = stream->base = base;+    stream->limit  = limit;++    /* don't skip the first line during the first call */+    stream->status = AFM_STREAM_STATUS_EOL;++    parser->memory    = memory;+    parser->stream    = stream;+    parser->FontInfo  = NULL;+    parser->get_index = NULL;++    return PSaux_Err_Ok;+  }+++  FT_LOCAL( void )+  afm_parser_done( AFM_Parser  parser )+  {+    FT_Memory  memory = parser->memory;+++    FT_FREE( parser->stream );+  }+++  FT_LOCAL_DEF( FT_Error )+  afm_parser_read_int( AFM_Parser  parser,+                       FT_Int*     aint )+  {+    AFM_ValueRec  val;+++    val.type = AFM_VALUE_TYPE_INTEGER;++    if ( afm_parser_read_vals( parser, &val, 1 ) == 1 )+    {+      *aint = val.u.i;++      return PSaux_Err_Ok;+    }+    else+      return PSaux_Err_Syntax_Error;+  }+++  static FT_Error+  afm_parse_track_kern( AFM_Parser  parser )+  {+    AFM_FontInfo   fi = parser->FontInfo;+    AFM_TrackKern  tk;+    char*          key;+    FT_Offset      len;+    int            n = -1;+++    if ( afm_parser_read_int( parser, &fi->NumTrackKern ) )+        goto Fail;++    if ( fi->NumTrackKern )+    {+      FT_Memory  memory = parser->memory;+      FT_Error   error;+++      if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) )+        return error;+    }++    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )+    {+      AFM_ValueRec  shared_vals[5];+++      switch ( afm_tokenize( key, len ) )+      {+      case AFM_TOKEN_TRACKKERN:+        n++;++        if ( n >= fi->NumTrackKern )+          goto Fail;++        tk = fi->TrackKerns + n;++        shared_vals[0].type = AFM_VALUE_TYPE_INTEGER;+        shared_vals[1].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[2].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[3].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[4].type = AFM_VALUE_TYPE_FIXED;+        if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )+          goto Fail;++        tk->degree     = shared_vals[0].u.i;+        tk->min_ptsize = shared_vals[1].u.f;+        tk->min_kern   = shared_vals[2].u.f;+        tk->max_ptsize = shared_vals[3].u.f;+        tk->max_kern   = shared_vals[4].u.f;++        /* is this correct? */+        if ( tk->degree < 0 && tk->min_kern > 0 )+          tk->min_kern = -tk->min_kern;+        break;++      case AFM_TOKEN_ENDTRACKKERN:+      case AFM_TOKEN_ENDKERNDATA:+      case AFM_TOKEN_ENDFONTMETRICS:+        fi->NumTrackKern = n + 1;+        return PSaux_Err_Ok;++      case AFM_TOKEN_UNKNOWN:+        break;++      default:+        goto Fail;+      }+    }++  Fail:+    return PSaux_Err_Syntax_Error;+  }+++#undef  KERN_INDEX+#define KERN_INDEX( g1, g2 )  ( ( (FT_ULong)g1 << 16 ) | g2 )+++  /* compare two kerning pairs */+  FT_CALLBACK_DEF( int )+  afm_compare_kern_pairs( const void*  a,+                          const void*  b )+  {+    AFM_KernPair  kp1 = (AFM_KernPair)a;+    AFM_KernPair  kp2 = (AFM_KernPair)b;++    FT_ULong  index1 = KERN_INDEX( kp1->index1, kp1->index2 );+    FT_ULong  index2 = KERN_INDEX( kp2->index1, kp2->index2 );+++    if ( index1 > index2 )+      return 1;+    else if ( index1 < index2 )+      return -1;+    else+      return 0;+  }+++  static FT_Error+  afm_parse_kern_pairs( AFM_Parser  parser )+  {+    AFM_FontInfo  fi = parser->FontInfo;+    AFM_KernPair  kp;+    char*         key;+    FT_Offset     len;+    int           n = -1;+++    if ( afm_parser_read_int( parser, &fi->NumKernPair ) )+      goto Fail;++    if ( fi->NumKernPair )+    {+      FT_Memory  memory = parser->memory;+      FT_Error   error;+++      if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )+        return error;+    }++    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )+    {+      AFM_Token  token = afm_tokenize( key, len );+++      switch ( token )+      {+      case AFM_TOKEN_KP:+      case AFM_TOKEN_KPX:+      case AFM_TOKEN_KPY:+        {+          FT_Int        r;+          AFM_ValueRec  shared_vals[4];+++          n++;++          if ( n >= fi->NumKernPair )+            goto Fail;++          kp = fi->KernPairs + n;++          shared_vals[0].type = AFM_VALUE_TYPE_INDEX;+          shared_vals[1].type = AFM_VALUE_TYPE_INDEX;+          shared_vals[2].type = AFM_VALUE_TYPE_INTEGER;+          shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;+          r = afm_parser_read_vals( parser, shared_vals, 4 );+          if ( r < 3 )+            goto Fail;++          kp->index1 = shared_vals[0].u.i;+          kp->index2 = shared_vals[1].u.i;+          if ( token == AFM_TOKEN_KPY )+          {+            kp->x = 0;+            kp->y = shared_vals[2].u.i;+          }+          else+          {+            kp->x = shared_vals[2].u.i;+            kp->y = ( token == AFM_TOKEN_KP && r == 4 )+                      ? shared_vals[3].u.i : 0;+          }+        }+        break;++      case AFM_TOKEN_ENDKERNPAIRS:+      case AFM_TOKEN_ENDKERNDATA:+      case AFM_TOKEN_ENDFONTMETRICS:+        fi->NumKernPair = n + 1;+        ft_qsort( fi->KernPairs, fi->NumKernPair,+                  sizeof( AFM_KernPairRec ),+                  afm_compare_kern_pairs );+        return PSaux_Err_Ok;++      case AFM_TOKEN_UNKNOWN:+        break;++      default:+        goto Fail;+      }+    }++  Fail:+    return PSaux_Err_Syntax_Error;+  }+++  static FT_Error+  afm_parse_kern_data( AFM_Parser  parser )+  {+    FT_Error   error;+    char*      key;+    FT_Offset  len;+++    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )+    {+      switch ( afm_tokenize( key, len ) )+      {+      case AFM_TOKEN_STARTTRACKKERN:+        error = afm_parse_track_kern( parser );+        if ( error )+          return error;+        break;++      case AFM_TOKEN_STARTKERNPAIRS:+      case AFM_TOKEN_STARTKERNPAIRS0:+        error = afm_parse_kern_pairs( parser );+        if ( error )+          return error;+        break;++      case AFM_TOKEN_ENDKERNDATA:+      case AFM_TOKEN_ENDFONTMETRICS:+        return PSaux_Err_Ok;++      case AFM_TOKEN_UNKNOWN:+        break;++      default:+        goto Fail;+      }+    }++  Fail:+    return PSaux_Err_Syntax_Error;+  }+++  static FT_Error+  afm_parser_skip_section( AFM_Parser  parser,+                           FT_UInt     n,+                           AFM_Token   end_section )+  {+    char*      key;+    FT_Offset  len;+++    while ( n-- > 0 )+    {+      key = afm_parser_next_key( parser, 1, NULL );+      if ( !key )+        goto Fail;+    }++    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )+    {+      AFM_Token  token = afm_tokenize( key, len );+++      if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS )+        return PSaux_Err_Ok;+    }++  Fail:+    return PSaux_Err_Syntax_Error;+  }+++  FT_LOCAL_DEF( FT_Error )+  afm_parser_parse( AFM_Parser  parser )+  {+    FT_Memory     memory = parser->memory;+    AFM_FontInfo  fi     = parser->FontInfo;+    FT_Error      error  = PSaux_Err_Syntax_Error;+    char*         key;+    FT_Offset     len;+    FT_Int        metrics_sets = 0;+++    if ( !fi )+      return PSaux_Err_Invalid_Argument;++    key = afm_parser_next_key( parser, 1, &len );+    if ( !key || len != 16                              ||+         ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )+      return PSaux_Err_Unknown_File_Format;++    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )+    {+      AFM_ValueRec  shared_vals[4];+++      switch ( afm_tokenize( key, len ) )+      {+      case AFM_TOKEN_METRICSSETS:+        if ( afm_parser_read_int( parser, &metrics_sets ) )+          goto Fail;++        if ( metrics_sets != 0 && metrics_sets != 2 )+        {+          error = PSaux_Err_Unimplemented_Feature;++          goto Fail;+        }+        break;++      case AFM_TOKEN_ISCIDFONT:+        shared_vals[0].type = AFM_VALUE_TYPE_BOOL;+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )+          goto Fail;++        fi->IsCIDFont = shared_vals[0].u.b;+        break;++      case AFM_TOKEN_FONTBBOX:+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[1].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[2].type = AFM_VALUE_TYPE_FIXED;+        shared_vals[3].type = AFM_VALUE_TYPE_FIXED;+        if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 )+          goto Fail;++        fi->FontBBox.xMin = shared_vals[0].u.f;+        fi->FontBBox.yMin = shared_vals[1].u.f;+        fi->FontBBox.xMax = shared_vals[2].u.f;+        fi->FontBBox.yMax = shared_vals[3].u.f;+        break;++      case AFM_TOKEN_ASCENDER:+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )+          goto Fail;++        fi->Ascender = shared_vals[0].u.f;+        break;++      case AFM_TOKEN_DESCENDER:+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )+          goto Fail;++        fi->Descender = shared_vals[0].u.f;+        break;++      case AFM_TOKEN_STARTCHARMETRICS:+        {+          FT_Int  n = 0;+++          if ( afm_parser_read_int( parser, &n ) )+            goto Fail;++          error = afm_parser_skip_section( parser, n,+                                           AFM_TOKEN_ENDCHARMETRICS );+          if ( error )+            return error;+        }+        break;++      case AFM_TOKEN_STARTKERNDATA:+        error = afm_parse_kern_data( parser );+        if ( error )+          goto Fail;+        /* fall through since we only support kern data */++      case AFM_TOKEN_ENDFONTMETRICS:+        return PSaux_Err_Ok;++      default:+        break;+      }+    }++  Fail:+    FT_FREE( fi->TrackKerns );+    fi->NumTrackKern = 0;++    FT_FREE( fi->KernPairs );+    fi->NumKernPair = 0;++    fi->IsCIDFont = 0;++    return error;+  }+++/* END */
+ src/psaux/afmparse.h view
@@ -0,0 +1,88 @@+/***************************************************************************/+/*                                                                         */+/*  afmparse.h                                                             */+/*                                                                         */+/*    AFM parser (specification).                                          */+/*                                                                         */+/*  Copyright 2006 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __AFMPARSE_H__+#define __AFMPARSE_H__+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  afm_parser_init( AFM_Parser  parser,+                   FT_Memory   memory,+                   FT_Byte*    base,+                   FT_Byte*    limit );+++  FT_LOCAL( void )+  afm_parser_done( AFM_Parser  parser );+++  FT_LOCAL( FT_Error )+  afm_parser_parse( AFM_Parser  parser );+++  enum  AFM_ValueType_+  {+    AFM_VALUE_TYPE_STRING,+    AFM_VALUE_TYPE_NAME,+    AFM_VALUE_TYPE_FIXED,   /* real number */+    AFM_VALUE_TYPE_INTEGER,+    AFM_VALUE_TYPE_BOOL,+    AFM_VALUE_TYPE_INDEX    /* glyph index */+  };+++  typedef struct  AFM_ValueRec_+  {+    enum AFM_ValueType_  type;+    union+    {+      char*     s;+      FT_Fixed  f;+      FT_Int    i;+      FT_Bool   b;++    } u;++  } AFM_ValueRec, *AFM_Value;++#define  AFM_MAX_ARGUMENTS  5++  FT_LOCAL( FT_Int )+  afm_parser_read_vals( AFM_Parser  parser,+                        AFM_Value   vals,+                        FT_UInt     n );++  /* read the next key from the next line or column */+  FT_LOCAL( char* )+  afm_parser_next_key( AFM_Parser  parser,+                       FT_Bool     line,+                       FT_Offset*  len );++FT_END_HEADER++#endif /* __AFMPARSE_H__ */+++/* END */
+ src/psaux/psaux.c view
@@ -0,0 +1,34 @@+/***************************************************************************/+/*                                                                         */+/*  psaux.c                                                                */+/*                                                                         */+/*    FreeType auxiliary PostScript driver component (body only).          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2006 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "psobjs.c"+#include "psauxmod.c"+#include "t1decode.c"+#include "t1cmap.c"++#ifndef T1_CONFIG_OPTION_NO_AFM+#include "afmparse.c"+#endif++#include "psconv.c"+++/* END */
+ src/psaux/psauxerr.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  psauxerr.h                                                             */+/*                                                                         */+/*    PS auxiliary module error codes (specification only).                */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the PS auxiliary module error enumeration */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __PSAUXERR_H__+#define __PSAUXERR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  PSaux_Err_+#define FT_ERR_BASE    FT_Mod_Err_PSaux++#include FT_ERRORS_H++#endif /* __PSAUXERR_H__ */+++/* END */
+ src/psaux/psauxmod.c view
@@ -0,0 +1,139 @@+/***************************************************************************/+/*                                                                         */+/*  psauxmod.c                                                             */+/*                                                                         */+/*    FreeType auxiliary PostScript module implementation (body).          */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "psauxmod.h"+#include "psobjs.h"+#include "t1decode.h"+#include "t1cmap.h"++#ifndef T1_CONFIG_OPTION_NO_AFM+#include "afmparse.h"+#endif+++  FT_CALLBACK_TABLE_DEF+  const PS_Table_FuncsRec  ps_table_funcs =+  {+    ps_table_new,+    ps_table_done,+    ps_table_add,+    ps_table_release+  };+++  FT_CALLBACK_TABLE_DEF+  const PS_Parser_FuncsRec  ps_parser_funcs =+  {+    ps_parser_init,+    ps_parser_done,+    ps_parser_skip_spaces,+    ps_parser_skip_PS_token,+    ps_parser_to_int,+    ps_parser_to_fixed,+    ps_parser_to_bytes,+    ps_parser_to_coord_array,+    ps_parser_to_fixed_array,+    ps_parser_to_token,+    ps_parser_to_token_array,+    ps_parser_load_field,+    ps_parser_load_field_table+  };+++  FT_CALLBACK_TABLE_DEF+  const T1_Builder_FuncsRec  t1_builder_funcs =+  {+    t1_builder_init,+    t1_builder_done,+    t1_builder_check_points,+    t1_builder_add_point,+    t1_builder_add_point1,+    t1_builder_add_contour,+    t1_builder_start_point,+    t1_builder_close_contour+  };+++  FT_CALLBACK_TABLE_DEF+  const T1_Decoder_FuncsRec  t1_decoder_funcs =+  {+    t1_decoder_init,+    t1_decoder_done,+    t1_decoder_parse_charstrings+  };+++#ifndef T1_CONFIG_OPTION_NO_AFM+  FT_CALLBACK_TABLE_DEF+  const AFM_Parser_FuncsRec  afm_parser_funcs =+  {+    afm_parser_init,+    afm_parser_done,+    afm_parser_parse+  };+#endif+++  FT_CALLBACK_TABLE_DEF+  const T1_CMap_ClassesRec  t1_cmap_classes =+  {+    &t1_cmap_standard_class_rec,+    &t1_cmap_expert_class_rec,+    &t1_cmap_custom_class_rec,+    &t1_cmap_unicode_class_rec+  };+++  static+  const PSAux_Interface  psaux_interface =+  {+    &ps_table_funcs,+    &ps_parser_funcs,+    &t1_builder_funcs,+    &t1_decoder_funcs,+    t1_decrypt,++    (const T1_CMap_ClassesRec*) &t1_cmap_classes,++#ifndef T1_CONFIG_OPTION_NO_AFM+    &afm_parser_funcs,+#else+    0,+#endif+  };+++  FT_CALLBACK_TABLE_DEF+  const FT_Module_Class  psaux_module_class =+  {+    0,+    sizeof( FT_ModuleRec ),+    "psaux",+    0x20000L,+    0x20000L,++    &psaux_interface,  /* module-specific interface */++    (FT_Module_Constructor)0,+    (FT_Module_Destructor) 0,+    (FT_Module_Requester)  0+  };+++/* END */
+ src/psaux/psauxmod.h view
@@ -0,0 +1,42 @@+/***************************************************************************/+/*                                                                         */+/*  psauxmod.h                                                             */+/*                                                                         */+/*    FreeType auxiliary PostScript module implementation (specification). */+/*                                                                         */+/*  Copyright 2000-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSAUXMOD_H__+#define __PSAUXMOD_H__+++#include <ft2build.h>+#include FT_MODULE_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  FT_EXPORT_VAR( const FT_Module_Class )  psaux_driver_class;+++FT_END_HEADER++#endif /* __PSAUXMOD_H__ */+++/* END */
+ src/psaux/psconv.c view
@@ -0,0 +1,472 @@+/***************************************************************************/+/*                                                                         */+/*  psconv.c                                                               */+/*                                                                         */+/*    Some convenience conversions (body).                                 */+/*                                                                         */+/*  Copyright 2006, 2008, 2009 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H++#include "psconv.h"+#include "psauxerr.h"+++  /* The following array is used by various functions to quickly convert */+  /* digits (both decimal and non-decimal) into numbers.                 */++#if 'A' == 65+  /* ASCII */++  static const FT_Char  ft_char_table[128] =+  {+    /* 0x00 */+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,+    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,+    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,+    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,+    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,+  };++  /* no character >= 0x80 can represent a valid number */+#define OP  >=++#endif /* 'A' == 65 */++#if 'A' == 193+  /* EBCDIC */++  static const FT_Char  ft_char_table[128] =+  {+    /* 0x80 */+    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,+    -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,+    -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,+    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,+    -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,+    -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,+  };++  /* no character < 0x80 can represent a valid number */+#define OP  <++#endif /* 'A' == 193 */+++  FT_LOCAL_DEF( FT_Int )+  PS_Conv_Strtol( FT_Byte**  cursor,+                  FT_Byte*   limit,+                  FT_Int     base )+  {+    FT_Byte*  p = *cursor;+    FT_Int    num = 0;+    FT_Bool   sign = 0;+++    if ( p == limit || base < 2 || base > 36 )+      return 0;++    if ( *p == '-' || *p == '+' )+    {+      sign = FT_BOOL( *p == '-' );++      p++;+      if ( p == limit )+        return 0;+    }++    for ( ; p < limit; p++ )+    {+      FT_Char  c;+++      if ( IS_PS_SPACE( *p ) || *p OP 0x80 )+        break;++      c = ft_char_table[*p & 0x7f];++      if ( c < 0 || c >= base )+        break;++      num = num * base + c;+    }++    if ( sign )+      num = -num;++    *cursor = p;++    return num;+  }+++  FT_LOCAL_DEF( FT_Int )+  PS_Conv_ToInt( FT_Byte**  cursor,+                 FT_Byte*   limit )++  {+    FT_Byte*  p;+    FT_Int    num;+++    num = PS_Conv_Strtol( cursor, limit, 10 );+    p   = *cursor;++    if ( p < limit && *p == '#' )+    {+      *cursor = p + 1;++      return PS_Conv_Strtol( cursor, limit, num );+    }+    else+      return num;+  }+++  FT_LOCAL_DEF( FT_Fixed )+  PS_Conv_ToFixed( FT_Byte**  cursor,+                   FT_Byte*   limit,+                   FT_Int     power_ten )+  {+    FT_Byte*  p = *cursor;+    FT_Fixed  integral;+    FT_Long   decimal = 0, divider = 1;+    FT_Bool   sign = 0;+++    if ( p == limit )+      return 0;++    if ( *p == '-' || *p == '+' )+    {+      sign = FT_BOOL( *p == '-' );++      p++;+      if ( p == limit )+        return 0;+    }++    if ( *p != '.' )+      integral = PS_Conv_ToInt( &p, limit ) << 16;+    else+      integral = 0;++    /* read the decimal part */+    if ( p < limit && *p == '.' )+    {+      p++;++      for ( ; p < limit; p++ )+      {+        FT_Char  c;+++        if ( IS_PS_SPACE( *p ) || *p OP 0x80 )+          break;++        c = ft_char_table[*p & 0x7f];++        if ( c < 0 || c >= 10 )+          break;++        if ( !integral && power_ten > 0 )+        {+          power_ten--;+          decimal = decimal * 10 + c;+        }+        else+        {+          if ( divider < 10000000L )+          {+            decimal = decimal * 10 + c;+            divider *= 10;+          }+        }+      }+    }++    /* read exponent, if any */+    if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )+    {+      p++;+      power_ten += PS_Conv_ToInt( &p, limit );+    }++    while ( power_ten > 0 )+    {+      integral *= 10;+      decimal  *= 10;+      power_ten--;+    }++    while ( power_ten < 0 )+    {+      integral /= 10;+      divider  *= 10;+      power_ten++;+    }++    if ( decimal )+      integral += FT_DivFix( decimal, divider );++    if ( sign )+      integral = -integral;++    *cursor = p;++    return integral;+  }+++#if 0+  FT_LOCAL_DEF( FT_UInt )+  PS_Conv_StringDecode( FT_Byte**  cursor,+                        FT_Byte*   limit,+                        FT_Byte*   buffer,+                        FT_Offset  n )+  {+    FT_Byte*  p;+    FT_UInt   r = 0;+++    for ( p = *cursor; r < n && p < limit; p++ )+    {+      FT_Byte  b;+++      if ( *p != '\\' )+      {+        buffer[r++] = *p;++        continue;+      }++      p++;++      switch ( *p )+      {+      case 'n':+        b = '\n';+        break;+      case 'r':+        b = '\r';+        break;+      case 't':+        b = '\t';+        break;+      case 'b':+        b = '\b';+        break;+      case 'f':+        b = '\f';+        break;+      case '\r':+        p++;+        if ( *p != '\n' )+        {+          b = *p;++          break;+        }+        /* no break */+      case '\n':+        continue;+        break;+      default:+        if ( IS_PS_DIGIT( *p ) )+        {+          b = *p - '0';++          p++;++          if ( IS_PS_DIGIT( *p ) )+          {+            b = b * 8 + *p - '0';++            p++;++            if ( IS_PS_DIGIT( *p ) )+              b = b * 8 + *p - '0';+            else+            {+              buffer[r++] = b;+              b = *p;+            }+          }+          else+          {+            buffer[r++] = b;+            b = *p;+          }+        }+        else+          b = *p;+        break;+      }++      buffer[r++] = b;+    }++    *cursor = p;++    return r;+  }+#endif /* 0 */+++  FT_LOCAL_DEF( FT_UInt )+  PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,+                          FT_Byte*   limit,+                          FT_Byte*   buffer,+                          FT_Offset  n )+  {+    FT_Byte*  p;+    FT_UInt   r   = 0;+    FT_UInt   w   = 0;+    FT_UInt   pad = 0x01;+++    n *= 2;++#if 1++    p  = *cursor;+    if ( n > (FT_UInt)( limit - p ) )+      n = (FT_UInt)( limit - p );++    /* we try to process two nibbles at a time to be as fast as possible */+    for ( ; r < n; r++ )+    {+      FT_UInt  c = p[r];+++      if ( IS_PS_SPACE( c ) )+        continue;++      if ( c OP 0x80 )+        break;++      c = ft_char_table[c & 0x7F];+      if ( (unsigned)c >= 16 )+        break;++      pad = ( pad << 4 ) | c;+      if ( pad & 0x100 )+      {+        buffer[w++] = (FT_Byte)pad;+        pad         = 0x01;+      }+    }++    if ( pad != 0x01 )+      buffer[w++] = (FT_Byte)( pad << 4 );++    *cursor = p + r;++    return w;++#else /* 0 */++    for ( r = 0; r < n; r++ )+    {+      FT_Char  c;+++      if ( IS_PS_SPACE( *p ) )+        continue;++      if ( *p OP 0x80 )+        break;++      c = ft_char_table[*p & 0x7f];++      if ( (unsigned)c >= 16 )+        break;++      if ( r & 1 )+      {+        *buffer = (FT_Byte)(*buffer + c);+        buffer++;+      }+      else+        *buffer = (FT_Byte)(c << 4);++      r++;+    }++    *cursor = p;++    return ( r + 1 ) / 2;++#endif /* 0 */++  }+++  FT_LOCAL_DEF( FT_UInt )+  PS_Conv_EexecDecode( FT_Byte**   cursor,+                       FT_Byte*    limit,+                       FT_Byte*    buffer,+                       FT_Offset   n,+                       FT_UShort*  seed )+  {+    FT_Byte*  p;+    FT_UInt   r;+    FT_UInt   s = *seed;+++#if 1++    p = *cursor;+    if ( n > (FT_UInt)(limit - p) )+      n = (FT_UInt)(limit - p);++    for ( r = 0; r < n; r++ )+    {+      FT_UInt  val = p[r];+      FT_UInt  b   = ( val ^ ( s >> 8 ) );+++      s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;+      buffer[r] = (FT_Byte) b;+    }++    *cursor = p + n;+    *seed   = (FT_UShort)s;++#else /* 0 */++    for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )+    {+      FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );+++      s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );+      *buffer++ = b;+    }+    *cursor = p;+    *seed   = s;++#endif /* 0 */++    return r;+  }+++/* END */
+ src/psaux/psconv.h view
@@ -0,0 +1,71 @@+/***************************************************************************/+/*                                                                         */+/*  psconv.h                                                               */+/*                                                                         */+/*    Some convenience conversions (specification).                        */+/*                                                                         */+/*  Copyright 2006 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSCONV_H__+#define __PSCONV_H__+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Int )+  PS_Conv_Strtol( FT_Byte**  cursor,+                  FT_Byte*   limit,+                  FT_Int     base );+++  FT_LOCAL( FT_Int )+  PS_Conv_ToInt( FT_Byte**  cursor,+                 FT_Byte*   limit );++  FT_LOCAL( FT_Fixed )+  PS_Conv_ToFixed( FT_Byte**  cursor,+                   FT_Byte*   limit,+                   FT_Int     power_ten );++#if 0+  FT_LOCAL( FT_UInt )+  PS_Conv_StringDecode( FT_Byte**  cursor,+                        FT_Byte*   limit,+                        FT_Byte*   buffer,+                        FT_Offset  n );+#endif++  FT_LOCAL( FT_UInt )+  PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,+                          FT_Byte*   limit,+                          FT_Byte*   buffer,+                          FT_Offset  n );++  FT_LOCAL( FT_UInt )+  PS_Conv_EexecDecode( FT_Byte**   cursor,+                       FT_Byte*    limit,+                       FT_Byte*    buffer,+                       FT_Offset   n,+                       FT_UShort*  seed );+++FT_END_HEADER++#endif /* __PSCONV_H__ */+++/* END */
+ src/psaux/psobjs.c view
@@ -0,0 +1,1711 @@+/***************************************************************************/+/*                                                                         */+/*  psobjs.c                                                               */+/*                                                                         */+/*    Auxiliary functions for PostScript fonts (body).                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H++#include "psobjs.h"+#include "psconv.h"++#include "psauxerr.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_psobjs+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                             PS_TABLE                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ps_table_new                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a PS_Table.                                            */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    table  :: The address of the target table.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    count  :: The table size = the maximum number of elements.         */+  /*                                                                       */+  /*    memory :: The memory object to use for all subsequent              */+  /*              reallocations.                                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  ps_table_new( PS_Table   table,+                FT_Int     count,+                FT_Memory  memory )+  {+    FT_Error  error;+++    table->memory = memory;+    if ( FT_NEW_ARRAY( table->elements, count ) ||+         FT_NEW_ARRAY( table->lengths,  count ) )+      goto Exit;++    table->max_elems = count;+    table->init      = 0xDEADBEEFUL;+    table->num_elems = 0;+    table->block     = 0;+    table->capacity  = 0;+    table->cursor    = 0;++    *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs;++  Exit:+    if ( error )+      FT_FREE( table->elements );++    return error;+  }+++  static void+  shift_elements( PS_Table  table,+                  FT_Byte*  old_base )+  {+    FT_PtrDist  delta  = table->block - old_base;+    FT_Byte**   offset = table->elements;+    FT_Byte**   limit  = offset + table->max_elems;+++    for ( ; offset < limit; offset++ )+    {+      if ( offset[0] )+        offset[0] += delta;+    }+  }+++  static FT_Error+  reallocate_t1_table( PS_Table  table,+                       FT_Long   new_size )+  {+    FT_Memory  memory   = table->memory;+    FT_Byte*   old_base = table->block;+    FT_Error   error;+++    /* allocate new base block */+    if ( FT_ALLOC( table->block, new_size ) )+    {+      table->block = old_base;+      return error;+    }++    /* copy elements and shift offsets */+    if ( old_base )+    {+      FT_MEM_COPY( table->block, old_base, table->capacity );+      shift_elements( table, old_base );+      FT_FREE( old_base );+    }++    table->capacity = new_size;++    return PSaux_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ps_table_add                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Adds an object to a PS_Table, possibly growing its memory block.   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    table  :: The target table.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    idx    :: The index of the object in the table.                    */+  /*                                                                       */+  /*    object :: The address of the object to copy in memory.             */+  /*                                                                       */+  /*    length :: The length in bytes of the source object.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  An error is returned if a  */+  /*    reallocation fails.                                                */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  ps_table_add( PS_Table    table,+                FT_Int      idx,+                void*       object,+                FT_PtrDist  length )+  {+    if ( idx < 0 || idx >= table->max_elems )+    {+      FT_ERROR(( "ps_table_add: invalid index\n" ));+      return PSaux_Err_Invalid_Argument;+    }++    if ( length < 0 )+    {+      FT_ERROR(( "ps_table_add: invalid length\n" ));+      return PSaux_Err_Invalid_Argument;+    }++    /* grow the base block if needed */+    if ( table->cursor + length > table->capacity )+    {+      FT_Error   error;+      FT_Offset  new_size = table->capacity;+      FT_Long    in_offset;+++      in_offset = (FT_Long)((FT_Byte*)object - table->block);+      if ( (FT_ULong)in_offset >= table->capacity )+        in_offset = -1;++      while ( new_size < table->cursor + length )+      {+        /* increase size by 25% and round up to the nearest multiple+           of 1024 */+        new_size += ( new_size >> 2 ) + 1;+        new_size  = FT_PAD_CEIL( new_size, 1024 );+      }++      error = reallocate_t1_table( table, new_size );+      if ( error )+        return error;++      if ( in_offset >= 0 )+        object = table->block + in_offset;+    }++    /* add the object to the base block and adjust offset */+    table->elements[idx] = table->block + table->cursor;+    table->lengths [idx] = length;+    FT_MEM_COPY( table->block + table->cursor, object, length );++    table->cursor += length;+    return PSaux_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ps_table_done                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a PS_TableRec (i.e., reallocate it to its current        */+  /*    cursor).                                                           */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    table :: The target table.                                         */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This function does NOT release the heap's memory block.  It is up  */+  /*    to the caller to clean it, or reference it in its own structures.  */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  ps_table_done( PS_Table  table )+  {+    FT_Memory  memory = table->memory;+    FT_Error   error;+    FT_Byte*   old_base = table->block;+++    /* should never fail, because rec.cursor <= rec.size */+    if ( !old_base )+      return;++    if ( FT_ALLOC( table->block, table->cursor ) )+      return;+    FT_MEM_COPY( table->block, old_base, table->cursor );+    shift_elements( table, old_base );++    table->capacity = table->cursor;+    FT_FREE( old_base );++    FT_UNUSED( error );+  }+++  FT_LOCAL_DEF( void )+  ps_table_release( PS_Table  table )+  {+    FT_Memory  memory = table->memory;+++    if ( (FT_ULong)table->init == 0xDEADBEEFUL )+    {+      FT_FREE( table->block );+      FT_FREE( table->elements );+      FT_FREE( table->lengths );+      table->init = 0;+    }+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            T1 PARSER                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* first character must be already part of the comment */++  static void+  skip_comment( FT_Byte*  *acur,+                FT_Byte*   limit )+  {+    FT_Byte*  cur = *acur;+++    while ( cur < limit )+    {+      if ( IS_PS_NEWLINE( *cur ) )+        break;+      cur++;+    }++    *acur = cur;+  }+++  static void+  skip_spaces( FT_Byte*  *acur,+               FT_Byte*   limit )+  {+    FT_Byte*  cur = *acur;+++    while ( cur < limit )+    {+      if ( !IS_PS_SPACE( *cur ) )+      {+        if ( *cur == '%' )+          /* According to the PLRM, a comment is equal to a space. */+          skip_comment( &cur, limit );+        else+          break;+      }+      cur++;+    }++    *acur = cur;+  }+++#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )+++  /* first character must be `(';                               */+  /* *acur is positioned at the character after the closing `)' */++  static FT_Error+  skip_literal_string( FT_Byte*  *acur,+                       FT_Byte*   limit )+  {+    FT_Byte*      cur   = *acur;+    FT_Int        embed = 0;+    FT_Error      error = PSaux_Err_Invalid_File_Format;+    unsigned int  i;+++    while ( cur < limit )+    {+      FT_Byte  c = *cur;+++      ++cur;++      if ( c == '\\' )+      {+        /* Red Book 3rd ed., section `Literal Text Strings', p. 29:     */+        /* A backslash can introduce three different types              */+        /* of escape sequences:                                         */+        /*   - a special escaped char like \r, \n, etc.                 */+        /*   - a one-, two-, or three-digit octal number                */+        /*   - none of the above in which case the backslash is ignored */++        if ( cur == limit )+          /* error (or to be ignored?) */+          break;++        switch ( *cur )+        {+          /* skip `special' escape */+        case 'n':+        case 'r':+        case 't':+        case 'b':+        case 'f':+        case '\\':+        case '(':+        case ')':+          ++cur;+          break;++        default:+          /* skip octal escape or ignore backslash */+          for ( i = 0; i < 3 && cur < limit; ++i )+          {+            if ( !IS_OCTAL_DIGIT( *cur ) )+              break;++            ++cur;+          }+        }+      }+      else if ( c == '(' )+        embed++;+      else if ( c == ')' )+      {+        embed--;+        if ( embed == 0 )+        {+          error = PSaux_Err_Ok;+          break;+        }+      }+    }++    *acur = cur;++    return error;+  }+++  /* first character must be `<' */++  static FT_Error+  skip_string( FT_Byte*  *acur,+               FT_Byte*   limit )+  {+    FT_Byte*  cur = *acur;+    FT_Error  err =  PSaux_Err_Ok;+++    while ( ++cur < limit )+    {+      /* All whitespace characters are ignored. */+      skip_spaces( &cur, limit );+      if ( cur >= limit )+        break;++      if ( !IS_PS_XDIGIT( *cur ) )+        break;+    }++    if ( cur < limit && *cur != '>' )+    {+      FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));+      err = PSaux_Err_Invalid_File_Format;+    }+    else+      cur++;++    *acur = cur;+    return err;+  }+++  /* first character must be the opening brace that */+  /* starts the procedure                           */++  /* NB: [ and ] need not match:                    */+  /* `/foo {[} def' is a valid PostScript fragment, */+  /* even within a Type1 font                       */++  static FT_Error+  skip_procedure( FT_Byte*  *acur,+                  FT_Byte*   limit )+  {+    FT_Byte*  cur;+    FT_Int    embed = 0;+    FT_Error  error = PSaux_Err_Ok;+++    FT_ASSERT( **acur == '{' );++    for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )+    {+      switch ( *cur )+      {+      case '{':+        ++embed;+        break;++      case '}':+        --embed;+        if ( embed == 0 )+        {+          ++cur;+          goto end;+        }+        break;++      case '(':+        error = skip_literal_string( &cur, limit );+        break;++      case '<':+        error = skip_string( &cur, limit );+        break;++      case '%':+        skip_comment( &cur, limit );+        break;+      }+    }++  end:+    if ( embed != 0 )+      error = PSaux_Err_Invalid_File_Format;++    *acur = cur;++    return error;+  }+++  /***********************************************************************/+  /*                                                                     */+  /* All exported parsing routines handle leading whitespace and stop at */+  /* the first character which isn't part of the just handled token.     */+  /*                                                                     */+  /***********************************************************************/+++  FT_LOCAL_DEF( void )+  ps_parser_skip_PS_token( PS_Parser  parser )+  {+    /* Note: PostScript allows any non-delimiting, non-whitespace        */+    /*       character in a name (PS Ref Manual, 3rd ed, p31).           */+    /*       PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */++    FT_Byte*  cur   = parser->cursor;+    FT_Byte*  limit = parser->limit;+    FT_Error  error = PSaux_Err_Ok;+++    skip_spaces( &cur, limit );             /* this also skips comments */+    if ( cur >= limit )+      goto Exit;++    /* self-delimiting, single-character tokens */+    if ( *cur == '[' || *cur == ']' )+    {+      cur++;+      goto Exit;+    }++    /* skip balanced expressions (procedures and strings) */++    if ( *cur == '{' )                              /* {...} */+    {+      error = skip_procedure( &cur, limit );+      goto Exit;+    }++    if ( *cur == '(' )                              /* (...) */+    {+      error = skip_literal_string( &cur, limit );+      goto Exit;+    }++    if ( *cur == '<' )                              /* <...> */+    {+      if ( cur + 1 < limit && *(cur + 1) == '<' )   /* << */+      {+        cur++;+        cur++;+      }+      else+        error = skip_string( &cur, limit );++      goto Exit;+    }++    if ( *cur == '>' )+    {+      cur++;+      if ( cur >= limit || *cur != '>' )             /* >> */+      {+        FT_ERROR(( "ps_parser_skip_PS_token:"+                   " unexpected closing delimiter `>'\n" ));+        error = PSaux_Err_Invalid_File_Format;+        goto Exit;+      }+      cur++;+      goto Exit;+    }++    if ( *cur == '/' )+      cur++;++    /* anything else */+    while ( cur < limit )+    {+      /* *cur might be invalid (e.g., ')' or '}'), but this   */+      /* is handled by the test `cur == parser->cursor' below */+      if ( IS_PS_DELIM( *cur ) )+        break;++      cur++;+    }++  Exit:+    if ( cur == parser->cursor )+    {+      FT_ERROR(( "ps_parser_skip_PS_token:"+                 " current token is `%c' which is self-delimiting\n"+                 "                        "+                 " but invalid at this point\n",+                 *cur ));++      error = PSaux_Err_Invalid_File_Format;+    }++    parser->error  = error;+    parser->cursor = cur;+  }+++  FT_LOCAL_DEF( void )+  ps_parser_skip_spaces( PS_Parser  parser )+  {+    skip_spaces( &parser->cursor, parser->limit );+  }+++  /* `token' here means either something between balanced delimiters */+  /* or the next token; the delimiters are not removed.              */++  FT_LOCAL_DEF( void )+  ps_parser_to_token( PS_Parser  parser,+                      T1_Token   token )+  {+    FT_Byte*  cur;+    FT_Byte*  limit;+    FT_Int    embed;+++    token->type  = T1_TOKEN_TYPE_NONE;+    token->start = 0;+    token->limit = 0;++    /* first of all, skip leading whitespace */+    ps_parser_skip_spaces( parser );++    cur   = parser->cursor;+    limit = parser->limit;++    if ( cur >= limit )+      return;++    switch ( *cur )+    {+      /************* check for literal string *****************/+    case '(':+      token->type  = T1_TOKEN_TYPE_STRING;+      token->start = cur;++      if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )+        token->limit = cur;+      break;++      /************* check for programs/array *****************/+    case '{':+      token->type  = T1_TOKEN_TYPE_ARRAY;+      token->start = cur;++      if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )+        token->limit = cur;+      break;++      /************* check for table/array ********************/+      /* XXX: in theory we should also look for "<<"          */+      /*      since this is semantically equivalent to "[";   */+      /*      in practice it doesn't matter (?)               */+    case '[':+      token->type  = T1_TOKEN_TYPE_ARRAY;+      embed        = 1;+      token->start = cur++;++      /* we need this to catch `[ ]' */+      parser->cursor = cur;+      ps_parser_skip_spaces( parser );+      cur = parser->cursor;++      while ( cur < limit && !parser->error )+      {+        /* XXX: this is wrong because it does not      */+        /*      skip comments, procedures, and strings */+        if ( *cur == '[' )+          embed++;+        else if ( *cur == ']' )+        {+          embed--;+          if ( embed <= 0 )+          {+            token->limit = ++cur;+            break;+          }+        }++        parser->cursor = cur;+        ps_parser_skip_PS_token( parser );+        /* we need this to catch `[XXX ]' */+        ps_parser_skip_spaces  ( parser );+        cur = parser->cursor;+      }+      break;++      /* ************ otherwise, it is any token **************/+    default:+      token->start = cur;+      token->type  = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );+      ps_parser_skip_PS_token( parser );+      cur = parser->cursor;+      if ( !parser->error )+        token->limit = cur;+    }++    if ( !token->limit )+    {+      token->start = 0;+      token->type  = T1_TOKEN_TYPE_NONE;+    }++    parser->cursor = cur;+  }+++  /* NB: `tokens' can be NULL if we only want to count */+  /* the number of array elements                      */++  FT_LOCAL_DEF( void )+  ps_parser_to_token_array( PS_Parser  parser,+                            T1_Token   tokens,+                            FT_UInt    max_tokens,+                            FT_Int*    pnum_tokens )+  {+    T1_TokenRec  master;+++    *pnum_tokens = -1;++    /* this also handles leading whitespace */+    ps_parser_to_token( parser, &master );++    if ( master.type == T1_TOKEN_TYPE_ARRAY )+    {+      FT_Byte*  old_cursor = parser->cursor;+      FT_Byte*  old_limit  = parser->limit;+      T1_Token  cur        = tokens;+      T1_Token  limit      = cur + max_tokens;+++      /* don't include outermost delimiters */+      parser->cursor = master.start + 1;+      parser->limit  = master.limit - 1;++      while ( parser->cursor < parser->limit )+      {+        T1_TokenRec  token;+++        ps_parser_to_token( parser, &token );+        if ( !token.type )+          break;++        if ( tokens != NULL && cur < limit )+          *cur = token;++        cur++;+      }++      *pnum_tokens = (FT_Int)( cur - tokens );++      parser->cursor = old_cursor;+      parser->limit  = old_limit;+    }+  }+++  /* first character must be a delimiter or a part of a number */+  /* NB: `coords' can be NULL if we just want to skip the      */+  /*     array; in this case we ignore `max_coords'            */++  static FT_Int+  ps_tocoordarray( FT_Byte*  *acur,+                   FT_Byte*   limit,+                   FT_Int     max_coords,+                   FT_Short*  coords )+  {+    FT_Byte*  cur   = *acur;+    FT_Int    count = 0;+    FT_Byte   c, ender;+++    if ( cur >= limit )+      goto Exit;++    /* check for the beginning of an array; otherwise, only one number */+    /* will be read                                                    */+    c     = *cur;+    ender = 0;++    if ( c == '[' )+      ender = ']';+    else if ( c == '{' )+      ender = '}';++    if ( ender )+      cur++;++    /* now, read the coordinates */+    while ( cur < limit )+    {+      FT_Short  dummy;+      FT_Byte*  old_cur;+++      /* skip whitespace in front of data */+      skip_spaces( &cur, limit );+      if ( cur >= limit )+        goto Exit;++      if ( *cur == ender )+      {+        cur++;+        break;+      }++      old_cur = cur;++      if ( coords != NULL && count >= max_coords )+        break;++      /* call PS_Conv_ToFixed() even if coords == NULL */+      /* to properly parse number at `cur'             */+      *( coords != NULL ? &coords[count] : &dummy ) =+        (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );++      if ( old_cur == cur )+      {+        count = -1;+        goto Exit;+      }+      else+        count++;++      if ( !ender )+        break;+    }++  Exit:+    *acur = cur;+    return count;+  }+++  /* first character must be a delimiter or a part of a number */+  /* NB: `values' can be NULL if we just want to skip the      */+  /*     array; in this case we ignore `max_values'            */++  static FT_Int+  ps_tofixedarray( FT_Byte*  *acur,+                   FT_Byte*   limit,+                   FT_Int     max_values,+                   FT_Fixed*  values,+                   FT_Int     power_ten )+  {+    FT_Byte*  cur   = *acur;+    FT_Int    count = 0;+    FT_Byte   c, ender;+++    if ( cur >= limit )+      goto Exit;++    /* Check for the beginning of an array.  Otherwise, only one number */+    /* will be read.                                                    */+    c     = *cur;+    ender = 0;++    if ( c == '[' )+      ender = ']';+    else if ( c == '{' )+      ender = '}';++    if ( ender )+      cur++;++    /* now, read the values */+    while ( cur < limit )+    {+      FT_Fixed  dummy;+      FT_Byte*  old_cur;+++      /* skip whitespace in front of data */+      skip_spaces( &cur, limit );+      if ( cur >= limit )+        goto Exit;++      if ( *cur == ender )+      {+        cur++;+        break;+      }++      old_cur = cur;++      if ( values != NULL && count >= max_values )+        break;++      /* call PS_Conv_ToFixed() even if coords == NULL */+      /* to properly parse number at `cur'             */+      *( values != NULL ? &values[count] : &dummy ) =+        PS_Conv_ToFixed( &cur, limit, power_ten );++      if ( old_cur == cur )+      {+        count = -1;+        goto Exit;+      }+      else+        count++;++      if ( !ender )+        break;+    }++  Exit:+    *acur = cur;+    return count;+  }+++#if 0++  static FT_String*+  ps_tostring( FT_Byte**  cursor,+               FT_Byte*   limit,+               FT_Memory  memory )+  {+    FT_Byte*    cur = *cursor;+    FT_PtrDist  len = 0;+    FT_Int      count;+    FT_String*  result;+    FT_Error    error;+++    /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */+    /*      that simply doesn't begin with an opening parenthesis, even */+    /*      though they have a closing one!  E.g. "amuncial.pfb"        */+    /*                                                                  */+    /*      We must deal with these ill-fated cases there.  Note that   */+    /*      these fonts didn't work with the old Type 1 driver as the   */+    /*      notice/copyright was not recognized as a valid string token */+    /*      and made the old token parser commit errors.                */++    while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )+      cur++;+    if ( cur + 1 >= limit )+      return 0;++    if ( *cur == '(' )+      cur++;  /* skip the opening parenthesis, if there is one */++    *cursor = cur;+    count   = 0;++    /* then, count its length */+    for ( ; cur < limit; cur++ )+    {+      if ( *cur == '(' )+        count++;++      else if ( *cur == ')' )+      {+        count--;+        if ( count < 0 )+          break;+      }+    }++    len = cur - *cursor;+    if ( cur >= limit || FT_ALLOC( result, len + 1 ) )+      return 0;++    /* now copy the string */+    FT_MEM_COPY( result, *cursor, len );+    result[len] = '\0';+    *cursor = cur;+    return result;+  }++#endif /* 0 */+++  static int+  ps_tobool( FT_Byte*  *acur,+             FT_Byte*   limit )+  {+    FT_Byte*  cur    = *acur;+    FT_Bool   result = 0;+++    /* return 1 if we find `true', 0 otherwise */+    if ( cur + 3 < limit &&+         cur[0] == 't'   &&+         cur[1] == 'r'   &&+         cur[2] == 'u'   &&+         cur[3] == 'e'   )+    {+      result = 1;+      cur   += 5;+    }+    else if ( cur + 4 < limit &&+              cur[0] == 'f'   &&+              cur[1] == 'a'   &&+              cur[2] == 'l'   &&+              cur[3] == 's'   &&+              cur[4] == 'e'   )+    {+      result = 0;+      cur   += 6;+    }++    *acur = cur;+    return result;+  }+++  /* load a simple field (i.e. non-table) into the current list of objects */++  FT_LOCAL_DEF( FT_Error )+  ps_parser_load_field( PS_Parser       parser,+                        const T1_Field  field,+                        void**          objects,+                        FT_UInt         max_objects,+                        FT_ULong*       pflags )+  {+    T1_TokenRec  token;+    FT_Byte*     cur;+    FT_Byte*     limit;+    FT_UInt      count;+    FT_UInt      idx;+    FT_Error     error;+++    /* this also skips leading whitespace */+    ps_parser_to_token( parser, &token );+    if ( !token.type )+      goto Fail;++    count = 1;+    idx   = 0;+    cur   = token.start;+    limit = token.limit;++    /* we must detect arrays in /FontBBox */+    if ( field->type == T1_FIELD_TYPE_BBOX )+    {+      T1_TokenRec  token2;+      FT_Byte*     old_cur   = parser->cursor;+      FT_Byte*     old_limit = parser->limit;+++      /* don't include delimiters */+      parser->cursor = token.start + 1;+      parser->limit  = token.limit - 1;++      ps_parser_to_token( parser, &token2 );+      parser->cursor = old_cur;+      parser->limit  = old_limit;++      if ( token2.type == T1_TOKEN_TYPE_ARRAY )+        goto FieldArray;+    }+    else if ( token.type == T1_TOKEN_TYPE_ARRAY )+    {+    FieldArray:+      /* if this is an array and we have no blend, an error occurs */+      if ( max_objects == 0 )+        goto Fail;++      count = max_objects;+      idx   = 1;++      /* don't include delimiters */+      cur++;+      limit--;+    }++    for ( ; count > 0; count--, idx++ )+    {+      FT_Byte*    q = (FT_Byte*)objects[idx] + field->offset;+      FT_Long     val;+      FT_String*  string;+++      skip_spaces( &cur, limit );++      switch ( field->type )+      {+      case T1_FIELD_TYPE_BOOL:+        val = ps_tobool( &cur, limit );+        goto Store_Integer;++      case T1_FIELD_TYPE_FIXED:+        val = PS_Conv_ToFixed( &cur, limit, 0 );+        goto Store_Integer;++      case T1_FIELD_TYPE_FIXED_1000:+        val = PS_Conv_ToFixed( &cur, limit, 3 );+        goto Store_Integer;++      case T1_FIELD_TYPE_INTEGER:+        val = PS_Conv_ToInt( &cur, limit );+        /* fall through */++      Store_Integer:+        switch ( field->size )+        {+        case (8 / FT_CHAR_BIT):+          *(FT_Byte*)q = (FT_Byte)val;+          break;++        case (16 / FT_CHAR_BIT):+          *(FT_UShort*)q = (FT_UShort)val;+          break;++        case (32 / FT_CHAR_BIT):+          *(FT_UInt32*)q = (FT_UInt32)val;+          break;++        default:                /* for 64-bit systems */+          *(FT_Long*)q = val;+        }+        break;++      case T1_FIELD_TYPE_STRING:+      case T1_FIELD_TYPE_KEY:+        {+          FT_Memory  memory = parser->memory;+          FT_UInt    len    = (FT_UInt)( limit - cur );+++          if ( cur >= limit )+            break;++          /* we allow both a string or a name   */+          /* for cases like /FontName (foo) def */+          if ( token.type == T1_TOKEN_TYPE_KEY )+          {+            /* don't include leading `/' */+            len--;+            cur++;+          }+          else if ( token.type == T1_TOKEN_TYPE_STRING )+          {+            /* don't include delimiting parentheses    */+            /* XXX we don't handle <<...>> here        */+            /* XXX should we convert octal escapes?    */+            /*     if so, what encoding should we use? */+            cur++;+            len -= 2;+          }+          else+          {+            FT_ERROR(( "ps_parser_load_field:"+                       " expected a name or string\n"+                       "                     "+                       " but found token of type %d instead\n",+                       token.type ));+            error = PSaux_Err_Invalid_File_Format;+            goto Exit;+          }++          /* for this to work (FT_String**)q must have been */+          /* initialized to NULL                            */+          if ( *(FT_String**)q != NULL )+          {+            FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",+                        field->ident ));+            FT_FREE( *(FT_String**)q );+            *(FT_String**)q = NULL;+          }++          if ( FT_ALLOC( string, len + 1 ) )+            goto Exit;++          FT_MEM_COPY( string, cur, len );+          string[len] = 0;++          *(FT_String**)q = string;+        }+        break;++      case T1_FIELD_TYPE_BBOX:+        {+          FT_Fixed  temp[4];+          FT_BBox*  bbox = (FT_BBox*)q;+          FT_Int    result;+++          result = ps_tofixedarray( &cur, limit, 4, temp, 0 );++          if ( result < 0 )+          {+            FT_ERROR(( "ps_parser_load_field:"+                       " expected four integers in bounding box\n" ));+            error = PSaux_Err_Invalid_File_Format;+            goto Exit;+          }++          bbox->xMin = FT_RoundFix( temp[0] );+          bbox->yMin = FT_RoundFix( temp[1] );+          bbox->xMax = FT_RoundFix( temp[2] );+          bbox->yMax = FT_RoundFix( temp[3] );+        }+        break;++      default:+        /* an error occurred */+        goto Fail;+      }+    }++#if 0  /* obsolete -- keep for reference */+    if ( pflags )+      *pflags |= 1L << field->flag_bit;+#else+    FT_UNUSED( pflags );+#endif++    error = PSaux_Err_Ok;++  Exit:+    return error;++  Fail:+    error = PSaux_Err_Invalid_File_Format;+    goto Exit;+  }+++#define T1_MAX_TABLE_ELEMENTS  32+++  FT_LOCAL_DEF( FT_Error )+  ps_parser_load_field_table( PS_Parser       parser,+                              const T1_Field  field,+                              void**          objects,+                              FT_UInt         max_objects,+                              FT_ULong*       pflags )+  {+    T1_TokenRec  elements[T1_MAX_TABLE_ELEMENTS];+    T1_Token     token;+    FT_Int       num_elements;+    FT_Error     error = PSaux_Err_Ok;+    FT_Byte*     old_cursor;+    FT_Byte*     old_limit;+    T1_FieldRec  fieldrec = *(T1_Field)field;+++    fieldrec.type = T1_FIELD_TYPE_INTEGER;+    if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||+         field->type == T1_FIELD_TYPE_BBOX        )+      fieldrec.type = T1_FIELD_TYPE_FIXED;++    ps_parser_to_token_array( parser, elements,+                              T1_MAX_TABLE_ELEMENTS, &num_elements );+    if ( num_elements < 0 )+    {+      error = PSaux_Err_Ignore;+      goto Exit;+    }+    if ( (FT_UInt)num_elements > field->array_max )+      num_elements = field->array_max;++    old_cursor = parser->cursor;+    old_limit  = parser->limit;++    /* we store the elements count if necessary;           */+    /* we further assume that `count_offset' can't be zero */+    if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 )+      *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =+        (FT_Byte)num_elements;++    /* we now load each element, adjusting the field.offset on each one */+    token = elements;+    for ( ; num_elements > 0; num_elements--, token++ )+    {+      parser->cursor = token->start;+      parser->limit  = token->limit;+      ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );+      fieldrec.offset += fieldrec.size;+    }++#if 0  /* obsolete -- keep for reference */+    if ( pflags )+      *pflags |= 1L << field->flag_bit;+#else+    FT_UNUSED( pflags );+#endif++    parser->cursor = old_cursor;+    parser->limit  = old_limit;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Long )+  ps_parser_to_int( PS_Parser  parser )+  {+    ps_parser_skip_spaces( parser );+    return PS_Conv_ToInt( &parser->cursor, parser->limit );+  }+++  /* first character must be `<' if `delimiters' is non-zero */++  FT_LOCAL_DEF( FT_Error )+  ps_parser_to_bytes( PS_Parser  parser,+                      FT_Byte*   bytes,+                      FT_Offset  max_bytes,+                      FT_Long*   pnum_bytes,+                      FT_Bool    delimiters )+  {+    FT_Error  error = PSaux_Err_Ok;+    FT_Byte*  cur;+++    ps_parser_skip_spaces( parser );+    cur = parser->cursor;++    if ( cur >= parser->limit )+      goto Exit;++    if ( delimiters )+    {+      if ( *cur != '<' )+      {+        FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" ));+        error = PSaux_Err_Invalid_File_Format;+        goto Exit;+      }++      cur++;+    }++    *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur,+                                          parser->limit,+                                          bytes,+                                          max_bytes );++    if ( delimiters )+    {+      if ( cur < parser->limit && *cur != '>' )+      {+        FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));+        error = PSaux_Err_Invalid_File_Format;+        goto Exit;+      }++      cur++;+    }++    parser->cursor = cur;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Fixed )+  ps_parser_to_fixed( PS_Parser  parser,+                      FT_Int     power_ten )+  {+    ps_parser_skip_spaces( parser );+    return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten );+  }+++  FT_LOCAL_DEF( FT_Int )+  ps_parser_to_coord_array( PS_Parser  parser,+                            FT_Int     max_coords,+                            FT_Short*  coords )+  {+    ps_parser_skip_spaces( parser );+    return ps_tocoordarray( &parser->cursor, parser->limit,+                            max_coords, coords );+  }+++  FT_LOCAL_DEF( FT_Int )+  ps_parser_to_fixed_array( PS_Parser  parser,+                            FT_Int     max_values,+                            FT_Fixed*  values,+                            FT_Int     power_ten )+  {+    ps_parser_skip_spaces( parser );+    return ps_tofixedarray( &parser->cursor, parser->limit,+                            max_values, values, power_ten );+  }+++#if 0++  FT_LOCAL_DEF( FT_String* )+  T1_ToString( PS_Parser  parser )+  {+    return ps_tostring( &parser->cursor, parser->limit, parser->memory );+  }+++  FT_LOCAL_DEF( FT_Bool )+  T1_ToBool( PS_Parser  parser )+  {+    return ps_tobool( &parser->cursor, parser->limit );+  }++#endif /* 0 */+++  FT_LOCAL_DEF( void )+  ps_parser_init( PS_Parser  parser,+                  FT_Byte*   base,+                  FT_Byte*   limit,+                  FT_Memory  memory )+  {+    parser->error  = PSaux_Err_Ok;+    parser->base   = base;+    parser->limit  = limit;+    parser->cursor = base;+    parser->memory = memory;+    parser->funcs  = ps_parser_funcs;+  }+++  FT_LOCAL_DEF( void )+  ps_parser_done( PS_Parser  parser )+  {+    FT_UNUSED( parser );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            T1 BUILDER                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    t1_builder_init                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given glyph builder.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    builder :: A pointer to the glyph builder to initialize.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face    :: The current face object.                                */+  /*                                                                       */+  /*    size    :: The current size object.                                */+  /*                                                                       */+  /*    glyph   :: The current glyph object.                               */+  /*                                                                       */+  /*    hinting :: Whether hinting should be applied.                      */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  t1_builder_init( T1_Builder    builder,+                   FT_Face       face,+                   FT_Size       size,+                   FT_GlyphSlot  glyph,+                   FT_Bool       hinting )+  {+    builder->parse_state = T1_Parse_Start;+    builder->load_points = 1;++    builder->face   = face;+    builder->glyph  = glyph;+    builder->memory = face->memory;++    if ( glyph )+    {+      FT_GlyphLoader  loader = glyph->internal->loader;+++      builder->loader  = loader;+      builder->base    = &loader->base.outline;+      builder->current = &loader->current.outline;+      FT_GlyphLoader_Rewind( loader );++      builder->hints_globals = size->internal;+      builder->hints_funcs   = 0;++      if ( hinting )+        builder->hints_funcs = glyph->internal->glyph_hints;+    }++    builder->pos_x = 0;+    builder->pos_y = 0;++    builder->left_bearing.x = 0;+    builder->left_bearing.y = 0;+    builder->advance.x      = 0;+    builder->advance.y      = 0;++    builder->funcs = t1_builder_funcs;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    t1_builder_done                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a given glyph builder.  Its contents can still be used   */+  /*    after the call, but the function saves important information       */+  /*    within the corresponding glyph slot.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    builder :: A pointer to the glyph builder to finalize.             */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  t1_builder_done( T1_Builder  builder )+  {+    FT_GlyphSlot  glyph = builder->glyph;+++    if ( glyph )+      glyph->outline = *builder->base;+  }+++  /* check that there is enough space for `count' more points */+  FT_LOCAL_DEF( FT_Error )+  t1_builder_check_points( T1_Builder  builder,+                           FT_Int      count )+  {+    return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );+  }+++  /* add a new point, do not check space */+  FT_LOCAL_DEF( void )+  t1_builder_add_point( T1_Builder  builder,+                        FT_Pos      x,+                        FT_Pos      y,+                        FT_Byte     flag )+  {+    FT_Outline*  outline = builder->current;+++    if ( builder->load_points )+    {+      FT_Vector*  point   = outline->points + outline->n_points;+      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;+++      point->x = FIXED_TO_INT( x );+      point->y = FIXED_TO_INT( y );+      *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );+    }+    outline->n_points++;+  }+++  /* check space for a new on-curve point, then add it */+  FT_LOCAL_DEF( FT_Error )+  t1_builder_add_point1( T1_Builder  builder,+                         FT_Pos      x,+                         FT_Pos      y )+  {+    FT_Error  error;+++    error = t1_builder_check_points( builder, 1 );+    if ( !error )+      t1_builder_add_point( builder, x, y, 1 );++    return error;+  }+++  /* check space for a new contour, then add it */+  FT_LOCAL_DEF( FT_Error )+  t1_builder_add_contour( T1_Builder  builder )+  {+    FT_Outline*  outline = builder->current;+    FT_Error     error;+++    /* this might happen in invalid fonts */+    if ( !outline )+    {+      FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" ));+      return PSaux_Err_Invalid_File_Format;+    }++    if ( !builder->load_points )+    {+      outline->n_contours++;+      return PSaux_Err_Ok;+    }++    error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );+    if ( !error )+    {+      if ( outline->n_contours > 0 )+        outline->contours[outline->n_contours - 1] =+          (short)( outline->n_points - 1 );++      outline->n_contours++;+    }++    return error;+  }+++  /* if a path was begun, add its first on-curve point */+  FT_LOCAL_DEF( FT_Error )+  t1_builder_start_point( T1_Builder  builder,+                          FT_Pos      x,+                          FT_Pos      y )+  {+    FT_Error  error = PSaux_Err_Invalid_File_Format;+++    /* test whether we are building a new contour */++    if ( builder->parse_state == T1_Parse_Have_Path )+      error = PSaux_Err_Ok;+    else+    {+      builder->parse_state = T1_Parse_Have_Path;+      error = t1_builder_add_contour( builder );+      if ( !error )+        error = t1_builder_add_point1( builder, x, y );+    }++    return error;+  }+++  /* close the current contour */+  FT_LOCAL_DEF( void )+  t1_builder_close_contour( T1_Builder  builder )+  {+    FT_Outline*  outline = builder->current;+    FT_Int       first;+++    if ( !outline )+      return;++    first = outline->n_contours <= 1+            ? 0 : outline->contours[outline->n_contours - 2] + 1;++    /* We must not include the last point in the path if it */+    /* is located on the first point.                       */+    if ( outline->n_points > 1 )+    {+      FT_Vector*  p1      = outline->points + first;+      FT_Vector*  p2      = outline->points + outline->n_points - 1;+      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;+++      /* `delete' last point only if it coincides with the first */+      /* point and it is not a control point (which can happen). */+      if ( p1->x == p2->x && p1->y == p2->y )+        if ( *control == FT_CURVE_TAG_ON )+          outline->n_points--;+    }++    if ( outline->n_contours > 0 )+    {+      /* Don't add contours only consisting of one point, i.e.,  */+      /* check whether the first and the last point is the same. */+      if ( first == outline->n_points - 1 )+      {+        outline->n_contours--;+        outline->n_points--;+      }+      else+        outline->contours[outline->n_contours - 1] =+          (short)( outline->n_points - 1 );+    }+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            OTHER                              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  t1_decrypt( FT_Byte*   buffer,+              FT_Offset  length,+              FT_UShort  seed )+  {+    PS_Conv_EexecDecode( &buffer,+                         buffer + length,+                         buffer,+                         length,+                         &seed );+  }+++/* END */
+ src/psaux/psobjs.h view
@@ -0,0 +1,212 @@+/***************************************************************************/+/*                                                                         */+/*  psobjs.h                                                               */+/*                                                                         */+/*    Auxiliary functions for PostScript fonts (specification).            */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSOBJS_H__+#define __PSOBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                             T1_TABLE                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_CALLBACK_TABLE+  const PS_Table_FuncsRec    ps_table_funcs;++  FT_CALLBACK_TABLE+  const PS_Parser_FuncsRec   ps_parser_funcs;++  FT_CALLBACK_TABLE+  const T1_Builder_FuncsRec  t1_builder_funcs;+++  FT_LOCAL( FT_Error )+  ps_table_new( PS_Table   table,+                FT_Int     count,+                FT_Memory  memory );++  FT_LOCAL( FT_Error )+  ps_table_add( PS_Table    table,+                FT_Int      idx,+                void*       object,+                FT_PtrDist  length );++  FT_LOCAL( void )+  ps_table_done( PS_Table  table );+++  FT_LOCAL( void )+  ps_table_release( PS_Table  table );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            T1 PARSER                          *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL( void )+  ps_parser_skip_spaces( PS_Parser  parser );++  FT_LOCAL( void )+  ps_parser_skip_PS_token( PS_Parser  parser );++  FT_LOCAL( void )+  ps_parser_to_token( PS_Parser  parser,+                      T1_Token   token );++  FT_LOCAL( void )+  ps_parser_to_token_array( PS_Parser  parser,+                            T1_Token   tokens,+                            FT_UInt    max_tokens,+                            FT_Int*    pnum_tokens );++  FT_LOCAL( FT_Error )+  ps_parser_load_field( PS_Parser       parser,+                        const T1_Field  field,+                        void**          objects,+                        FT_UInt         max_objects,+                        FT_ULong*       pflags );++  FT_LOCAL( FT_Error )+  ps_parser_load_field_table( PS_Parser       parser,+                              const T1_Field  field,+                              void**          objects,+                              FT_UInt         max_objects,+                              FT_ULong*       pflags );++  FT_LOCAL( FT_Long )+  ps_parser_to_int( PS_Parser  parser );+++  FT_LOCAL( FT_Error )+  ps_parser_to_bytes( PS_Parser  parser,+                      FT_Byte*   bytes,+                      FT_Offset  max_bytes,+                      FT_Long*   pnum_bytes,+                      FT_Bool    delimiters );+++  FT_LOCAL( FT_Fixed )+  ps_parser_to_fixed( PS_Parser  parser,+                      FT_Int     power_ten );+++  FT_LOCAL( FT_Int )+  ps_parser_to_coord_array( PS_Parser  parser,+                            FT_Int     max_coords,+                            FT_Short*  coords );++  FT_LOCAL( FT_Int )+  ps_parser_to_fixed_array( PS_Parser  parser,+                            FT_Int     max_values,+                            FT_Fixed*  values,+                            FT_Int     power_ten );+++  FT_LOCAL( void )+  ps_parser_init( PS_Parser  parser,+                  FT_Byte*   base,+                  FT_Byte*   limit,+                  FT_Memory  memory );++  FT_LOCAL( void )+  ps_parser_done( PS_Parser  parser );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            T1 BUILDER                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL( void )+  t1_builder_init( T1_Builder    builder,+                   FT_Face       face,+                   FT_Size       size,+                   FT_GlyphSlot  glyph,+                   FT_Bool       hinting );++  FT_LOCAL( void )+  t1_builder_done( T1_Builder  builder );++  FT_LOCAL( FT_Error )+  t1_builder_check_points( T1_Builder  builder,+                           FT_Int      count );++  FT_LOCAL( void )+  t1_builder_add_point( T1_Builder  builder,+                        FT_Pos      x,+                        FT_Pos      y,+                        FT_Byte     flag );++  FT_LOCAL( FT_Error )+  t1_builder_add_point1( T1_Builder  builder,+                         FT_Pos      x,+                         FT_Pos      y );++  FT_LOCAL( FT_Error )+  t1_builder_add_contour( T1_Builder  builder );+++  FT_LOCAL( FT_Error )+  t1_builder_start_point( T1_Builder  builder,+                          FT_Pos      x,+                          FT_Pos      y );+++  FT_LOCAL( void )+  t1_builder_close_contour( T1_Builder  builder );+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                            OTHER                              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_LOCAL( void )+  t1_decrypt( FT_Byte*   buffer,+              FT_Offset  length,+              FT_UShort  seed );+++FT_END_HEADER++#endif /* __PSOBJS_H__ */+++/* END */
+ src/psaux/t1cmap.c view
@@ -0,0 +1,341 @@+/***************************************************************************/+/*                                                                         */+/*  t1cmap.c                                                               */+/*                                                                         */+/*    Type 1 character map support (body).                                 */+/*                                                                         */+/*  Copyright 2002, 2003, 2006, 2007 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "t1cmap.h"++#include FT_INTERNAL_DEBUG_H++#include "psauxerr.h"+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  t1_cmap_std_init( T1_CMapStd  cmap,+                    FT_Int      is_expert )+  {+    T1_Face             face    = (T1_Face)FT_CMAP_FACE( cmap );+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;+++    cmap->num_glyphs    = face->type1.num_glyphs;+    cmap->glyph_names   = (const char* const*)face->type1.glyph_names;+    cmap->sid_to_string = psnames->adobe_std_strings;+    cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding+                                    : psnames->adobe_std_encoding;++    FT_ASSERT( cmap->code_to_sid != NULL );+  }+++  FT_CALLBACK_DEF( void )+  t1_cmap_std_done( T1_CMapStd  cmap )+  {+    cmap->num_glyphs    = 0;+    cmap->glyph_names   = NULL;+    cmap->sid_to_string = NULL;+    cmap->code_to_sid   = NULL;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  t1_cmap_std_char_index( T1_CMapStd  cmap,+                          FT_UInt32   char_code )+  {+    FT_UInt  result = 0;+++    if ( char_code < 256 )+    {+      FT_UInt      code, n;+      const char*  glyph_name;+++      /* convert character code to Adobe SID string */+      code       = cmap->code_to_sid[char_code];+      glyph_name = cmap->sid_to_string( code );++      /* look for the corresponding glyph name */+      for ( n = 0; n < cmap->num_glyphs; n++ )+      {+        const char* gname = cmap->glyph_names[n];+++        if ( gname && gname[0] == glyph_name[0]  &&+             ft_strcmp( gname, glyph_name ) == 0 )+        {+          result = n;+          break;+        }+      }+    }++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  t1_cmap_std_char_next( T1_CMapStd   cmap,+                         FT_UInt32   *pchar_code )+  {+    FT_UInt    result    = 0;+    FT_UInt32  char_code = *pchar_code + 1;+++    while ( char_code < 256 )+    {+      result = t1_cmap_std_char_index( cmap, char_code );+      if ( result != 0 )+        goto Exit;++      char_code++;+    }+    char_code = 0;++  Exit:+    *pchar_code = char_code;+    return result;+  }+++  FT_CALLBACK_DEF( FT_Error )+  t1_cmap_standard_init( T1_CMapStd  cmap )+  {+    t1_cmap_std_init( cmap, 0 );+    return 0;+  }+++  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec+  t1_cmap_standard_class_rec =+  {+    sizeof ( T1_CMapStdRec ),++    (FT_CMap_InitFunc)     t1_cmap_standard_init,+    (FT_CMap_DoneFunc)     t1_cmap_std_done,+    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,+    (FT_CMap_CharNextFunc) t1_cmap_std_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++  FT_CALLBACK_DEF( FT_Error )+  t1_cmap_expert_init( T1_CMapStd  cmap )+  {+    t1_cmap_std_init( cmap, 1 );+    return 0;+  }++  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec+  t1_cmap_expert_class_rec =+  {+    sizeof ( T1_CMapStdRec ),++    (FT_CMap_InitFunc)     t1_cmap_expert_init,+    (FT_CMap_DoneFunc)     t1_cmap_std_done,+    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,+    (FT_CMap_CharNextFunc) t1_cmap_std_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  FT_CALLBACK_DEF( FT_Error )+  t1_cmap_custom_init( T1_CMapCustom  cmap )+  {+    T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );+    T1_Encoding  encoding = &face->type1.encoding;+++    cmap->first   = encoding->code_first;+    cmap->count   = (FT_UInt)( encoding->code_last - cmap->first );+    cmap->indices = encoding->char_index;++    FT_ASSERT( cmap->indices != NULL );+    FT_ASSERT( encoding->code_first <= encoding->code_last );++    return 0;+  }+++  FT_CALLBACK_DEF( void )+  t1_cmap_custom_done( T1_CMapCustom  cmap )+  {+    cmap->indices = NULL;+    cmap->first   = 0;+    cmap->count   = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  t1_cmap_custom_char_index( T1_CMapCustom  cmap,+                             FT_UInt32      char_code )+  {+    FT_UInt    result = 0;+++    if ( ( char_code >= cmap->first )                  &&+         ( char_code < ( cmap->first + cmap->count ) ) )+      result = cmap->indices[char_code];++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  t1_cmap_custom_char_next( T1_CMapCustom  cmap,+                            FT_UInt32     *pchar_code )+  {+    FT_UInt    result = 0;+    FT_UInt32  char_code = *pchar_code;+++    ++char_code;++    if ( char_code < cmap->first )+      char_code = cmap->first;++    for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )+    {+      result = cmap->indices[char_code];+      if ( result != 0 )+        goto Exit;+    }++    char_code = 0;++  Exit:+    *pchar_code = char_code;+    return result;+  }+++  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec+  t1_cmap_custom_class_rec =+  {+    sizeof ( T1_CMapCustomRec ),++    (FT_CMap_InitFunc)     t1_cmap_custom_init,+    (FT_CMap_DoneFunc)     t1_cmap_custom_done,+    (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,+    (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_CALLBACK_DEF( const char * )+  t1_get_glyph_name( T1_Face  face,+                     FT_UInt  idx )+  {+    return face->type1.glyph_names[idx];+  }+++  FT_CALLBACK_DEF( FT_Error )+  t1_cmap_unicode_init( PS_Unicodes  unicodes )+  {+    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );+    FT_Memory           memory  = FT_FACE_MEMORY( face );+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;+++    return psnames->unicodes_init( memory,+                                   unicodes,+                                   face->type1.num_glyphs,+                                   (PS_GetGlyphNameFunc)&t1_get_glyph_name,+                                   (PS_FreeGlyphNameFunc)NULL,+                                   (FT_Pointer)face );+  }+++  FT_CALLBACK_DEF( void )+  t1_cmap_unicode_done( PS_Unicodes  unicodes )+  {+    FT_Face    face   = FT_CMAP_FACE( unicodes );+    FT_Memory  memory = FT_FACE_MEMORY( face );+++    FT_FREE( unicodes->maps );+    unicodes->num_maps = 0;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  t1_cmap_unicode_char_index( PS_Unicodes  unicodes,+                              FT_UInt32    char_code )+  {+    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;+++    return psnames->unicodes_char_index( unicodes, char_code );+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  t1_cmap_unicode_char_next( PS_Unicodes  unicodes,+                             FT_UInt32   *pchar_code )+  {+    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );+    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;+++    return psnames->unicodes_char_next( unicodes, pchar_code );+  }+++  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec+  t1_cmap_unicode_class_rec =+  {+    sizeof ( PS_UnicodesRec ),++    (FT_CMap_InitFunc)     t1_cmap_unicode_init,+    (FT_CMap_DoneFunc)     t1_cmap_unicode_done,+    (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,+    (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,++    NULL, NULL, NULL, NULL, NULL+  };+++/* END */
+ src/psaux/t1cmap.h view
@@ -0,0 +1,105 @@+/***************************************************************************/+/*                                                                         */+/*  t1cmap.h                                                               */+/*                                                                         */+/*    Type 1 character map support (specification).                        */+/*                                                                         */+/*  Copyright 2002, 2003, 2006 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1CMAP_H__+#define __T1CMAP_H__++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_TYPE1_TYPES_H++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* standard (and expert) encoding cmaps */+  typedef struct T1_CMapStdRec_*  T1_CMapStd;++  typedef struct  T1_CMapStdRec_+  {+    FT_CMapRec                cmap;++    const FT_UShort*          code_to_sid;+    PS_Adobe_Std_StringsFunc  sid_to_string;++    FT_UInt                   num_glyphs;+    const char* const*        glyph_names;++  } T1_CMapStdRec;+++  FT_CALLBACK_TABLE const FT_CMap_ClassRec+  t1_cmap_standard_class_rec;++  FT_CALLBACK_TABLE const FT_CMap_ClassRec+  t1_cmap_expert_class_rec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                  TYPE1 CUSTOM ENCODING CMAP                   *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  typedef struct T1_CMapCustomRec_*  T1_CMapCustom;++  typedef struct  T1_CMapCustomRec_+  {+    FT_CMapRec  cmap;+    FT_UInt     first;+    FT_UInt     count;+    FT_UShort*  indices;++  } T1_CMapCustomRec;+++  FT_CALLBACK_TABLE const FT_CMap_ClassRec+  t1_cmap_custom_class_rec;+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****             TYPE1 SYNTHETIC UNICODE ENCODING CMAP             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* unicode (synthetic) cmaps */++  FT_CALLBACK_TABLE const FT_CMap_ClassRec+  t1_cmap_unicode_class_rec;++ /* */+++FT_END_HEADER++#endif /* __T1CMAP_H__ */+++/* END */
+ src/psaux/t1decode.c view
@@ -0,0 +1,1601 @@+/***************************************************************************/+/*                                                                         */+/*  t1decode.c                                                             */+/*                                                                         */+/*    PostScript Type 1 decoding routines (body).                          */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009    */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+#include FT_OUTLINE_H++#include "t1decode.h"+#include "psobjs.h"++#include "psauxerr.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1decode+++  typedef enum  T1_Operator_+  {+    op_none = 0,+    op_endchar,+    op_hsbw,+    op_seac,+    op_sbw,+    op_closepath,+    op_hlineto,+    op_hmoveto,+    op_hvcurveto,+    op_rlineto,+    op_rmoveto,+    op_rrcurveto,+    op_vhcurveto,+    op_vlineto,+    op_vmoveto,+    op_dotsection,+    op_hstem,+    op_hstem3,+    op_vstem,+    op_vstem3,+    op_div,+    op_callothersubr,+    op_callsubr,+    op_pop,+    op_return,+    op_setcurrentpoint,+    op_unknown15,++    op_max    /* never remove this one */++  } T1_Operator;+++  static+  const FT_Int  t1_args_count[op_max] =+  {+    0, /* none */+    0, /* endchar */+    2, /* hsbw */+    5, /* seac */+    4, /* sbw */+    0, /* closepath */+    1, /* hlineto */+    1, /* hmoveto */+    4, /* hvcurveto */+    2, /* rlineto */+    2, /* rmoveto */+    6, /* rrcurveto */+    4, /* vhcurveto */+    1, /* vlineto */+    1, /* vmoveto */+    0, /* dotsection */+    2, /* hstem */+    6, /* hstem3 */+    2, /* vstem */+    6, /* vstem3 */+    2, /* div */+   -1, /* callothersubr */+    1, /* callsubr */+    0, /* pop */+    0, /* return */+    2, /* setcurrentpoint */+    2  /* opcode 15 (undocumented and obsolete) */+  };+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    t1_lookup_glyph_by_stdcharcode                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Looks up a given glyph by its StandardEncoding charcode.  Used to  */+  /*    implement the SEAC Type 1 operator.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: The current face object.                               */+  /*                                                                       */+  /*    charcode :: The character code to look for.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A glyph index in the font face.  Returns -1 if the corresponding   */+  /*    glyph wasn't found.                                                */+  /*                                                                       */+  static FT_Int+  t1_lookup_glyph_by_stdcharcode( T1_Decoder  decoder,+                                  FT_Int      charcode )+  {+    FT_UInt             n;+    const FT_String*    glyph_name;+    FT_Service_PsCMaps  psnames = decoder->psnames;+++    /* check range of standard char code */+    if ( charcode < 0 || charcode > 255 )+      return -1;++    glyph_name = psnames->adobe_std_strings(+                   psnames->adobe_std_encoding[charcode]);++    for ( n = 0; n < decoder->num_glyphs; n++ )+    {+      FT_String*  name = (FT_String*)decoder->glyph_names[n];+++      if ( name                               &&+           name[0] == glyph_name[0]           &&+           ft_strcmp( name, glyph_name ) == 0 )+        return n;+    }++    return -1;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    t1operator_seac                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Implements the `seac' Type 1 operator for a Type 1 decoder.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    decoder :: The current CID decoder.                                */+  /*                                                                       */+  /*    asb     :: The accent's side bearing.                              */+  /*                                                                       */+  /*    adx     :: The horizontal offset of the accent.                    */+  /*                                                                       */+  /*    ady     :: The vertical offset of the accent.                      */+  /*                                                                       */+  /*    bchar   :: The base character's StandardEncoding charcode.         */+  /*                                                                       */+  /*    achar   :: The accent character's StandardEncoding charcode.       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  t1operator_seac( T1_Decoder  decoder,+                   FT_Pos      asb,+                   FT_Pos      adx,+                   FT_Pos      ady,+                   FT_Int      bchar,+                   FT_Int      achar )+  {+    FT_Error     error;+    FT_Int       bchar_index, achar_index;+#if 0+    FT_Int       n_base_points;+    FT_Outline*  base = decoder->builder.base;+#endif+    FT_Vector    left_bearing, advance;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    T1_Face      face  = (T1_Face)decoder->builder.face;+#endif     +++    if ( decoder->seac )+    {+      FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));+      return PSaux_Err_Syntax_Error;+    }++    /* seac weirdness */+    adx += decoder->builder.left_bearing.x;++    /* `glyph_names' is set to 0 for CID fonts which do not */+    /* include an encoding.  How can we deal with these?    */+#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( decoder->glyph_names == 0                   &&+         !face->root.internal->incremental_interface )+#else+    if ( decoder->glyph_names == 0 )+#endif /* FT_CONFIG_OPTION_INCREMENTAL */+    {+      FT_ERROR(( "t1operator_seac:"+                 " glyph names table not available in this font\n" ));+      return PSaux_Err_Syntax_Error;+    }++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( face->root.internal->incremental_interface )+    {+      /* the caller must handle the font encoding also */+      bchar_index = bchar;+      achar_index = achar;+    }+    else+#endif+    {+      bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );+      achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );+    }++    if ( bchar_index < 0 || achar_index < 0 )+    {+      FT_ERROR(( "t1operator_seac:"+                 " invalid seac character code arguments\n" ));+      return PSaux_Err_Syntax_Error;+    }++    /* if we are trying to load a composite glyph, do not load the */+    /* accent character and return the array of subglyphs.         */+    if ( decoder->builder.no_recurse )+    {+      FT_GlyphSlot    glyph  = (FT_GlyphSlot)decoder->builder.glyph;+      FT_GlyphLoader  loader = glyph->internal->loader;+      FT_SubGlyph     subg;+++      /* reallocate subglyph array if necessary */+      error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );+      if ( error )+        goto Exit;++      subg = loader->current.subglyphs;++      /* subglyph 0 = base character */+      subg->index = bchar_index;+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |+                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;+      subg->arg1  = 0;+      subg->arg2  = 0;+      subg++;++      /* subglyph 1 = accent character */+      subg->index = achar_index;+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;+      subg->arg1  = (FT_Int)FIXED_TO_INT( adx - asb );+      subg->arg2  = (FT_Int)FIXED_TO_INT( ady );++      /* set up remaining glyph fields */+      glyph->num_subglyphs = 2;+      glyph->subglyphs     = loader->base.subglyphs;+      glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;++      loader->current.num_subglyphs = 2;+      goto Exit;+    }++    /* First load `bchar' in builder */+    /* now load the unscaled outline */++    FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */++    /* the seac operator must not be nested */+    decoder->seac = TRUE;+    error = t1_decoder_parse_glyph( decoder, bchar_index );+    decoder->seac = FALSE;+    if ( error )+      goto Exit;++    /* save the left bearing and width of the base character */+    /* as they will be erased by the next load.              */++    left_bearing = decoder->builder.left_bearing;+    advance      = decoder->builder.advance;++    decoder->builder.left_bearing.x = 0;+    decoder->builder.left_bearing.y = 0;++    decoder->builder.pos_x = adx - asb;+    decoder->builder.pos_y = ady;++    /* Now load `achar' on top of */+    /* the base outline           */++    /* the seac operator must not be nested */+    decoder->seac = TRUE;+    error = t1_decoder_parse_glyph( decoder, achar_index );+    decoder->seac = FALSE;+    if ( error )+      goto Exit;++    /* restore the left side bearing and   */+    /* advance width of the base character */++    decoder->builder.left_bearing = left_bearing;+    decoder->builder.advance      = advance;++    decoder->builder.pos_x = 0;+    decoder->builder.pos_y = 0;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    t1_decoder_parse_charstrings                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parses a given Type 1 charstrings program.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    decoder         :: The current Type 1 decoder.                     */+  /*                                                                       */+  /*    charstring_base :: The base address of the charstring stream.      */+  /*                                                                       */+  /*    charstring_len  :: The length in bytes of the charstring stream.   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  t1_decoder_parse_charstrings( T1_Decoder  decoder,+                                FT_Byte*    charstring_base,+                                FT_UInt     charstring_len )+  {+    FT_Error         error;+    T1_Decoder_Zone  zone;+    FT_Byte*         ip;+    FT_Byte*         limit;+    T1_Builder       builder = &decoder->builder;+    FT_Pos           x, y, orig_x, orig_y;+    FT_Int           known_othersubr_result_cnt   = 0;+    FT_Int           unknown_othersubr_result_cnt = 0;+    FT_Bool          large_int;+    FT_Fixed         seed;++    T1_Hints_Funcs   hinter;++#ifdef FT_DEBUG_LEVEL_TRACE+    FT_Bool          bol = TRUE;+#endif+++    /* compute random seed from stack address of parameter */+    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^+                         (FT_PtrDist)(char*)&decoder           ^+                         (FT_PtrDist)(char*)&charstring_base ) &+                         FT_ULONG_MAX ) ;+    seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;+    if ( seed == 0 )+      seed = 0x7384;++    /* First of all, initialize the decoder */+    decoder->top  = decoder->stack;+    decoder->zone = decoder->zones;+    zone          = decoder->zones;++    builder->parse_state = T1_Parse_Start;++    hinter = (T1_Hints_Funcs)builder->hints_funcs;++    /* a font that reads BuildCharArray without setting */+    /* its values first is buggy, but ...               */+    FT_ASSERT( ( decoder->len_buildchar == 0 ) ==+               ( decoder->buildchar == NULL )  );++    if ( decoder->len_buildchar > 0 )+      ft_memset( &decoder->buildchar[0],+                 0,+                 sizeof( decoder->buildchar[0] ) * decoder->len_buildchar );++    FT_TRACE4(( "\n"+                "Start charstring\n" ));++    zone->base           = charstring_base;+    limit = zone->limit  = charstring_base + charstring_len;+    ip    = zone->cursor = zone->base;++    error = PSaux_Err_Ok;++    x = orig_x = builder->pos_x;+    y = orig_y = builder->pos_y;++    /* begin hints recording session, if any */+    if ( hinter )+      hinter->open( hinter->hints );++    large_int = FALSE;++    /* now, execute loop */+    while ( ip < limit )+    {+      FT_Long*     top   = decoder->top;+      T1_Operator  op    = op_none;+      FT_Int32     value = 0;+++      FT_ASSERT( known_othersubr_result_cnt == 0   ||+                 unknown_othersubr_result_cnt == 0 );++#ifdef FT_DEBUG_LEVEL_TRACE+      if ( bol )+      {+        FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));+        bol = FALSE;+      }+#endif++      /*********************************************************************/+      /*                                                                   */+      /* Decode operator or operand                                        */+      /*                                                                   */+      /*                                                                   */++      /* first of all, decompress operator or value */+      switch ( *ip++ )+      {+      case 1:+        op = op_hstem;+        break;++      case 3:+        op = op_vstem;+        break;+      case 4:+        op = op_vmoveto;+        break;+      case 5:+        op = op_rlineto;+        break;+      case 6:+        op = op_hlineto;+        break;+      case 7:+        op = op_vlineto;+        break;+      case 8:+        op = op_rrcurveto;+        break;+      case 9:+        op = op_closepath;+        break;+      case 10:+        op = op_callsubr;+        break;+      case 11:+        op = op_return;+        break;++      case 13:+        op = op_hsbw;+        break;+      case 14:+        op = op_endchar;+        break;++      case 15:          /* undocumented, obsolete operator */+        op = op_unknown15;+        break;++      case 21:+        op = op_rmoveto;+        break;+      case 22:+        op = op_hmoveto;+        break;++      case 30:+        op = op_vhcurveto;+        break;+      case 31:+        op = op_hvcurveto;+        break;++      case 12:+        if ( ip > limit )+        {+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " invalid escape (12+EOF)\n" ));+          goto Syntax_Error;+        }++        switch ( *ip++ )+        {+        case 0:+          op = op_dotsection;+          break;+        case 1:+          op = op_vstem3;+          break;+        case 2:+          op = op_hstem3;+          break;+        case 6:+          op = op_seac;+          break;+        case 7:+          op = op_sbw;+          break;+        case 12:+          op = op_div;+          break;+        case 16:+          op = op_callothersubr;+          break;+        case 17:+          op = op_pop;+          break;+        case 33:+          op = op_setcurrentpoint;+          break;++        default:+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " invalid escape (12+%d)\n",+                     ip[-1] ));+          goto Syntax_Error;+        }+        break;++      case 255:    /* four bytes integer */+        if ( ip + 4 > limit )+        {+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " unexpected EOF in integer\n" ));+          goto Syntax_Error;+        }++        value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |+                            ( (FT_Long)ip[1] << 16 ) |+                            ( (FT_Long)ip[2] << 8  ) |+                                       ip[3]         );+        ip += 4;++        /* According to the specification, values > 32000 or < -32000 must */+        /* be followed by a `div' operator to make the result be in the    */+        /* range [-32000;32000].  We expect that the second argument of    */+        /* `div' is not a large number.  Additionally, we don't handle     */+        /* stuff like `<large1> <large2> <num> div <num> div' or           */+        /* <large1> <large2> <num> div div'.  This is probably not allowed */+        /* anyway.                                                         */+        if ( value > 32000 || value < -32000 )+        {+          if ( large_int )+          {+            FT_ERROR(( "t1_decoder_parse_charstrings:"+                       " no `div' after large integer\n" ));+          }+          else+            large_int = TRUE;+        }+        else+        {+          if ( !large_int )+            value <<= 16;+        }++        break;++      default:+        if ( ip[-1] >= 32 )+        {+          if ( ip[-1] < 247 )+            value = (FT_Int32)ip[-1] - 139;+          else+          {+            if ( ++ip > limit )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " unexpected EOF in integer\n" ));+              goto Syntax_Error;+            }++            if ( ip[-2] < 251 )+              value =  ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;+            else+              value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );+          }++          if ( !large_int )+            value <<= 16;+        }+        else+        {+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " invalid byte (%d)\n", ip[-1] ));+          goto Syntax_Error;+        }+      }++      if ( unknown_othersubr_result_cnt > 0 )+      {+        switch ( op )+        {+        case op_callsubr:+        case op_return:+        case op_none:+        case op_pop:+          break;++        default:+          /* all operands have been transferred by previous pops */+          unknown_othersubr_result_cnt = 0;+          break;+        }+      }++      if ( large_int && !( op == op_none || op == op_div ) )+      {+        FT_ERROR(( "t1_decoder_parse_charstrings:"+                   " no `div' after large integer\n" ));++        large_int = FALSE;+      }++      /*********************************************************************/+      /*                                                                   */+      /*  Push value on stack, or process operator                         */+      /*                                                                   */+      /*                                                                   */+      if ( op == op_none )+      {+        if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )+        {+          FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));+          goto Syntax_Error;+        }++#ifdef FT_DEBUG_LEVEL_TRACE+        if ( large_int )+          FT_TRACE4(( " %ld", value ));+        else+          FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) ));+#endif++        *top++       = value;+        decoder->top = top;+      }+      else if ( op == op_callothersubr )  /* callothersubr */+      {+        FT_Int  subr_no;+        FT_Int  arg_cnt;+++#ifdef FT_DEBUG_LEVEL_TRACE+        FT_TRACE4(( " callothersubr\n" ));+        bol = TRUE;+#endif++        if ( top - decoder->stack < 2 )+          goto Stack_Underflow;++        top -= 2;++        subr_no = (FT_Int)( top[1] >> 16 );+        arg_cnt = (FT_Int)( top[0] >> 16 );++        /***********************************************************/+        /*                                                         */+        /* remove all operands to callothersubr from the stack     */+        /*                                                         */+        /* for handled othersubrs, where we know the number of     */+        /* arguments, we increase the stack by the value of        */+        /* known_othersubr_result_cnt                              */+        /*                                                         */+        /* for unhandled othersubrs the following pops adjust the  */+        /* stack pointer as necessary                              */++        if ( arg_cnt > top - decoder->stack )+          goto Stack_Underflow;++        top -= arg_cnt;++        known_othersubr_result_cnt   = 0;+        unknown_othersubr_result_cnt = 0;++        /* XXX TODO: The checks to `arg_count == <whatever>'       */+        /* might not be correct; an othersubr expects a certain    */+        /* number of operands on the PostScript stack (as opposed  */+        /* to the T1 stack) but it doesn't have to put them there  */+        /* by itself; previous othersubrs might have left the      */+        /* operands there if they were not followed by an          */+        /* appropriate number of pops                              */+        /*                                                         */+        /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */+        /* accept a font that contains charstrings like            */+        /*                                                         */+        /*     100 200 2 20 callothersubr                          */+        /*     300 1 20 callothersubr pop                          */+        /*                                                         */+        /* Perhaps this is the reason why BuildCharArray exists.   */++        switch ( subr_no )+        {+        case 1:                     /* start flex feature */+          if ( arg_cnt != 0 )+            goto Unexpected_OtherSubr;++          decoder->flex_state        = 1;+          decoder->num_flex_vectors  = 0;+          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok                                   ||+               ( error = t1_builder_check_points( builder, 6 ) )+                 != PSaux_Err_Ok                                   )+            goto Fail;+          break;++        case 2:                     /* add flex vectors */+          {+            FT_Int  idx;+++            if ( arg_cnt != 0 )+              goto Unexpected_OtherSubr;++            /* note that we should not add a point for index 0; */+            /* this will move our current position to the flex  */+            /* point without adding any point to the outline    */+            idx = decoder->num_flex_vectors++;+            if ( idx > 0 && idx < 7 )+              t1_builder_add_point( builder,+                                    x,+                                    y,+                                    (FT_Byte)( idx == 3 || idx == 6 ) );+          }+          break;++        case 0:                     /* end flex feature */+          if ( arg_cnt != 3 )+            goto Unexpected_OtherSubr;++          if ( decoder->flex_state       == 0 ||+               decoder->num_flex_vectors != 7 )+          {+            FT_ERROR(( "t1_decoder_parse_charstrings:"+                       " unexpected flex end\n" ));+            goto Syntax_Error;+          }++          /* the two `results' are popped by the following setcurrentpoint */+          top[0] = x;+          top[1] = y;+          known_othersubr_result_cnt = 2;+          break;++        case 3:                     /* change hints */+          if ( arg_cnt != 1 )+            goto Unexpected_OtherSubr;++          known_othersubr_result_cnt = 1;++          if ( hinter )+            hinter->reset( hinter->hints, builder->current->n_points );+          break;++        case 12:+        case 13:+          /* counter control hints, clear stack */+          top = decoder->stack;+          break;++        case 14:+        case 15:+        case 16:+        case 17:+        case 18:                    /* multiple masters */+          {+            PS_Blend  blend = decoder->blend;+            FT_UInt   num_points, nn, mm;+            FT_Long*  delta;+            FT_Long*  values;+++            if ( !blend )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " unexpected multiple masters operator\n" ));+              goto Syntax_Error;+            }++            num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );+            if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " incorrect number of multiple masters arguments\n" ));+              goto Syntax_Error;+            }++            /* we want to compute:                                   */+            /*                                                       */+            /*  a0*w0 + a1*w1 + ... + ak*wk                          */+            /*                                                       */+            /* but we only have the a0, a1-a0, a2-a0, .. ak-a0       */+            /* however, given that w0 + w1 + ... + wk == 1, we can   */+            /* rewrite it easily as:                                 */+            /*                                                       */+            /*  a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk       */+            /*                                                       */+            /* where k == num_designs-1                              */+            /*                                                       */+            /* I guess that's why it's written in this `compact'     */+            /* form.                                                 */+            /*                                                       */+            delta  = top + num_points;+            values = top;+            for ( nn = 0; nn < num_points; nn++ )+            {+              FT_Long  tmp = values[0];+++              for ( mm = 1; mm < blend->num_designs; mm++ )+                tmp += FT_MulFix( *delta++, blend->weight_vector[mm] );++              *values++ = tmp;+            }++            known_othersubr_result_cnt = num_points;+            break;+          }++        case 19:+          /* <idx> 1 19 callothersubr                             */+          /* => replace elements starting from index cvi( <idx> ) */+          /*    of BuildCharArray with WeightVector               */+          {+            FT_Int    idx;+            PS_Blend  blend = decoder->blend;+++            if ( arg_cnt != 1 || blend == NULL )+              goto Unexpected_OtherSubr;++            idx = (FT_Int)( top[0] >> 16 );++            if ( idx < 0                                           ||+                 idx + blend->num_designs > decoder->len_buildchar )+              goto Unexpected_OtherSubr;++            ft_memcpy( &decoder->buildchar[idx],+                       blend->weight_vector,+                       blend->num_designs *+                         sizeof( blend->weight_vector[0] ) );+          }+          break;++        case 20:+          /* <arg1> <arg2> 2 20 callothersubr pop   */+          /* ==> push <arg1> + <arg2> onto T1 stack */+          if ( arg_cnt != 2 )+            goto Unexpected_OtherSubr;++          top[0] += top[1]; /* XXX (over|under)flow */++          known_othersubr_result_cnt = 1;+          break;++        case 21:+          /* <arg1> <arg2> 2 21 callothersubr pop   */+          /* ==> push <arg1> - <arg2> onto T1 stack */+          if ( arg_cnt != 2 )+            goto Unexpected_OtherSubr;++          top[0] -= top[1]; /* XXX (over|under)flow */++          known_othersubr_result_cnt = 1;+          break;++        case 22:+          /* <arg1> <arg2> 2 22 callothersubr pop   */+          /* ==> push <arg1> * <arg2> onto T1 stack */+          if ( arg_cnt != 2 )+            goto Unexpected_OtherSubr;++          top[0] = FT_MulFix( top[0], top[1] );++          known_othersubr_result_cnt = 1;+          break;++        case 23:+          /* <arg1> <arg2> 2 23 callothersubr pop   */+          /* ==> push <arg1> / <arg2> onto T1 stack */+          if ( arg_cnt != 2 || top[1] == 0 )+            goto Unexpected_OtherSubr;++          top[0] = FT_DivFix( top[0], top[1] );++          known_othersubr_result_cnt = 1;+          break;++        case 24:+          /* <val> <idx> 2 24 callothersubr               */+          /* ==> set BuildCharArray[cvi( <idx> )] = <val> */+          {+            FT_Int    idx;+            PS_Blend  blend = decoder->blend;+++            if ( arg_cnt != 2 || blend == NULL )+              goto Unexpected_OtherSubr;++            idx = (FT_Int)( top[1] >> 16 );++            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )+              goto Unexpected_OtherSubr;++            decoder->buildchar[idx] = top[0];+          }+          break;++        case 25:+          /* <idx> 1 25 callothersubr pop        */+          /* ==> push BuildCharArray[cvi( idx )] */+          /*     onto T1 stack                   */+          {+            FT_Int    idx;+            PS_Blend  blend = decoder->blend;+++            if ( arg_cnt != 1 || blend == NULL )+              goto Unexpected_OtherSubr;++            idx = (FT_Int)( top[0] >> 16 );++            if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )+              goto Unexpected_OtherSubr;++            top[0] = decoder->buildchar[idx];+          }++          known_othersubr_result_cnt = 1;+          break;++#if 0+        case 26:+          /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */+          /*                      leave mark on T1 stack                    */+          /* <val> <idx>      ==> set BuildCharArray[cvi( <idx> )] = <val>  */+          XXX which routine has left its mark on the (PostScript) stack?;+          break;+#endif++        case 27:+          /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */+          /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */+          /*     otherwise push <res2>                          */+          if ( arg_cnt != 4 )+            goto Unexpected_OtherSubr;++          if ( top[2] > top[3] )+            top[0] = top[1];++          known_othersubr_result_cnt = 1;+          break;++        case 28:+          /* 0 28 callothersubr pop                               */+          /* => push random value from interval [0, 1) onto stack */+          if ( arg_cnt != 0 )+            goto Unexpected_OtherSubr;++          {+            FT_Fixed  Rand;+++            Rand = seed;+            if ( Rand >= 0x8000L )+              Rand++;++            top[0] = Rand;++            seed = FT_MulFix( seed, 0x10000L - seed );+            if ( seed == 0 )+              seed += 0x2873;+          }++          known_othersubr_result_cnt = 1;+          break;++        default:+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " unknown othersubr [%d %d], wish me luck\n",+                     arg_cnt, subr_no ));+          unknown_othersubr_result_cnt = arg_cnt;+          break;++        Unexpected_OtherSubr:+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));+          goto Syntax_Error;+        }++        top += known_othersubr_result_cnt;++        decoder->top = top;+      }+      else  /* general operator */+      {+        FT_Int  num_args = t1_args_count[op];+++        FT_ASSERT( num_args >= 0 );++        if ( top - decoder->stack < num_args )+          goto Stack_Underflow;++        /* XXX Operators usually take their operands from the        */+        /*     bottom of the stack, i.e., the operands are           */+        /*     decoder->stack[0], ..., decoder->stack[num_args - 1]; */+        /*     only div, callsubr, and callothersubr are different.  */+        /*     In practice it doesn't matter (?).                    */++#ifdef FT_DEBUG_LEVEL_TRACE++        switch ( op )+        {+        case op_callsubr:+        case op_div:+        case op_callothersubr:+        case op_pop:+        case op_return:+          break;++        default:+          if ( top - decoder->stack != num_args )+            FT_TRACE0(( "t1_decoder_parse_charstrings:"+                        " too much operands on the stack"+                        " (seen %d, expected %d)\n",+                        top - decoder->stack, num_args ));+            break;+        }++#endif /* FT_DEBUG_LEVEL_TRACE */++        top -= num_args;++        switch ( op )+        {+        case op_endchar:+          FT_TRACE4(( " endchar\n" ));++          t1_builder_close_contour( builder );++          /* close hints recording session */+          if ( hinter )+          {+            if ( hinter->close( hinter->hints, builder->current->n_points ) )+              goto Syntax_Error;++            /* apply hints to the loaded glyph outline now */+            hinter->apply( hinter->hints,+                           builder->current,+                           (PSH_Globals)builder->hints_globals,+                           decoder->hint_mode );+          }++          /* add current outline to the glyph slot */+          FT_GlyphLoader_Add( builder->loader );++          /* the compiler should optimize away this empty loop but ... */++#ifdef FT_DEBUG_LEVEL_TRACE++          if ( decoder->len_buildchar > 0 )+          {+            FT_UInt  i;+++            FT_TRACE4(( "BuildCharArray = [ " ));++            for ( i = 0; i < decoder->len_buildchar; ++i )+              FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));++            FT_TRACE4(( "]\n" ));+          }++#endif /* FT_DEBUG_LEVEL_TRACE */++          FT_TRACE4(( "\n" ));++          /* return now! */+          return PSaux_Err_Ok;++        case op_hsbw:+          FT_TRACE4(( " hsbw" ));++          builder->parse_state = T1_Parse_Have_Width;++          builder->left_bearing.x += top[0];+          builder->advance.x       = top[1];+          builder->advance.y       = 0;++          orig_x = x = builder->pos_x + top[0];+          orig_y = y = builder->pos_y;++          FT_UNUSED( orig_y );++          /* the `metrics_only' indicates that we only want to compute */+          /* the glyph's metrics (lsb + advance width), not load the   */+          /* rest of it; so exit immediately                           */+          if ( builder->metrics_only )+            return PSaux_Err_Ok;++          break;++        case op_seac:+          return t1operator_seac( decoder,+                                  top[0],+                                  top[1],+                                  top[2],+                                  (FT_Int)( top[3] >> 16 ),+                                  (FT_Int)( top[4] >> 16 ) );++        case op_sbw:+          FT_TRACE4(( " sbw" ));++          builder->parse_state = T1_Parse_Have_Width;++          builder->left_bearing.x += top[0];+          builder->left_bearing.y += top[1];+          builder->advance.x       = top[2];+          builder->advance.y       = top[3];++          x = builder->pos_x + top[0];+          y = builder->pos_y + top[1];++          /* the `metrics_only' indicates that we only want to compute */+          /* the glyph's metrics (lsb + advance width), not load the   */+          /* rest of it; so exit immediately                           */+          if ( builder->metrics_only )+            return PSaux_Err_Ok;++          break;++        case op_closepath:+          FT_TRACE4(( " closepath" ));++          /* if there is no path, `closepath' is a no-op */+          if ( builder->parse_state == T1_Parse_Have_Path   ||+               builder->parse_state == T1_Parse_Have_Moveto )+            t1_builder_close_contour( builder );++          builder->parse_state = T1_Parse_Have_Width;+          break;++        case op_hlineto:+          FT_TRACE4(( " hlineto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok )+            goto Fail;++          x += top[0];+          goto Add_Line;++        case op_hmoveto:+          FT_TRACE4(( " hmoveto" ));++          x += top[0];+          if ( !decoder->flex_state )+          {+            if ( builder->parse_state == T1_Parse_Start )+              goto Syntax_Error;+            builder->parse_state = T1_Parse_Have_Moveto;+          }+          break;++        case op_hvcurveto:+          FT_TRACE4(( " hvcurveto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok                                   ||+               ( error = t1_builder_check_points( builder, 3 ) )+                 != PSaux_Err_Ok                                   )+            goto Fail;++          x += top[0];+          t1_builder_add_point( builder, x, y, 0 );+          x += top[1];+          y += top[2];+          t1_builder_add_point( builder, x, y, 0 );+          y += top[3];+          t1_builder_add_point( builder, x, y, 1 );+          break;++        case op_rlineto:+          FT_TRACE4(( " rlineto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok )+            goto Fail;++          x += top[0];+          y += top[1];++        Add_Line:+          if ( ( error = t1_builder_add_point1( builder, x, y ) )+                 != PSaux_Err_Ok )+            goto Fail;+          break;++        case op_rmoveto:+          FT_TRACE4(( " rmoveto" ));++          x += top[0];+          y += top[1];+          if ( !decoder->flex_state )+          {+            if ( builder->parse_state == T1_Parse_Start )+              goto Syntax_Error;+            builder->parse_state = T1_Parse_Have_Moveto;+          }+          break;++        case op_rrcurveto:+          FT_TRACE4(( " rrcurveto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok                                   ||+               ( error = t1_builder_check_points( builder, 3 ) )+                 != PSaux_Err_Ok                                   )+            goto Fail;++          x += top[0];+          y += top[1];+          t1_builder_add_point( builder, x, y, 0 );++          x += top[2];+          y += top[3];+          t1_builder_add_point( builder, x, y, 0 );++          x += top[4];+          y += top[5];+          t1_builder_add_point( builder, x, y, 1 );+          break;++        case op_vhcurveto:+          FT_TRACE4(( " vhcurveto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok                                   ||+               ( error = t1_builder_check_points( builder, 3 ) )+                 != PSaux_Err_Ok                                   )+            goto Fail;++          y += top[0];+          t1_builder_add_point( builder, x, y, 0 );+          x += top[1];+          y += top[2];+          t1_builder_add_point( builder, x, y, 0 );+          x += top[3];+          t1_builder_add_point( builder, x, y, 1 );+          break;++        case op_vlineto:+          FT_TRACE4(( " vlineto" ));++          if ( ( error = t1_builder_start_point( builder, x, y ) )+                 != PSaux_Err_Ok )+            goto Fail;++          y += top[0];+          goto Add_Line;++        case op_vmoveto:+          FT_TRACE4(( " vmoveto" ));++          y += top[0];+          if ( !decoder->flex_state )+          {+            if ( builder->parse_state == T1_Parse_Start )+              goto Syntax_Error;+            builder->parse_state = T1_Parse_Have_Moveto;+          }+          break;++        case op_div:+          FT_TRACE4(( " div" ));++          /* if `large_int' is set, we divide unscaled numbers; */+          /* otherwise, we divide numbers in 16.16 format --    */+          /* in both cases, it is the same operation            */+          *top = FT_DivFix( top[0], top[1] );+          ++top;++          large_int = FALSE;+          break;++        case op_callsubr:+          {+            FT_Int  idx;+++            FT_TRACE4(( " callsubr" ));++            idx = (FT_Int)( top[0] >> 16 );+            if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " invalid subrs index\n" ));+              goto Syntax_Error;+            }++            if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " too many nested subrs\n" ));+              goto Syntax_Error;+            }++            zone->cursor = ip;  /* save current instruction pointer */++            zone++;++            /* The Type 1 driver stores subroutines without the seed bytes. */+            /* The CID driver stores subroutines with seed bytes.  This     */+            /* case is taken care of when decoder->subrs_len == 0.          */+            zone->base = decoder->subrs[idx];++            if ( decoder->subrs_len )+              zone->limit = zone->base + decoder->subrs_len[idx];+            else+            {+              /* We are using subroutines from a CID font.  We must adjust */+              /* for the seed bytes.                                       */+              zone->base  += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );+              zone->limit  = decoder->subrs[idx + 1];+            }++            zone->cursor = zone->base;++            if ( !zone->base )+            {+              FT_ERROR(( "t1_decoder_parse_charstrings:"+                         " invoking empty subrs\n" ));+              goto Syntax_Error;+            }++            decoder->zone = zone;+            ip            = zone->base;+            limit         = zone->limit;+            break;+          }++        case op_pop:+          FT_TRACE4(( " pop" ));++          if ( known_othersubr_result_cnt > 0 )+          {+            known_othersubr_result_cnt--;+            /* ignore, we pushed the operands ourselves */+            break;+          }++          if ( unknown_othersubr_result_cnt == 0 )+          {+            FT_ERROR(( "t1_decoder_parse_charstrings:"+                       " no more operands for othersubr\n" ));+            goto Syntax_Error;+          }++          unknown_othersubr_result_cnt--;+          top++;   /* `push' the operand to callothersubr onto the stack */+          break;++        case op_return:+          FT_TRACE4(( " return" ));++          if ( zone <= decoder->zones )+          {+            FT_ERROR(( "t1_decoder_parse_charstrings:"+                       " unexpected return\n" ));+            goto Syntax_Error;+          }++          zone--;+          ip            = zone->cursor;+          limit         = zone->limit;+          decoder->zone = zone;+          break;++        case op_dotsection:+          FT_TRACE4(( " dotsection" ));++          break;++        case op_hstem:+          FT_TRACE4(( " hstem" ));++          /* record horizontal hint */+          if ( hinter )+          {+            /* top[0] += builder->left_bearing.y; */+            hinter->stem( hinter->hints, 1, top );+          }+          break;++        case op_hstem3:+          FT_TRACE4(( " hstem3" ));++          /* record horizontal counter-controlled hints */+          if ( hinter )+            hinter->stem3( hinter->hints, 1, top );+          break;++        case op_vstem:+          FT_TRACE4(( " vstem" ));++          /* record vertical hint */+          if ( hinter )+          {+            top[0] += orig_x;+            hinter->stem( hinter->hints, 0, top );+          }+          break;++        case op_vstem3:+          FT_TRACE4(( " vstem3" ));++          /* record vertical counter-controlled hints */+          if ( hinter )+          {+            FT_Pos  dx = orig_x;+++            top[0] += dx;+            top[2] += dx;+            top[4] += dx;+            hinter->stem3( hinter->hints, 0, top );+          }+          break;++        case op_setcurrentpoint:+          FT_TRACE4(( " setcurrentpoint" ));++          /* From the T1 specification, section 6.4:                */+          /*                                                        */+          /*   The setcurrentpoint command is used only in          */+          /*   conjunction with results from OtherSubrs procedures. */++          /* known_othersubr_result_cnt != 0 is already handled     */+          /* above.                                                 */++          /* Note, however, that both Ghostscript and Adobe         */+          /* Distiller handle this situation by silently ignoring   */+          /* the inappropriate `setcurrentpoint' instruction.  So   */+          /* we do the same.                                        */+#if 0++          if ( decoder->flex_state != 1 )+          {+            FT_ERROR(( "t1_decoder_parse_charstrings:"+                       " unexpected `setcurrentpoint'\n" ));+            goto Syntax_Error;+          }+          else+            ...+#endif++          x = top[0];+          y = top[1];+          decoder->flex_state = 0;+          break;++        case op_unknown15:+          FT_TRACE4(( " opcode_15" ));+          /* nothing to do except to pop the two arguments */+          break;++        default:+          FT_ERROR(( "t1_decoder_parse_charstrings:"+                     " unhandled opcode %d\n", op ));+          goto Syntax_Error;+        }++        /* XXX Operators usually clear the operand stack;  */+        /*     only div, callsubr, callothersubr, pop, and */+        /*     return are different.                       */+        /*     In practice it doesn't matter (?).          */++        decoder->top = top;++#ifdef FT_DEBUG_LEVEL_TRACE+        FT_TRACE4(( "\n" ));+        bol = TRUE;+#endif++      } /* general operator processing */++    } /* while ip < limit */++    FT_TRACE4(( "..end..\n\n" ));++  Fail:+    return error;++  Syntax_Error:+    return PSaux_Err_Syntax_Error;++  Stack_Underflow:+    return PSaux_Err_Stack_Underflow;+  }+++  /* parse a single Type 1 glyph */+  FT_LOCAL_DEF( FT_Error )+  t1_decoder_parse_glyph( T1_Decoder  decoder,+                          FT_UInt     glyph )+  {+    return decoder->parse_callback( decoder, glyph );+  }+++  /* initialize T1 decoder */+  FT_LOCAL_DEF( FT_Error )+  t1_decoder_init( T1_Decoder           decoder,+                   FT_Face              face,+                   FT_Size              size,+                   FT_GlyphSlot         slot,+                   FT_Byte**            glyph_names,+                   PS_Blend             blend,+                   FT_Bool              hinting,+                   FT_Render_Mode       hint_mode,+                   T1_Decoder_Callback  parse_callback )+  {+    FT_MEM_ZERO( decoder, sizeof ( *decoder ) );++    /* retrieve PSNames interface from list of current modules */+    {+      FT_Service_PsCMaps  psnames = 0;+++      FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );+      if ( !psnames )+      {+        FT_ERROR(( "t1_decoder_init:"+                   " the `psnames' module is not available\n" ));+        return PSaux_Err_Unimplemented_Feature;+      }++      decoder->psnames = psnames;+    }++    t1_builder_init( &decoder->builder, face, size, slot, hinting );++    /* decoder->buildchar and decoder->len_buildchar have to be  */+    /* initialized by the caller since we cannot know the length */+    /* of the BuildCharArray                                     */++    decoder->num_glyphs     = (FT_UInt)face->num_glyphs;+    decoder->glyph_names    = glyph_names;+    decoder->hint_mode      = hint_mode;+    decoder->blend          = blend;+    decoder->parse_callback = parse_callback;++    decoder->funcs          = t1_decoder_funcs;++    return PSaux_Err_Ok;+  }+++  /* finalize T1 decoder */+  FT_LOCAL_DEF( void )+  t1_decoder_done( T1_Decoder  decoder )+  {+    t1_builder_done( &decoder->builder );+  }+++/* END */
+ src/psaux/t1decode.h view
@@ -0,0 +1,64 @@+/***************************************************************************/+/*                                                                         */+/*  t1decode.h                                                             */+/*                                                                         */+/*    PostScript Type 1 decoding routines (specification).                 */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1DECODE_H__+#define __T1DECODE_H__+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_AUX_H+#include FT_INTERNAL_TYPE1_TYPES_H+++FT_BEGIN_HEADER+++  FT_CALLBACK_TABLE+  const T1_Decoder_FuncsRec  t1_decoder_funcs;+++  FT_LOCAL( FT_Error )+  t1_decoder_parse_glyph( T1_Decoder  decoder,+                          FT_UInt     glyph_index );++  FT_LOCAL( FT_Error )+  t1_decoder_parse_charstrings( T1_Decoder  decoder,+                                FT_Byte*    base,+                                FT_UInt     len );++  FT_LOCAL( FT_Error )+  t1_decoder_init( T1_Decoder           decoder,+                   FT_Face              face,+                   FT_Size              size,+                   FT_GlyphSlot         slot,+                   FT_Byte**            glyph_names,+                   PS_Blend             blend,+                   FT_Bool              hinting,+                   FT_Render_Mode       hint_mode,+                   T1_Decoder_Callback  parse_glyph );++  FT_LOCAL( void )+  t1_decoder_done( T1_Decoder  decoder );+++FT_END_HEADER++#endif /* __T1DECODE_H__ */+++/* END */
+ src/pshinter/pshalgo.c view
@@ -0,0 +1,2306 @@+/***************************************************************************/+/*                                                                         */+/*  pshalgo.c                                                              */+/*                                                                         */+/*    PostScript hinting algorithm (body).                                 */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010   */+/*            by                                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used        */+/*  modified and distributed under the terms of the FreeType project       */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H+#include "pshalgo.h"++#include "pshnterr.h"+++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pshalgo2+++#ifdef DEBUG_HINTER+  PSH_Hint_Table  ps_debug_hint_table = 0;+  PSH_HintFunc    ps_debug_hint_func  = 0;+  PSH_Glyph       ps_debug_glyph      = 0;+#endif+++#define  COMPUTE_INFLEXS  /* compute inflection points to optimize `S' */+                          /* and similar glyphs                        */+#define  STRONGER         /* slightly increase the contrast of smooth  */+                          /* hinting                                   */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                  BASIC HINTS RECORDINGS                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* return true if two stem hints overlap */+  static FT_Int+  psh_hint_overlap( PSH_Hint  hint1,+                    PSH_Hint  hint2 )+  {+    return hint1->org_pos + hint1->org_len >= hint2->org_pos &&+           hint2->org_pos + hint2->org_len >= hint1->org_pos;+  }+++  /* destroy hints table */+  static void+  psh_hint_table_done( PSH_Hint_Table  table,+                       FT_Memory       memory )+  {+    FT_FREE( table->zones );+    table->num_zones = 0;+    table->zone      = 0;++    FT_FREE( table->sort );+    FT_FREE( table->hints );+    table->num_hints   = 0;+    table->max_hints   = 0;+    table->sort_global = 0;+  }+++  /* deactivate all hints in a table */+  static void+  psh_hint_table_deactivate( PSH_Hint_Table  table )+  {+    FT_UInt   count = table->max_hints;+    PSH_Hint  hint  = table->hints;+++    for ( ; count > 0; count--, hint++ )+    {+      psh_hint_deactivate( hint );+      hint->order = -1;+    }+  }+++  /* internal function to record a new hint */+  static void+  psh_hint_table_record( PSH_Hint_Table  table,+                         FT_UInt         idx )+  {+    PSH_Hint  hint = table->hints + idx;+++    if ( idx >= table->max_hints )+    {+      FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx ));+      return;+    }++    /* ignore active hints */+    if ( psh_hint_is_active( hint ) )+      return;++    psh_hint_activate( hint );++    /* now scan the current active hint set to check */+    /* whether `hint' overlaps with another hint     */+    {+      PSH_Hint*  sorted = table->sort_global;+      FT_UInt    count  = table->num_hints;+      PSH_Hint   hint2;+++      hint->parent = 0;+      for ( ; count > 0; count--, sorted++ )+      {+        hint2 = sorted[0];++        if ( psh_hint_overlap( hint, hint2 ) )+        {+          hint->parent = hint2;+          break;+        }+      }+    }++    if ( table->num_hints < table->max_hints )+      table->sort_global[table->num_hints++] = hint;+    else+      FT_TRACE0(( "psh_hint_table_record: too many sorted hints!  BUG!\n" ));+  }+++  static void+  psh_hint_table_record_mask( PSH_Hint_Table  table,+                              PS_Mask         hint_mask )+  {+    FT_Int    mask = 0, val = 0;+    FT_Byte*  cursor = hint_mask->bytes;+    FT_UInt   idx, limit;+++    limit = hint_mask->num_bits;++    for ( idx = 0; idx < limit; idx++ )+    {+      if ( mask == 0 )+      {+        val  = *cursor++;+        mask = 0x80;+      }++      if ( val & mask )+        psh_hint_table_record( table, idx );++      mask >>= 1;+    }+  }+++  /* create hints table */+  static FT_Error+  psh_hint_table_init( PSH_Hint_Table  table,+                       PS_Hint_Table   hints,+                       PS_Mask_Table   hint_masks,+                       PS_Mask_Table   counter_masks,+                       FT_Memory       memory )+  {+    FT_UInt   count;+    FT_Error  error;++    FT_UNUSED( counter_masks );+++    count = hints->num_hints;++    /* allocate our tables */+    if ( FT_NEW_ARRAY( table->sort,  2 * count     ) ||+         FT_NEW_ARRAY( table->hints,     count     ) ||+         FT_NEW_ARRAY( table->zones, 2 * count + 1 ) )+      goto Exit;++    table->max_hints   = count;+    table->sort_global = table->sort + count;+    table->num_hints   = 0;+    table->num_zones   = 0;+    table->zone        = 0;++    /* initialize the `table->hints' array */+    {+      PSH_Hint  write = table->hints;+      PS_Hint   read  = hints->hints;+++      for ( ; count > 0; count--, write++, read++ )+      {+        write->org_pos = read->pos;+        write->org_len = read->len;+        write->flags   = read->flags;+      }+    }++    /* we now need to determine the initial `parent' stems; first  */+    /* activate the hints that are given by the initial hint masks */+    if ( hint_masks )+    {+      PS_Mask  mask = hint_masks->masks;+++      count             = hint_masks->num_masks;+      table->hint_masks = hint_masks;++      for ( ; count > 0; count--, mask++ )+        psh_hint_table_record_mask( table, mask );+    }++    /* finally, do a linear parse in case some hints were left alone */+    if ( table->num_hints != table->max_hints )+    {+      FT_UInt  idx;+++      FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" ));++      count = table->max_hints;+      for ( idx = 0; idx < count; idx++ )+        psh_hint_table_record( table, idx );+    }++  Exit:+    return error;+  }+++  static void+  psh_hint_table_activate_mask( PSH_Hint_Table  table,+                                PS_Mask         hint_mask )+  {+    FT_Int    mask = 0, val = 0;+    FT_Byte*  cursor = hint_mask->bytes;+    FT_UInt   idx, limit, count;+++    limit = hint_mask->num_bits;+    count = 0;++    psh_hint_table_deactivate( table );++    for ( idx = 0; idx < limit; idx++ )+    {+      if ( mask == 0 )+      {+        val  = *cursor++;+        mask = 0x80;+      }++      if ( val & mask )+      {+        PSH_Hint  hint = &table->hints[idx];+++        if ( !psh_hint_is_active( hint ) )+        {+          FT_UInt     count2;++#if 0+          PSH_Hint*  sort = table->sort;+          PSH_Hint   hint2;+++          for ( count2 = count; count2 > 0; count2--, sort++ )+          {+            hint2 = sort[0];+            if ( psh_hint_overlap( hint, hint2 ) )+              FT_TRACE0(( "psh_hint_table_activate_mask:"+                          " found overlapping hints\n" ))+          }+#else+          count2 = 0;+#endif++          if ( count2 == 0 )+          {+            psh_hint_activate( hint );+            if ( count < table->max_hints )+              table->sort[count++] = hint;+            else+              FT_TRACE0(( "psh_hint_tableactivate_mask:"+                          " too many active hints\n" ));+          }+        }+      }++      mask >>= 1;+    }+    table->num_hints = count;++    /* now, sort the hints; they are guaranteed to not overlap */+    /* so we can compare their "org_pos" field directly        */+    {+      FT_Int     i1, i2;+      PSH_Hint   hint1, hint2;+      PSH_Hint*  sort = table->sort;+++      /* a simple bubble sort will do, since in 99% of cases, the hints */+      /* will be already sorted -- and the sort will be linear          */+      for ( i1 = 1; i1 < (FT_Int)count; i1++ )+      {+        hint1 = sort[i1];+        for ( i2 = i1 - 1; i2 >= 0; i2-- )+        {+          hint2 = sort[i2];++          if ( hint2->org_pos < hint1->org_pos )+            break;++          sort[i2 + 1] = hint2;+          sort[i2]     = hint1;+        }+      }+    }+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****               HINTS GRID-FITTING AND OPTIMIZATION             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#if 1+  static FT_Pos+  psh_dimension_quantize_len( PSH_Dimension  dim,+                              FT_Pos         len,+                              FT_Bool        do_snapping )+  {+    if ( len <= 64 )+      len = 64;+    else+    {+      FT_Pos  delta = len - dim->stdw.widths[0].cur;+++      if ( delta < 0 )+        delta = -delta;++      if ( delta < 40 )+      {+        len = dim->stdw.widths[0].cur;+        if ( len < 48 )+          len = 48;+      }++      if ( len < 3 * 64 )+      {+        delta = ( len & 63 );+        len  &= -64;++        if ( delta < 10 )+          len += delta;++        else if ( delta < 32 )+          len += 10;++        else if ( delta < 54 )+          len += 54;++        else+          len += delta;+      }+      else+        len = FT_PIX_ROUND( len );+    }++    if ( do_snapping )+      len = FT_PIX_ROUND( len );++    return  len;+  }+#endif /* 0 */+++#ifdef DEBUG_HINTER++  static void+  ps_simple_scale( PSH_Hint_Table  table,+                   FT_Fixed        scale,+                   FT_Fixed        delta,+                   FT_Int          dimension )+  {+    PSH_Hint  hint;+    FT_UInt   count;+++    for ( count = 0; count < table->max_hints; count++ )+    {+      hint = table->hints + count;++      hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;+      hint->cur_len = FT_MulFix( hint->org_len, scale );++      if ( ps_debug_hint_func )+        ps_debug_hint_func( hint, dimension );+    }+  }++#endif /* DEBUG_HINTER */+++  static FT_Fixed+  psh_hint_snap_stem_side_delta( FT_Fixed  pos,+                                 FT_Fixed  len )+  {+    FT_Fixed  delta1 = FT_PIX_ROUND( pos ) - pos;+    FT_Fixed  delta2 = FT_PIX_ROUND( pos + len ) - pos - len;+++    if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) )+      return delta1;+    else+      return delta2;+  }+++  static void+  psh_hint_align( PSH_Hint     hint,+                  PSH_Globals  globals,+                  FT_Int       dimension,+                  PSH_Glyph    glyph )+  {+    PSH_Dimension  dim   = &globals->dimension[dimension];+    FT_Fixed       scale = dim->scale_mult;+    FT_Fixed       delta = dim->scale_delta;+++    if ( !psh_hint_is_fitted( hint ) )+    {+      FT_Pos  pos = FT_MulFix( hint->org_pos, scale ) + delta;+      FT_Pos  len = FT_MulFix( hint->org_len, scale );++      FT_Int            do_snapping;+      FT_Pos            fit_len;+      PSH_AlignmentRec  align;+++      /* ignore stem alignments when requested through the hint flags */+      if ( ( dimension == 0 && !glyph->do_horz_hints ) ||+           ( dimension == 1 && !glyph->do_vert_hints ) )+      {+        hint->cur_pos = pos;+        hint->cur_len = len;++        psh_hint_set_fitted( hint );+        return;+      }++      /* perform stem snapping when requested - this is necessary+       * for monochrome and LCD hinting modes only+       */+      do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) ||+                    ( dimension == 1 && glyph->do_vert_snapping );++      hint->cur_len = fit_len = len;++      /* check blue zones for horizontal stems */+      align.align     = PSH_BLUE_ALIGN_NONE;+      align.align_bot = align.align_top = 0;++      if ( dimension == 1 )+        psh_blues_snap_stem( &globals->blues,+                             hint->org_pos + hint->org_len,+                             hint->org_pos,+                             &align );++      switch ( align.align )+      {+      case PSH_BLUE_ALIGN_TOP:+        /* the top of the stem is aligned against a blue zone */+        hint->cur_pos = align.align_top - fit_len;+        break;++      case PSH_BLUE_ALIGN_BOT:+        /* the bottom of the stem is aligned against a blue zone */+        hint->cur_pos = align.align_bot;+        break;++      case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:+        /* both edges of the stem are aligned against blue zones */+        hint->cur_pos = align.align_bot;+        hint->cur_len = align.align_top - align.align_bot;+        break;++      default:+        {+          PSH_Hint  parent = hint->parent;+++          if ( parent )+          {+            FT_Pos  par_org_center, par_cur_center;+            FT_Pos  cur_org_center, cur_delta;+++            /* ensure that parent is already fitted */+            if ( !psh_hint_is_fitted( parent ) )+              psh_hint_align( parent, globals, dimension, glyph );++            /* keep original relation between hints, this is, use the */+            /* scaled distance between the centers of the hints to    */+            /* compute the new position                               */+            par_org_center = parent->org_pos + ( parent->org_len >> 1 );+            par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );+            cur_org_center = hint->org_pos   + ( hint->org_len   >> 1 );++            cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );+            pos       = par_cur_center + cur_delta - ( len >> 1 );+          }++          hint->cur_pos = pos;+          hint->cur_len = fit_len;++          /* Stem adjustment tries to snap stem widths to standard+           * ones.  This is important to prevent unpleasant rounding+           * artefacts.+           */+          if ( glyph->do_stem_adjust )+          {+            if ( len <= 64 )+            {+              /* the stem is less than one pixel; we will center it+               * around the nearest pixel center+               */+              if ( len >= 32 )+              {+                /* This is a special case where we also widen the stem+                 * and align it to the pixel grid.+                 *+                 *   stem_center          = pos + (len/2)+                 *   nearest_pixel_center = FT_ROUND(stem_center-32)+32+                 *   new_pos              = nearest_pixel_center-32+                 *                        = FT_ROUND(stem_center-32)+                 *                        = FT_FLOOR(stem_center-32+32)+                 *                        = FT_FLOOR(stem_center)+                 *   new_len              = 64+                 */+                pos = FT_PIX_FLOOR( pos + ( len >> 1 ) );+                len = 64;+              }+              else if ( len > 0 )+              {+                /* This is a very small stem; we simply align it to the+                 * pixel grid, trying to find the minimal displacement.+                 *+                 * left               = pos+                 * right              = pos + len+                 * left_nearest_edge  = ROUND(pos)+                 * right_nearest_edge = ROUND(right)+                 *+                 * if ( ABS(left_nearest_edge - left) <=+                 *      ABS(right_nearest_edge - right) )+                 *    new_pos = left+                 * else+                 *    new_pos = right+                 */+                FT_Pos  left_nearest  = FT_PIX_ROUND( pos );+                FT_Pos  right_nearest = FT_PIX_ROUND( pos + len );+                FT_Pos  left_disp     = left_nearest - pos;+                FT_Pos  right_disp    = right_nearest - ( pos + len );+++                if ( left_disp < 0 )+                  left_disp = -left_disp;+                if ( right_disp < 0 )+                  right_disp = -right_disp;+                if ( left_disp <= right_disp )+                  pos = left_nearest;+                else+                  pos = right_nearest;+              }+              else+              {+                /* this is a ghost stem; we simply round it */+                pos = FT_PIX_ROUND( pos );+              }+            }+            else+            {+              len = psh_dimension_quantize_len( dim, len, 0 );+            }+          }++          /* now that we have a good hinted stem width, try to position */+          /* the stem along a pixel grid integer coordinate             */+          hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len );+          hint->cur_len = len;+        }+      }++      if ( do_snapping )+      {+        pos = hint->cur_pos;+        len = hint->cur_len;++        if ( len < 64 )+          len = 64;+        else+          len = FT_PIX_ROUND( len );++        switch ( align.align )+        {+          case PSH_BLUE_ALIGN_TOP:+            hint->cur_pos = align.align_top - len;+            hint->cur_len = len;+            break;++          case PSH_BLUE_ALIGN_BOT:+            hint->cur_len = len;+            break;++          case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP:+            /* don't touch */+            break;+++          default:+            hint->cur_len = len;+            if ( len & 64 )+              pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32;+            else+              pos = FT_PIX_ROUND( pos + ( len >> 1 ) );++            hint->cur_pos = pos - ( len >> 1 );+            hint->cur_len = len;+        }+      }++      psh_hint_set_fitted( hint );++#ifdef DEBUG_HINTER+      if ( ps_debug_hint_func )+        ps_debug_hint_func( hint, dimension );+#endif+    }+  }+++#if 0  /* not used for now, experimental */++ /*+  *  A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT)+  *  of stems+  */+  static void+  psh_hint_align_light( PSH_Hint     hint,+                        PSH_Globals  globals,+                        FT_Int       dimension,+                        PSH_Glyph    glyph )+  {+    PSH_Dimension  dim   = &globals->dimension[dimension];+    FT_Fixed       scale = dim->scale_mult;+    FT_Fixed       delta = dim->scale_delta;+++    if ( !psh_hint_is_fitted( hint ) )+    {+      FT_Pos  pos = FT_MulFix( hint->org_pos, scale ) + delta;+      FT_Pos  len = FT_MulFix( hint->org_len, scale );++      FT_Pos  fit_len;++      PSH_AlignmentRec  align;+++      /* ignore stem alignments when requested through the hint flags */+      if ( ( dimension == 0 && !glyph->do_horz_hints ) ||+           ( dimension == 1 && !glyph->do_vert_hints ) )+      {+        hint->cur_pos = pos;+        hint->cur_len = len;++        psh_hint_set_fitted( hint );+        return;+      }++      fit_len = len;++      hint->cur_len = fit_len;++      /* check blue zones for horizontal stems */+      align.align = PSH_BLUE_ALIGN_NONE;+      align.align_bot = align.align_top = 0;++      if ( dimension == 1 )+        psh_blues_snap_stem( &globals->blues,+                             hint->org_pos + hint->org_len,+                             hint->org_pos,+                             &align );++      switch ( align.align )+      {+      case PSH_BLUE_ALIGN_TOP:+        /* the top of the stem is aligned against a blue zone */+        hint->cur_pos = align.align_top - fit_len;+        break;++      case PSH_BLUE_ALIGN_BOT:+        /* the bottom of the stem is aligned against a blue zone */+        hint->cur_pos = align.align_bot;+        break;++      case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:+        /* both edges of the stem are aligned against blue zones */+        hint->cur_pos = align.align_bot;+        hint->cur_len = align.align_top - align.align_bot;+        break;++      default:+        {+          PSH_Hint  parent = hint->parent;+++          if ( parent )+          {+            FT_Pos  par_org_center, par_cur_center;+            FT_Pos  cur_org_center, cur_delta;+++            /* ensure that parent is already fitted */+            if ( !psh_hint_is_fitted( parent ) )+              psh_hint_align_light( parent, globals, dimension, glyph );++            par_org_center = parent->org_pos + ( parent->org_len / 2 );+            par_cur_center = parent->cur_pos + ( parent->cur_len / 2 );+            cur_org_center = hint->org_pos   + ( hint->org_len   / 2 );++            cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );+            pos       = par_cur_center + cur_delta - ( len >> 1 );+          }++          /* Stems less than one pixel wide are easy -- we want to+           * make them as dark as possible, so they must fall within+           * one pixel.  If the stem is split between two pixels+           * then snap the edge that is nearer to the pixel boundary+           * to the pixel boundary.+           */+          if ( len <= 64 )+          {+            if ( ( pos + len + 63 ) / 64  != pos / 64 + 1 )+              pos += psh_hint_snap_stem_side_delta ( pos, len );+          }++          /* Position stems other to minimize the amount of mid-grays.+           * There are, in general, two positions that do this,+           * illustrated as A) and B) below.+           *+           *   +                   +                   +                   ++           *+           * A)             |--------------------------------|+           * B)   |--------------------------------|+           * C)       |--------------------------------|+           *+           * Position A) (split the excess stem equally) should be better+           * for stems of width N + f where f < 0.5.+           *+           * Position B) (split the deficiency equally) should be better+           * for stems of width N + f where f > 0.5.+           *+           * It turns out though that minimizing the total number of lit+           * pixels is also important, so position C), with one edge+           * aligned with a pixel boundary is actually preferable+           * to A).  There are also more possibile positions for C) than+           * for A) or B), so it involves less distortion of the overall+           * character shape.+           */+          else /* len > 64 */+          {+            FT_Fixed  frac_len = len & 63;+            FT_Fixed  center = pos + ( len >> 1 );+            FT_Fixed  delta_a, delta_b;+++            if ( ( len / 64 ) & 1 )+            {+              delta_a = FT_PIX_FLOOR( center ) + 32 - center;+              delta_b = FT_PIX_ROUND( center ) - center;+            }+            else+            {+              delta_a = FT_PIX_ROUND( center ) - center;+              delta_b = FT_PIX_FLOOR( center ) + 32 - center;+            }++            /* We choose between B) and C) above based on the amount+             * of fractinal stem width; for small amounts, choose+             * C) always, for large amounts, B) always, and inbetween,+             * pick whichever one involves less stem movement.+             */+            if ( frac_len < 32 )+            {+              pos += psh_hint_snap_stem_side_delta ( pos, len );+            }+            else if ( frac_len < 48 )+            {+              FT_Fixed  side_delta = psh_hint_snap_stem_side_delta ( pos,+                                                                     len );++              if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) )+                pos += side_delta;+              else+                pos += delta_b;+            }+            else+            {+              pos += delta_b;+            }+          }++          hint->cur_pos = pos;+        }+      }  /* switch */++      psh_hint_set_fitted( hint );++#ifdef DEBUG_HINTER+      if ( ps_debug_hint_func )+        ps_debug_hint_func( hint, dimension );+#endif+    }+  }++#endif /* 0 */+++  static void+  psh_hint_table_align_hints( PSH_Hint_Table  table,+                              PSH_Globals     globals,+                              FT_Int          dimension,+                              PSH_Glyph       glyph )+  {+    PSH_Hint       hint;+    FT_UInt        count;++#ifdef DEBUG_HINTER++    PSH_Dimension  dim   = &globals->dimension[dimension];+    FT_Fixed       scale = dim->scale_mult;+    FT_Fixed       delta = dim->scale_delta;+++    if ( ps_debug_no_vert_hints && dimension == 0 )+    {+      ps_simple_scale( table, scale, delta, dimension );+      return;+    }++    if ( ps_debug_no_horz_hints && dimension == 1 )+    {+      ps_simple_scale( table, scale, delta, dimension );+      return;+    }++#endif /* DEBUG_HINTER*/++    hint  = table->hints;+    count = table->max_hints;++    for ( ; count > 0; count--, hint++ )+      psh_hint_align( hint, globals, dimension, glyph );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                POINTS INTERPOLATION ROUTINES                  *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#define PSH_ZONE_MIN  -3200000L+#define PSH_ZONE_MAX  +3200000L++#define xxDEBUG_ZONES+++#ifdef DEBUG_ZONES++#include FT_CONFIG_STANDARD_LIBRARY_H++  static void+  psh_print_zone( PSH_Zone  zone )+  {+    printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",+             zone->scale / 65536.0,+             zone->delta / 64.0,+             zone->min,+             zone->max );+  }++#else++#define psh_print_zone( x )  do { } while ( 0 )++#endif /* DEBUG_ZONES */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    HINTER GLYPH MANAGEMENT                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++#if 1++#define  psh_corner_is_flat      ft_corner_is_flat+#define  psh_corner_orientation  ft_corner_orientation++#else++  FT_LOCAL_DEF( FT_Int )+  psh_corner_is_flat( FT_Pos  x_in,+                      FT_Pos  y_in,+                      FT_Pos  x_out,+                      FT_Pos  y_out )+  {+    FT_Pos  ax = x_in;+    FT_Pos  ay = y_in;++    FT_Pos  d_in, d_out, d_corner;+++    if ( ax < 0 )+      ax = -ax;+    if ( ay < 0 )+      ay = -ay;+    d_in = ax + ay;++    ax = x_out;+    if ( ax < 0 )+      ax = -ax;+    ay = y_out;+    if ( ay < 0 )+      ay = -ay;+    d_out = ax + ay;++    ax = x_out + x_in;+    if ( ax < 0 )+      ax = -ax;+    ay = y_out + y_in;+    if ( ay < 0 )+      ay = -ay;+    d_corner = ax + ay;++    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );+  }++  static FT_Int+  psh_corner_orientation( FT_Pos  in_x,+                          FT_Pos  in_y,+                          FT_Pos  out_x,+                          FT_Pos  out_y )+  {+    FT_Int  result;+++    /* deal with the trivial cases quickly */+    if ( in_y == 0 )+    {+      if ( in_x >= 0 )+        result = out_y;+      else+        result = -out_y;+    }+    else if ( in_x == 0 )+    {+      if ( in_y >= 0 )+        result = -out_x;+      else+        result = out_x;+    }+    else if ( out_y == 0 )+    {+      if ( out_x >= 0 )+        result = in_y;+      else+        result = -in_y;+    }+    else if ( out_x == 0 )+    {+      if ( out_y >= 0 )+        result = -in_x;+      else+        result =  in_x;+    }+    else /* general case */+    {+      long long  delta = (long long)in_x * out_y - (long long)in_y * out_x;++      if ( delta == 0 )+        result = 0;+      else+        result = 1 - 2 * ( delta < 0 );+    }++    return result;+  }++#endif /* !1 */+++#ifdef COMPUTE_INFLEXS++  /* compute all inflex points in a given glyph */+  static void+  psh_glyph_compute_inflections( PSH_Glyph  glyph )+  {+    FT_UInt  n;+++    for ( n = 0; n < glyph->num_contours; n++ )+    {+      PSH_Point  first, start, end, before, after;+      FT_Pos     in_x, in_y, out_x, out_y;+      FT_Int     orient_prev, orient_cur;+      FT_Int     finished = 0;+++      /* we need at least 4 points to create an inflection point */+      if ( glyph->contours[n].count < 4 )+        continue;++      /* compute first segment in contour */+      first = glyph->contours[n].start;++      start = end = first;+      do+      {+        end = end->next;+        if ( end == first )+          goto Skip;++        in_x = end->org_u - start->org_u;+        in_y = end->org_v - start->org_v;++      } while ( in_x == 0 && in_y == 0 );++      /* extend the segment start whenever possible */+      before = start;+      do+      {+        do+        {+          start  = before;+          before = before->prev;+          if ( before == first )+            goto Skip;++          out_x = start->org_u - before->org_u;+          out_y = start->org_v - before->org_v;++        } while ( out_x == 0 && out_y == 0 );++        orient_prev = psh_corner_orientation( in_x, in_y, out_x, out_y );++      } while ( orient_prev == 0 );++      first = start;+      in_x  = out_x;+      in_y  = out_y;++      /* now, process all segments in the contour */+      do+      {+        /* first, extend current segment's end whenever possible */+        after = end;+        do+        {+          do+          {+            end   = after;+            after = after->next;+            if ( after == first )+              finished = 1;++            out_x = after->org_u - end->org_u;+            out_y = after->org_v - end->org_v;++          } while ( out_x == 0 && out_y == 0 );++          orient_cur = psh_corner_orientation( in_x, in_y, out_x, out_y );++        } while ( orient_cur == 0 );++        if ( ( orient_cur ^ orient_prev ) < 0 )+        {+          do+          {+            psh_point_set_inflex( start );+            start = start->next;+          }+          while ( start != end );++          psh_point_set_inflex( start );+        }++        start       = end;+        end         = after;+        orient_prev = orient_cur;+        in_x        = out_x;+        in_y        = out_y;++      } while ( !finished );++    Skip:+      ;+    }+  }++#endif /* COMPUTE_INFLEXS */+++  static void+  psh_glyph_done( PSH_Glyph  glyph )+  {+    FT_Memory  memory = glyph->memory;+++    psh_hint_table_done( &glyph->hint_tables[1], memory );+    psh_hint_table_done( &glyph->hint_tables[0], memory );++    FT_FREE( glyph->points );+    FT_FREE( glyph->contours );++    glyph->num_points   = 0;+    glyph->num_contours = 0;++    glyph->memory = 0;+  }+++  static int+  psh_compute_dir( FT_Pos  dx,+                   FT_Pos  dy )+  {+    FT_Pos  ax, ay;+    int     result = PSH_DIR_NONE;+++    ax = ( dx >= 0 ) ? dx : -dx;+    ay = ( dy >= 0 ) ? dy : -dy;++    if ( ay * 12 < ax )+    {+      /* |dy| <<< |dx|  means a near-horizontal segment */+      result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT;+    }+    else if ( ax * 12 < ay )+    {+      /* |dx| <<< |dy|  means a near-vertical segment */+      result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN;+    }++    return result;+  }+++  /* load outline point coordinates into hinter glyph */+  static void+  psh_glyph_load_points( PSH_Glyph  glyph,+                         FT_Int     dimension )+  {+    FT_Vector*  vec   = glyph->outline->points;+    PSH_Point   point = glyph->points;+    FT_UInt     count = glyph->num_points;+++    for ( ; count > 0; count--, point++, vec++ )+    {+      point->flags2 = 0;+      point->hint   = NULL;+      if ( dimension == 0 )+      {+        point->org_u = vec->x;+        point->org_v = vec->y;+      }+      else+      {+        point->org_u = vec->y;+        point->org_v = vec->x;+      }++#ifdef DEBUG_HINTER+      point->org_x = vec->x;+      point->org_y = vec->y;+#endif++    }+  }+++  /* save hinted point coordinates back to outline */+  static void+  psh_glyph_save_points( PSH_Glyph  glyph,+                         FT_Int     dimension )+  {+    FT_UInt     n;+    PSH_Point   point = glyph->points;+    FT_Vector*  vec   = glyph->outline->points;+    char*       tags  = glyph->outline->tags;+++    for ( n = 0; n < glyph->num_points; n++ )+    {+      if ( dimension == 0 )+        vec[n].x = point->cur_u;+      else+        vec[n].y = point->cur_u;++      if ( psh_point_is_strong( point ) )+        tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 );++#ifdef DEBUG_HINTER++      if ( dimension == 0 )+      {+        point->cur_x   = point->cur_u;+        point->flags_x = point->flags2 | point->flags;+      }+      else+      {+        point->cur_y   = point->cur_u;+        point->flags_y = point->flags2 | point->flags;+      }++#endif++      point++;+    }+  }+++  static FT_Error+  psh_glyph_init( PSH_Glyph    glyph,+                  FT_Outline*  outline,+                  PS_Hints     ps_hints,+                  PSH_Globals  globals )+  {+    FT_Error   error;+    FT_Memory  memory;+++    /* clear all fields */+    FT_MEM_ZERO( glyph, sizeof ( *glyph ) );++    memory = glyph->memory = globals->memory;++    /* allocate and setup points + contours arrays */+    if ( FT_NEW_ARRAY( glyph->points,   outline->n_points   ) ||+         FT_NEW_ARRAY( glyph->contours, outline->n_contours ) )+      goto Exit;++    glyph->num_points   = outline->n_points;+    glyph->num_contours = outline->n_contours;++    {+      FT_UInt      first = 0, next, n;+      PSH_Point    points  = glyph->points;+      PSH_Contour  contour = glyph->contours;+++      for ( n = 0; n < glyph->num_contours; n++ )+      {+        FT_Int     count;+        PSH_Point  point;+++        next  = outline->contours[n] + 1;+        count = next - first;++        contour->start = points + first;+        contour->count = (FT_UInt)count;++        if ( count > 0 )+        {+          point = points + first;++          point->prev    = points + next - 1;+          point->contour = contour;++          for ( ; count > 1; count-- )+          {+            point[0].next = point + 1;+            point[1].prev = point;+            point++;+            point->contour = contour;+          }+          point->next = points + first;+        }++        contour++;+        first = next;+      }+    }++    {+      PSH_Point   points = glyph->points;+      PSH_Point   point  = points;+      FT_Vector*  vec    = outline->points;+      FT_UInt     n;+++      for ( n = 0; n < glyph->num_points; n++, point++ )+      {+        FT_Int  n_prev = (FT_Int)( point->prev - points );+        FT_Int  n_next = (FT_Int)( point->next - points );+        FT_Pos  dxi, dyi, dxo, dyo;+++        if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) )+          point->flags = PSH_POINT_OFF;++        dxi = vec[n].x - vec[n_prev].x;+        dyi = vec[n].y - vec[n_prev].y;++        point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi );++        dxo = vec[n_next].x - vec[n].x;+        dyo = vec[n_next].y - vec[n].y;++        point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo );++        /* detect smooth points */+        if ( point->flags & PSH_POINT_OFF )+          point->flags |= PSH_POINT_SMOOTH;++        else if ( point->dir_in == point->dir_out )+        {+          if ( point->dir_out != PSH_DIR_NONE           ||+               psh_corner_is_flat( dxi, dyi, dxo, dyo ) )+            point->flags |= PSH_POINT_SMOOTH;+        }+      }+    }++    glyph->outline = outline;+    glyph->globals = globals;++#ifdef COMPUTE_INFLEXS+    psh_glyph_load_points( glyph, 0 );+    psh_glyph_compute_inflections( glyph );+#endif /* COMPUTE_INFLEXS */++    /* now deal with hints tables */+    error = psh_hint_table_init( &glyph->hint_tables [0],+                                 &ps_hints->dimension[0].hints,+                                 &ps_hints->dimension[0].masks,+                                 &ps_hints->dimension[0].counters,+                                 memory );+    if ( error )+      goto Exit;++    error = psh_hint_table_init( &glyph->hint_tables [1],+                                 &ps_hints->dimension[1].hints,+                                 &ps_hints->dimension[1].masks,+                                 &ps_hints->dimension[1].counters,+                                 memory );+    if ( error )+      goto Exit;++  Exit:+    return error;+  }+++  /* compute all extrema in a glyph for a given dimension */+  static void+  psh_glyph_compute_extrema( PSH_Glyph  glyph )+  {+    FT_UInt  n;+++    /* first of all, compute all local extrema */+    for ( n = 0; n < glyph->num_contours; n++ )+    {+      PSH_Point  first = glyph->contours[n].start;+      PSH_Point  point, before, after;+++      if ( glyph->contours[n].count == 0 )+        continue;++      point  = first;+      before = point;+      after  = point;++      do+      {+        before = before->prev;+        if ( before == first )+          goto Skip;++      } while ( before->org_u == point->org_u );++      first = point = before->next;++      for (;;)+      {+        after = point;+        do+        {+          after = after->next;+          if ( after == first )+            goto Next;++        } while ( after->org_u == point->org_u );++        if ( before->org_u < point->org_u )+        {+          if ( after->org_u < point->org_u )+          {+            /* local maximum */+            goto Extremum;+          }+        }+        else /* before->org_u > point->org_u */+        {+          if ( after->org_u > point->org_u )+          {+            /* local minimum */+          Extremum:+            do+            {+              psh_point_set_extremum( point );+              point = point->next;++            } while ( point != after );+          }+        }++        before = after->prev;+        point  = after;++      } /* for  */++    Next:+      ;+    }++    /* for each extremum, determine its direction along the */+    /* orthogonal axis                                      */+    for ( n = 0; n < glyph->num_points; n++ )+    {+      PSH_Point  point, before, after;+++      point  = &glyph->points[n];+      before = point;+      after  = point;++      if ( psh_point_is_extremum( point ) )+      {+        do+        {+          before = before->prev;+          if ( before == point )+            goto Skip;++        } while ( before->org_v == point->org_v );++        do+        {+          after = after->next;+          if ( after == point )+            goto Skip;++        } while ( after->org_v == point->org_v );+      }++      if ( before->org_v < point->org_v &&+           after->org_v  > point->org_v )+      {+        psh_point_set_positive( point );+      }+      else if ( before->org_v > point->org_v &&+                after->org_v  < point->org_v )+      {+        psh_point_set_negative( point );+      }++    Skip:+      ;+    }+  }+++  /* major_dir is the direction for points on the bottom/left of the stem; */+  /* Points on the top/right of the stem will have a direction of          */+  /* -major_dir.                                                           */++  static void+  psh_hint_table_find_strong_points( PSH_Hint_Table  table,+                                     PSH_Point       point,+                                     FT_UInt         count,+                                     FT_Int          threshold,+                                     FT_Int          major_dir )+  {+    PSH_Hint*  sort      = table->sort;+    FT_UInt    num_hints = table->num_hints;+++    for ( ; count > 0; count--, point++ )+    {+      FT_Int  point_dir = 0;+      FT_Pos  org_u     = point->org_u;+++      if ( psh_point_is_strong( point ) )+        continue;++      if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) )+        point_dir = point->dir_in;++      else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) )+        point_dir = point->dir_out;++      if ( point_dir )+      {+        if ( point_dir == major_dir )+        {+          FT_UInt  nn;+++          for ( nn = 0; nn < num_hints; nn++ )+          {+            PSH_Hint  hint = sort[nn];+            FT_Pos    d    = org_u - hint->org_pos;+++            if ( d < threshold && -d < threshold )+            {+              psh_point_set_strong( point );+              point->flags2 |= PSH_POINT_EDGE_MIN;+              point->hint    = hint;+              break;+            }+          }+        }+        else if ( point_dir == -major_dir )+        {+          FT_UInt  nn;+++          for ( nn = 0; nn < num_hints; nn++ )+          {+            PSH_Hint  hint = sort[nn];+            FT_Pos    d    = org_u - hint->org_pos - hint->org_len;+++            if ( d < threshold && -d < threshold )+            {+              psh_point_set_strong( point );+              point->flags2 |= PSH_POINT_EDGE_MAX;+              point->hint    = hint;+              break;+            }+          }+        }+      }++#if 1+      else if ( psh_point_is_extremum( point ) )+      {+        /* treat extrema as special cases for stem edge alignment */+        FT_UInt  nn, min_flag, max_flag;+++        if ( major_dir == PSH_DIR_HORIZONTAL )+        {+          min_flag = PSH_POINT_POSITIVE;+          max_flag = PSH_POINT_NEGATIVE;+        }+        else+        {+          min_flag = PSH_POINT_NEGATIVE;+          max_flag = PSH_POINT_POSITIVE;+        }++        if ( point->flags2 & min_flag )+        {+          for ( nn = 0; nn < num_hints; nn++ )+          {+            PSH_Hint  hint = sort[nn];+            FT_Pos    d    = org_u - hint->org_pos;+++            if ( d < threshold && -d < threshold )+            {+              point->flags2 |= PSH_POINT_EDGE_MIN;+              point->hint    = hint;+              psh_point_set_strong( point );+              break;+            }+          }+        }+        else if ( point->flags2 & max_flag )+        {+          for ( nn = 0; nn < num_hints; nn++ )+          {+            PSH_Hint  hint = sort[nn];+            FT_Pos    d    = org_u - hint->org_pos - hint->org_len;+++            if ( d < threshold && -d < threshold )+            {+              point->flags2 |= PSH_POINT_EDGE_MAX;+              point->hint    = hint;+              psh_point_set_strong( point );+              break;+            }+          }+        }++        if ( point->hint == NULL )+        {+          for ( nn = 0; nn < num_hints; nn++ )+          {+            PSH_Hint  hint = sort[nn];+++            if ( org_u >= hint->org_pos                 &&+                org_u <= hint->org_pos + hint->org_len )+            {+              point->hint = hint;+              break;+            }+          }+        }+      }++#endif /* 1 */+    }+  }+++  /* the accepted shift for strong points in fractional pixels */+#define PSH_STRONG_THRESHOLD  32++  /* the maximum shift value in font units */+#define PSH_STRONG_THRESHOLD_MAXIMUM  30+++  /* find strong points in a glyph */+  static void+  psh_glyph_find_strong_points( PSH_Glyph  glyph,+                                FT_Int     dimension )+  {+    /* a point is `strong' if it is located on a stem edge and       */+    /* has an `in' or `out' tangent parallel to the hint's direction */++    PSH_Hint_Table  table     = &glyph->hint_tables[dimension];+    PS_Mask         mask      = table->hint_masks->masks;+    FT_UInt         num_masks = table->hint_masks->num_masks;+    FT_UInt         first     = 0;+    FT_Int          major_dir = dimension == 0 ? PSH_DIR_VERTICAL+                                               : PSH_DIR_HORIZONTAL;+    PSH_Dimension   dim       = &glyph->globals->dimension[dimension];+    FT_Fixed        scale     = dim->scale_mult;+    FT_Int          threshold;+++    threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale );+    if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM )+      threshold = PSH_STRONG_THRESHOLD_MAXIMUM;++    /* process secondary hints to `selected' points */+    if ( num_masks > 1 && glyph->num_points > 0 )+    {+      /* the `endchar' op can reduce the number of points */+      first = mask->end_point > glyph->num_points+                ? glyph->num_points+                : mask->end_point;+      mask++;+      for ( ; num_masks > 1; num_masks--, mask++ )+      {+        FT_UInt  next;+        FT_Int   count;+++        next  = mask->end_point > glyph->num_points+                  ? glyph->num_points+                  : mask->end_point;+        count = next - first;+        if ( count > 0 )+        {+          PSH_Point  point = glyph->points + first;+++          psh_hint_table_activate_mask( table, mask );++          psh_hint_table_find_strong_points( table, point, count,+                                             threshold, major_dir );+        }+        first = next;+      }+    }++    /* process primary hints for all points */+    if ( num_masks == 1 )+    {+      FT_UInt    count = glyph->num_points;+      PSH_Point  point = glyph->points;+++      psh_hint_table_activate_mask( table, table->hint_masks->masks );++      psh_hint_table_find_strong_points( table, point, count,+                                         threshold, major_dir );+    }++    /* now, certain points may have been attached to a hint and */+    /* not marked as strong; update their flags then            */+    {+      FT_UInt    count = glyph->num_points;+      PSH_Point  point = glyph->points;+++      for ( ; count > 0; count--, point++ )+        if ( point->hint && !psh_point_is_strong( point ) )+          psh_point_set_strong( point );+    }+  }+++  /* find points in a glyph which are in a blue zone and have `in' or */+  /* `out' tangents parallel to the horizontal axis                   */+  static void+  psh_glyph_find_blue_points( PSH_Blues  blues,+                              PSH_Glyph  glyph )+  {+    PSH_Blue_Table  table;+    PSH_Blue_Zone   zone;+    FT_UInt         glyph_count = glyph->num_points;+    FT_UInt         blue_count;+    PSH_Point       point = glyph->points;+++    for ( ; glyph_count > 0; glyph_count--, point++ )+    {+      FT_Pos  y;+++      /* check tangents */+      if ( !PSH_DIR_COMPARE( point->dir_in,  PSH_DIR_HORIZONTAL ) &&+           !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) )+        continue;++      /* skip strong points */+      if ( psh_point_is_strong( point ) )+        continue;++      y = point->org_u;++      /* look up top zones */+      table      = &blues->normal_top;+      blue_count = table->count;+      zone       = table->zones;++      for ( ; blue_count > 0; blue_count--, zone++ )+      {+        FT_Pos  delta = y - zone->org_bottom;+++        if ( delta < -blues->blue_fuzz )+          break;++        if ( y <= zone->org_top + blues->blue_fuzz )+          if ( blues->no_overshoots || delta <= blues->blue_threshold )+          {+            point->cur_u = zone->cur_bottom;+            psh_point_set_strong( point );+            psh_point_set_fitted( point );+          }+      }++      /* look up bottom zones */+      table      = &blues->normal_bottom;+      blue_count = table->count;+      zone       = table->zones + blue_count - 1;++      for ( ; blue_count > 0; blue_count--, zone-- )+      {+        FT_Pos  delta = zone->org_top - y;+++        if ( delta < -blues->blue_fuzz )+          break;++        if ( y >= zone->org_bottom - blues->blue_fuzz )+          if ( blues->no_overshoots || delta < blues->blue_threshold )+          {+            point->cur_u = zone->cur_top;+            psh_point_set_strong( point );+            psh_point_set_fitted( point );+          }+      }+    }+  }+++  /* interpolate strong points with the help of hinted coordinates */+  static void+  psh_glyph_interpolate_strong_points( PSH_Glyph  glyph,+                                       FT_Int     dimension )+  {+    PSH_Dimension  dim   = &glyph->globals->dimension[dimension];+    FT_Fixed       scale = dim->scale_mult;++    FT_UInt        count = glyph->num_points;+    PSH_Point      point = glyph->points;+++    for ( ; count > 0; count--, point++ )+    {+      PSH_Hint  hint = point->hint;+++      if ( hint )+      {+        FT_Pos  delta;+++        if ( psh_point_is_edge_min( point ) )+          point->cur_u = hint->cur_pos;++        else if ( psh_point_is_edge_max( point ) )+          point->cur_u = hint->cur_pos + hint->cur_len;++        else+        {+          delta = point->org_u - hint->org_pos;++          if ( delta <= 0 )+            point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );++          else if ( delta >= hint->org_len )+            point->cur_u = hint->cur_pos + hint->cur_len ++                             FT_MulFix( delta - hint->org_len, scale );++          else /* hint->org_len > 0 */+            point->cur_u = hint->cur_pos ++                             FT_MulDiv( delta, hint->cur_len,+                                        hint->org_len );+        }+        psh_point_set_fitted( point );+      }+    }+  }+++#define  PSH_MAX_STRONG_INTERNAL  16++  static void+  psh_glyph_interpolate_normal_points( PSH_Glyph  glyph,+                                       FT_Int     dimension )+  {++#if 1+    /* first technique: a point is strong if it is a local extremum */++    PSH_Dimension  dim    = &glyph->globals->dimension[dimension];+    FT_Fixed       scale  = dim->scale_mult;+    FT_Memory      memory = glyph->memory;++    PSH_Point*     strongs     = NULL;+    PSH_Point      strongs_0[PSH_MAX_STRONG_INTERNAL];+    FT_UInt        num_strongs = 0;++    PSH_Point      points = glyph->points;+    PSH_Point      points_end = points + glyph->num_points;+    PSH_Point      point;+++    /* first count the number of strong points */+    for ( point = points; point < points_end; point++ )+    {+      if ( psh_point_is_strong( point ) )+        num_strongs++;+    }++    if ( num_strongs == 0 )  /* nothing to do here */+      return;++    /* allocate an array to store a list of points, */+    /* stored in increasing org_u order             */+    if ( num_strongs <= PSH_MAX_STRONG_INTERNAL )+      strongs = strongs_0;+    else+    {+      FT_Error  error;+++      if ( FT_NEW_ARRAY( strongs, num_strongs ) )+        return;+    }++    num_strongs = 0;+    for ( point = points; point < points_end; point++ )+    {+      PSH_Point*  insert;+++      if ( !psh_point_is_strong( point ) )+        continue;++      for ( insert = strongs + num_strongs; insert > strongs; insert-- )+      {+        if ( insert[-1]->org_u <= point->org_u )+          break;++        insert[0] = insert[-1];+      }+      insert[0] = point;+      num_strongs++;+    }++    /* now try to interpolate all normal points */+    for ( point = points; point < points_end; point++ )+    {+      if ( psh_point_is_strong( point ) )+        continue;++      /* sometimes, some local extrema are smooth points */+      if ( psh_point_is_smooth( point ) )+      {+        if ( point->dir_in == PSH_DIR_NONE   ||+             point->dir_in != point->dir_out )+          continue;++        if ( !psh_point_is_extremum( point ) &&+             !psh_point_is_inflex( point )   )+          continue;++        point->flags &= ~PSH_POINT_SMOOTH;+      }++      /* find best enclosing point coordinates then interpolate */+      {+        PSH_Point   before, after;+        FT_UInt     nn;+++        for ( nn = 0; nn < num_strongs; nn++ )+          if ( strongs[nn]->org_u > point->org_u )+            break;++        if ( nn == 0 )  /* point before the first strong point */+        {+          after = strongs[0];++          point->cur_u = after->cur_u ++                           FT_MulFix( point->org_u - after->org_u,+                                      scale );+        }+        else+        {+          before = strongs[nn - 1];++          for ( nn = num_strongs; nn > 0; nn-- )+            if ( strongs[nn - 1]->org_u < point->org_u )+              break;++          if ( nn == num_strongs )  /* point is after last strong point */+          {+            before = strongs[nn - 1];++            point->cur_u = before->cur_u ++                             FT_MulFix( point->org_u - before->org_u,+                                        scale );+          }+          else+          {+            FT_Pos  u;+++            after = strongs[nn];++            /* now interpolate point between before and after */+            u = point->org_u;++            if ( u == before->org_u )+              point->cur_u = before->cur_u;++            else if ( u == after->org_u )+              point->cur_u = after->cur_u;++            else+              point->cur_u = before->cur_u ++                               FT_MulDiv( u - before->org_u,+                                          after->cur_u - before->cur_u,+                                          after->org_u - before->org_u );+          }+        }+        psh_point_set_fitted( point );+      }+    }++    if ( strongs != strongs_0 )+      FT_FREE( strongs );++#endif /* 1 */++  }+++  /* interpolate other points */+  static void+  psh_glyph_interpolate_other_points( PSH_Glyph  glyph,+                                      FT_Int     dimension )+  {+    PSH_Dimension  dim          = &glyph->globals->dimension[dimension];+    FT_Fixed       scale        = dim->scale_mult;+    FT_Fixed       delta        = dim->scale_delta;+    PSH_Contour    contour      = glyph->contours;+    FT_UInt        num_contours = glyph->num_contours;+++    for ( ; num_contours > 0; num_contours--, contour++ )+    {+      PSH_Point  start = contour->start;+      PSH_Point  first, next, point;+      FT_UInt    fit_count;+++      /* count the number of strong points in this contour */+      next      = start + contour->count;+      fit_count = 0;+      first     = 0;++      for ( point = start; point < next; point++ )+        if ( psh_point_is_fitted( point ) )+        {+          if ( !first )+            first = point;++          fit_count++;+        }++      /* if there are less than 2 fitted points in the contour, we */+      /* simply scale and eventually translate the contour points  */+      if ( fit_count < 2 )+      {+        if ( fit_count == 1 )+          delta = first->cur_u - FT_MulFix( first->org_u, scale );++        for ( point = start; point < next; point++ )+          if ( point != first )+            point->cur_u = FT_MulFix( point->org_u, scale ) + delta;++        goto Next_Contour;+      }++      /* there are more than 2 strong points in this contour; we */+      /* need to interpolate weak points between them            */+      start = first;+      do+      {+        point = first;++        /* skip consecutive fitted points */+        for (;;)+        {+          next = first->next;+          if ( next == start )+            goto Next_Contour;++          if ( !psh_point_is_fitted( next ) )+            break;++          first = next;+        }++        /* find next fitted point after unfitted one */+        for (;;)+        {+          next = next->next;+          if ( psh_point_is_fitted( next ) )+            break;+        }++        /* now interpolate between them */+        {+          FT_Pos    org_a, org_ab, cur_a, cur_ab;+          FT_Pos    org_c, org_ac, cur_c;+          FT_Fixed  scale_ab;+++          if ( first->org_u <= next->org_u )+          {+            org_a  = first->org_u;+            cur_a  = first->cur_u;+            org_ab = next->org_u - org_a;+            cur_ab = next->cur_u - cur_a;+          }+          else+          {+            org_a  = next->org_u;+            cur_a  = next->cur_u;+            org_ab = first->org_u - org_a;+            cur_ab = first->cur_u - cur_a;+          }++          scale_ab = 0x10000L;+          if ( org_ab > 0 )+            scale_ab = FT_DivFix( cur_ab, org_ab );++          point = first->next;+          do+          {+            org_c  = point->org_u;+            org_ac = org_c - org_a;++            if ( org_ac <= 0 )+            {+              /* on the left of the interpolation zone */+              cur_c = cur_a + FT_MulFix( org_ac, scale );+            }+            else if ( org_ac >= org_ab )+            {+              /* on the right on the interpolation zone */+              cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale );+            }+            else+            {+              /* within the interpolation zone */+              cur_c = cur_a + FT_MulFix( org_ac, scale_ab );+            }++            point->cur_u = cur_c;++            point = point->next;++          } while ( point != next );+        }++        /* keep going until all points in the contours have been processed */+        first = next;++      } while ( first != start );++    Next_Contour:+      ;+    }+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     HIGH-LEVEL INTERFACE                      *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  FT_Error+  ps_hints_apply( PS_Hints        ps_hints,+                  FT_Outline*     outline,+                  PSH_Globals     globals,+                  FT_Render_Mode  hint_mode )+  {+    PSH_GlyphRec  glyphrec;+    PSH_Glyph     glyph = &glyphrec;+    FT_Error      error;+#ifdef DEBUG_HINTER+    FT_Memory     memory;+#endif+    FT_Int        dimension;+++    /* something to do? */+    if ( outline->n_points == 0 || outline->n_contours == 0 )+      return PSH_Err_Ok;++#ifdef DEBUG_HINTER++    memory = globals->memory;++    if ( ps_debug_glyph )+    {+      psh_glyph_done( ps_debug_glyph );+      FT_FREE( ps_debug_glyph );+    }++    if ( FT_NEW( glyph ) )+      return error;++    ps_debug_glyph = glyph;++#endif /* DEBUG_HINTER */++    error = psh_glyph_init( glyph, outline, ps_hints, globals );+    if ( error )+      goto Exit;++    /* try to optimize the y_scale so that the top of non-capital letters+     * is aligned on a pixel boundary whenever possible+     */+    {+      PSH_Dimension  dim_x = &glyph->globals->dimension[0];+      PSH_Dimension  dim_y = &glyph->globals->dimension[1];++      FT_Fixed  x_scale = dim_x->scale_mult;+      FT_Fixed  y_scale = dim_y->scale_mult;++      FT_Fixed  old_x_scale = x_scale;+      FT_Fixed  old_y_scale = y_scale;++      FT_Fixed  scaled;+      FT_Fixed  fitted;++      FT_Bool  rescale = FALSE;+++      scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );+      fitted = FT_PIX_ROUND( scaled );++      if ( fitted != 0 && scaled != fitted )+      {+        rescale = TRUE;++        y_scale = FT_MulDiv( y_scale, fitted, scaled );++        if ( fitted < scaled )+          x_scale -= x_scale / 50;++        psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 );+      }++      glyph->do_horz_hints = 1;+      glyph->do_vert_hints = 1;++      glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||+                                         hint_mode == FT_RENDER_MODE_LCD  );++      glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO  ||+                                         hint_mode == FT_RENDER_MODE_LCD_V );++      glyph->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );++      for ( dimension = 0; dimension < 2; dimension++ )+      {+        /* load outline coordinates into glyph */+        psh_glyph_load_points( glyph, dimension );++        /* compute local extrema */+        psh_glyph_compute_extrema( glyph );++        /* compute aligned stem/hints positions */+        psh_hint_table_align_hints( &glyph->hint_tables[dimension],+                                    glyph->globals,+                                    dimension,+                                    glyph );++        /* find strong points, align them, then interpolate others */+        psh_glyph_find_strong_points( glyph, dimension );+        if ( dimension == 1 )+          psh_glyph_find_blue_points( &globals->blues, glyph );+        psh_glyph_interpolate_strong_points( glyph, dimension );+        psh_glyph_interpolate_normal_points( glyph, dimension );+        psh_glyph_interpolate_other_points( glyph, dimension );++        /* save hinted coordinates back to outline */+        psh_glyph_save_points( glyph, dimension );++        if ( rescale )+          psh_globals_set_scale( glyph->globals,+                                 old_x_scale, old_y_scale, 0, 0 );+      }+    }++  Exit:++#ifndef DEBUG_HINTER+    psh_glyph_done( glyph );+#endif++    return error;+  }+++/* END */
+ src/pshinter/pshalgo.h view
@@ -0,0 +1,255 @@+/***************************************************************************/+/*                                                                         */+/*  pshalgo.h                                                              */+/*                                                                         */+/*    PostScript hinting algorithm (specification).                        */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2008 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSHALGO_H__+#define __PSHALGO_H__+++#include "pshrec.h"+#include "pshglob.h"+#include FT_TRIGONOMETRY_H+++FT_BEGIN_HEADER+++  /* handle to Hint structure */+  typedef struct PSH_HintRec_*  PSH_Hint;++  /* hint bit-flags */+  typedef enum  PSH_Hint_Flags_+  {+    PSH_HINT_GHOST  = PS_HINT_FLAG_GHOST,+    PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM,+    PSH_HINT_ACTIVE = 4,+    PSH_HINT_FITTED = 8++  } PSH_Hint_Flags;+++#define psh_hint_is_active( x )  ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 )+#define psh_hint_is_ghost( x )   ( ( (x)->flags & PSH_HINT_GHOST  ) != 0 )+#define psh_hint_is_fitted( x )  ( ( (x)->flags & PSH_HINT_FITTED ) != 0 )++#define psh_hint_activate( x )    (x)->flags |=  PSH_HINT_ACTIVE+#define psh_hint_deactivate( x )  (x)->flags &= ~PSH_HINT_ACTIVE+#define psh_hint_set_fitted( x )  (x)->flags |=  PSH_HINT_FITTED++  /* hint structure */+  typedef struct  PSH_HintRec_+  {+    FT_Int    org_pos;+    FT_Int    org_len;+    FT_Pos    cur_pos;+    FT_Pos    cur_len;+    FT_UInt   flags;+    PSH_Hint  parent;+    FT_Int    order;++  } PSH_HintRec;+++  /* this is an interpolation zone used for strong points;  */+  /* weak points are interpolated according to their strong */+  /* neighbours                                             */+  typedef struct  PSH_ZoneRec_+  {+    FT_Fixed  scale;+    FT_Fixed  delta;+    FT_Pos    min;+    FT_Pos    max;++  } PSH_ZoneRec, *PSH_Zone;+++  typedef struct  PSH_Hint_TableRec_+  {+    FT_UInt        max_hints;+    FT_UInt        num_hints;+    PSH_Hint       hints;+    PSH_Hint*      sort;+    PSH_Hint*      sort_global;+    FT_UInt        num_zones;+    PSH_ZoneRec*   zones;+    PSH_Zone       zone;+    PS_Mask_Table  hint_masks;+    PS_Mask_Table  counter_masks;++  } PSH_Hint_TableRec, *PSH_Hint_Table;+++  typedef struct PSH_PointRec_*    PSH_Point;+  typedef struct PSH_ContourRec_*  PSH_Contour;++  enum+  {+    PSH_DIR_NONE  =  4,+    PSH_DIR_UP    = -1,+    PSH_DIR_DOWN  =  1,+    PSH_DIR_LEFT  = -2,+    PSH_DIR_RIGHT =  2+  };++#define PSH_DIR_HORIZONTAL  2+#define PSH_DIR_VERTICAL    1++#define PSH_DIR_COMPARE( d1, d2 )   ( (d1) == (d2) || (d1) == -(d2) )+#define PSH_DIR_IS_HORIZONTAL( d )  PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL )+#define PSH_DIR_IS_VERTICAL( d )    PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL )+++ /* the following bit-flags are computed once by the glyph */+ /* analyzer, for both dimensions                          */+  enum+  {+    PSH_POINT_OFF    = 1,   /* point is off the curve */+    PSH_POINT_SMOOTH = 2,   /* point is smooth        */+    PSH_POINT_INFLEX = 4    /* point is inflection    */+  };++#define psh_point_is_smooth( p )  ( (p)->flags & PSH_POINT_SMOOTH )+#define psh_point_is_off( p )     ( (p)->flags & PSH_POINT_OFF    )+#define psh_point_is_inflex( p )  ( (p)->flags & PSH_POINT_INFLEX )++#define psh_point_set_smooth( p )  (p)->flags |= PSH_POINT_SMOOTH+#define psh_point_set_off( p )     (p)->flags |= PSH_POINT_OFF+#define psh_point_set_inflex( p )  (p)->flags |= PSH_POINT_INFLEX++  /* the following bit-flags are re-computed for each dimension */+  enum+  {+    PSH_POINT_STRONG   = 16,   /* point is strong                           */+    PSH_POINT_FITTED   = 32,   /* point is already fitted                   */+    PSH_POINT_EXTREMUM = 64,   /* point is local extremum                   */+    PSH_POINT_POSITIVE = 128,  /* extremum has positive contour flow        */+    PSH_POINT_NEGATIVE = 256,  /* extremum has negative contour flow        */+    PSH_POINT_EDGE_MIN = 512,  /* point is aligned to left/bottom stem edge */+    PSH_POINT_EDGE_MAX = 1024  /* point is aligned to top/right stem edge   */+  };++#define psh_point_is_strong( p )    ( (p)->flags2 & PSH_POINT_STRONG )+#define psh_point_is_fitted( p )    ( (p)->flags2 & PSH_POINT_FITTED )+#define psh_point_is_extremum( p )  ( (p)->flags2 & PSH_POINT_EXTREMUM )+#define psh_point_is_positive( p )  ( (p)->flags2 & PSH_POINT_POSITIVE )+#define psh_point_is_negative( p )  ( (p)->flags2 & PSH_POINT_NEGATIVE )+#define psh_point_is_edge_min( p )  ( (p)->flags2 & PSH_POINT_EDGE_MIN )+#define psh_point_is_edge_max( p )  ( (p)->flags2 & PSH_POINT_EDGE_MAX )++#define psh_point_set_strong( p )    (p)->flags2 |= PSH_POINT_STRONG+#define psh_point_set_fitted( p )    (p)->flags2 |= PSH_POINT_FITTED+#define psh_point_set_extremum( p )  (p)->flags2 |= PSH_POINT_EXTREMUM+#define psh_point_set_positive( p )  (p)->flags2 |= PSH_POINT_POSITIVE+#define psh_point_set_negative( p )  (p)->flags2 |= PSH_POINT_NEGATIVE+#define psh_point_set_edge_min( p )  (p)->flags2 |= PSH_POINT_EDGE_MIN+#define psh_point_set_edge_max( p )  (p)->flags2 |= PSH_POINT_EDGE_MAX+++  typedef struct  PSH_PointRec_+  {+    PSH_Point    prev;+    PSH_Point    next;+    PSH_Contour  contour;+    FT_UInt      flags;+    FT_UInt      flags2;+    FT_Char      dir_in;+    FT_Char      dir_out;+    FT_Angle     angle_in;+    FT_Angle     angle_out;+    PSH_Hint     hint;+    FT_Pos       org_u;+    FT_Pos       org_v;+    FT_Pos       cur_u;+#ifdef DEBUG_HINTER+    FT_Pos       org_x;+    FT_Pos       cur_x;+    FT_Pos       org_y;+    FT_Pos       cur_y;+    FT_UInt      flags_x;+    FT_UInt      flags_y;+#endif++  } PSH_PointRec;+++#define PSH_POINT_EQUAL_ORG( a, b )  ( (a)->org_u == (b)->org_u && \+                                       (a)->org_v == (b)->org_v )++#define PSH_POINT_ANGLE( a, b )  FT_Atan2( (b)->org_u - (a)->org_u,  \+                                           (b)->org_v - (a)->org_v )++  typedef struct  PSH_ContourRec_+  {+    PSH_Point  start;+    FT_UInt    count;++  } PSH_ContourRec;+++  typedef struct  PSH_GlyphRec_+  {+    FT_UInt            num_points;+    FT_UInt            num_contours;++    PSH_Point          points;+    PSH_Contour        contours;++    FT_Memory          memory;+    FT_Outline*        outline;+    PSH_Globals        globals;+    PSH_Hint_TableRec  hint_tables[2];++    FT_Bool            vertical;+    FT_Int             major_dir;+    FT_Int             minor_dir;++    FT_Bool            do_horz_hints;+    FT_Bool            do_vert_hints;+    FT_Bool            do_horz_snapping;+    FT_Bool            do_vert_snapping;+    FT_Bool            do_stem_adjust;++  } PSH_GlyphRec, *PSH_Glyph;+++#ifdef DEBUG_HINTER+  extern PSH_Hint_Table  ps_debug_hint_table;++  typedef void+  (*PSH_HintFunc)( PSH_Hint  hint,+                   FT_Bool   vertical );++  extern PSH_HintFunc    ps_debug_hint_func;++  extern PSH_Glyph       ps_debug_glyph;+#endif+++  extern FT_Error+  ps_hints_apply( PS_Hints        ps_hints,+                  FT_Outline*     outline,+                  PSH_Globals     globals,+                  FT_Render_Mode  hint_mode );+++FT_END_HEADER+++#endif /* __PSHALGO_H__ */+++/* END */
+ src/pshinter/pshglob.c view
@@ -0,0 +1,750 @@+/***************************************************************************/+/*                                                                         */+/*  pshglob.c                                                              */+/*                                                                         */+/*    PostScript hinter global hinting management (body).                  */+/*    Inspired by the new auto-hinter module.                              */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2006, 2010 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used        */+/*  modified and distributed under the terms of the FreeType project       */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "pshglob.h"++#ifdef DEBUG_HINTER+  PSH_Globals  ps_debug_globals = 0;+#endif+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       STANDARD WIDTHS                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* scale the widths/heights table */+  static void+  psh_globals_scale_widths( PSH_Globals  globals,+                            FT_UInt      direction )+  {+    PSH_Dimension  dim   = &globals->dimension[direction];+    PSH_Widths     stdw  = &dim->stdw;+    FT_UInt        count = stdw->count;+    PSH_Width      width = stdw->widths;+    PSH_Width      stand = width;               /* standard width/height */+    FT_Fixed       scale = dim->scale_mult;+++    if ( count > 0 )+    {+      width->cur = FT_MulFix( width->org, scale );+      width->fit = FT_PIX_ROUND( width->cur );++      width++;+      count--;++      for ( ; count > 0; count--, width++ )+      {+        FT_Pos  w, dist;+++        w    = FT_MulFix( width->org, scale );+        dist = w - stand->cur;++        if ( dist < 0 )+          dist = -dist;++        if ( dist < 128 )+          w = stand->cur;++        width->cur = w;+        width->fit = FT_PIX_ROUND( w );+      }+    }+  }+++#if 0++  /* org_width is is font units, result in device pixels, 26.6 format */+  FT_LOCAL_DEF( FT_Pos )+  psh_dimension_snap_width( PSH_Dimension  dimension,+                            FT_Int         org_width )+  {+    FT_UInt  n;+    FT_Pos   width     = FT_MulFix( org_width, dimension->scale_mult );+    FT_Pos   best      = 64 + 32 + 2;+    FT_Pos   reference = width;+++    for ( n = 0; n < dimension->stdw.count; n++ )+    {+      FT_Pos  w;+      FT_Pos  dist;+++      w = dimension->stdw.widths[n].cur;+      dist = width - w;+      if ( dist < 0 )+        dist = -dist;+      if ( dist < best )+      {+        best      = dist;+        reference = w;+      }+    }++    if ( width >= reference )+    {+      width -= 0x21;+      if ( width < reference )+        width = reference;+    }+    else+    {+      width += 0x21;+      if ( width > reference )+        width = reference;+    }++    return width;+  }++#endif /* 0 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       BLUE ZONES                              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  psh_blues_set_zones_0( PSH_Blues       target,+                         FT_Bool         is_others,+                         FT_UInt         read_count,+                         FT_Short*       read,+                         PSH_Blue_Table  top_table,+                         PSH_Blue_Table  bot_table )+  {+    FT_UInt  count_top = top_table->count;+    FT_UInt  count_bot = bot_table->count;+    FT_Bool  first     = 1;++    FT_UNUSED( target );+++    for ( ; read_count > 1; read_count -= 2 )+    {+      FT_Int         reference, delta;+      FT_UInt        count;+      PSH_Blue_Zone  zones, zone;+      FT_Bool        top;+++      /* read blue zone entry, and select target top/bottom zone */+      top = 0;+      if ( first || is_others )+      {+        reference = read[1];+        delta     = read[0] - reference;++        zones = bot_table->zones;+        count = count_bot;+        first = 0;+      }+      else+      {+        reference = read[0];+        delta     = read[1] - reference;++        zones = top_table->zones;+        count = count_top;+        top   = 1;+      }++      /* insert into sorted table */+      zone = zones;+      for ( ; count > 0; count--, zone++ )+      {+        if ( reference < zone->org_ref )+          break;++        if ( reference == zone->org_ref )+        {+          FT_Int  delta0 = zone->org_delta;+++          /* we have two zones on the same reference position -- */+          /* only keep the largest one                           */+          if ( delta < 0 )+          {+            if ( delta < delta0 )+              zone->org_delta = delta;+          }+          else+          {+            if ( delta > delta0 )+              zone->org_delta = delta;+          }+          goto Skip;+        }+      }++      for ( ; count > 0; count-- )+        zone[count] = zone[count-1];++      zone->org_ref   = reference;+      zone->org_delta = delta;++      if ( top )+        count_top++;+      else+        count_bot++;++    Skip:+      read += 2;+    }++    top_table->count = count_top;+    bot_table->count = count_bot;+  }+++  /* Re-read blue zones from the original fonts and store them into out */+  /* private structure.  This function re-orders, sanitizes and         */+  /* fuzz-expands the zones as well.                                    */+  static void+  psh_blues_set_zones( PSH_Blues  target,+                       FT_UInt    count,+                       FT_Short*  blues,+                       FT_UInt    count_others,+                       FT_Short*  other_blues,+                       FT_Int     fuzz,+                       FT_Int     family )+  {+    PSH_Blue_Table  top_table, bot_table;+    FT_Int          count_top, count_bot;+++    if ( family )+    {+      top_table = &target->family_top;+      bot_table = &target->family_bottom;+    }+    else+    {+      top_table = &target->normal_top;+      bot_table = &target->normal_bottom;+    }++    /* read the input blue zones, and build two sorted tables  */+    /* (one for the top zones, the other for the bottom zones) */+    top_table->count = 0;+    bot_table->count = 0;++    /* first, the blues */+    psh_blues_set_zones_0( target, 0,+                           count, blues, top_table, bot_table );+    psh_blues_set_zones_0( target, 1,+                           count_others, other_blues, top_table, bot_table );++    count_top = top_table->count;+    count_bot = bot_table->count;++    /* sanitize top table */+    if ( count_top > 0 )+    {+      PSH_Blue_Zone  zone = top_table->zones;+++      for ( count = count_top; count > 0; count--, zone++ )+      {+        FT_Int  delta;+++        if ( count > 1 )+        {+          delta = zone[1].org_ref - zone[0].org_ref;+          if ( zone->org_delta > delta )+            zone->org_delta = delta;+        }++        zone->org_bottom = zone->org_ref;+        zone->org_top    = zone->org_delta + zone->org_ref;+      }+    }++    /* sanitize bottom table */+    if ( count_bot > 0 )+    {+      PSH_Blue_Zone  zone = bot_table->zones;+++      for ( count = count_bot; count > 0; count--, zone++ )+      {+        FT_Int  delta;+++        if ( count > 1 )+        {+          delta = zone[0].org_ref - zone[1].org_ref;+          if ( zone->org_delta < delta )+            zone->org_delta = delta;+        }++        zone->org_top    = zone->org_ref;+        zone->org_bottom = zone->org_delta + zone->org_ref;+      }+    }++    /* expand top and bottom tables with blue fuzz */+    {+      FT_Int         dim, top, bot, delta;+      PSH_Blue_Zone  zone;+++      zone  = top_table->zones;+      count = count_top;++      for ( dim = 1; dim >= 0; dim-- )+      {+        if ( count > 0 )+        {+          /* expand the bottom of the lowest zone normally */+          zone->org_bottom -= fuzz;++          /* expand the top and bottom of intermediate zones;    */+          /* checking that the interval is smaller than the fuzz */+          top = zone->org_top;++          for ( count--; count > 0; count-- )+          {+            bot   = zone[1].org_bottom;+            delta = bot - top;++            if ( delta < 2 * fuzz )+              zone[0].org_top = zone[1].org_bottom = top + delta / 2;+            else+            {+              zone[0].org_top    = top + fuzz;+              zone[1].org_bottom = bot - fuzz;+            }++            zone++;+            top = zone->org_top;+          }++          /* expand the top of the highest zone normally */+          zone->org_top = top + fuzz;+        }+        zone  = bot_table->zones;+        count = count_bot;+      }+    }+  }+++  /* reset the blues table when the device transform changes */+  static void+  psh_blues_scale_zones( PSH_Blues  blues,+                         FT_Fixed   scale,+                         FT_Pos     delta )+  {+    FT_UInt         count;+    FT_UInt         num;+    PSH_Blue_Table  table = 0;++    /*                                                        */+    /* Determine whether we need to suppress overshoots or    */+    /* not.  We simply need to compare the vertical scale     */+    /* parameter to the raw bluescale value.  Here is why:    */+    /*                                                        */+    /*   We need to suppress overshoots for all pointsizes.   */+    /*   At 300dpi that satisfies:                            */+    /*                                                        */+    /*      pointsize < 240*bluescale + 0.49                  */+    /*                                                        */+    /*   This corresponds to:                                 */+    /*                                                        */+    /*      pixelsize < 1000*bluescale + 49/24                */+    /*                                                        */+    /*      scale*EM_Size < 1000*bluescale + 49/24            */+    /*                                                        */+    /*   However, for normal Type 1 fonts, EM_Size is 1000!   */+    /*   We thus only check:                                  */+    /*                                                        */+    /*      scale < bluescale + 49/24000                      */+    /*                                                        */+    /*   which we shorten to                                  */+    /*                                                        */+    /*      "scale < bluescale"                               */+    /*                                                        */+    /* Note that `blue_scale' is stored 1000 times its real   */+    /* value, and that `scale' converts from font units to    */+    /* fractional pixels.                                     */+    /*                                                        */++    /* 1000 / 64 = 125 / 8 */+    if ( scale >= 0x20C49BAL )+      blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 );+    else+      blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 );++    /*                                                        */+    /*  The blue threshold is the font units distance under   */+    /*  which overshoots are suppressed due to the BlueShift  */+    /*  even if the scale is greater than BlueScale.          */+    /*                                                        */+    /*  It is the smallest distance such that                 */+    /*                                                        */+    /*    dist <= BlueShift && dist*scale <= 0.5 pixels       */+    /*                                                        */+    {+      FT_Int  threshold = blues->blue_shift;+++      while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 )+        threshold--;++      blues->blue_threshold = threshold;+    }++    for ( num = 0; num < 4; num++ )+    {+      PSH_Blue_Zone  zone;+++      switch ( num )+      {+      case 0:+        table = &blues->normal_top;+        break;+      case 1:+        table = &blues->normal_bottom;+        break;+      case 2:+        table = &blues->family_top;+        break;+      default:+        table = &blues->family_bottom;+        break;+      }++      zone  = table->zones;+      count = table->count;+      for ( ; count > 0; count--, zone++ )+      {+        zone->cur_top    = FT_MulFix( zone->org_top,    scale ) + delta;+        zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta;+        zone->cur_ref    = FT_MulFix( zone->org_ref,    scale ) + delta;+        zone->cur_delta  = FT_MulFix( zone->org_delta,  scale );++        /* round scaled reference position */+        zone->cur_ref = FT_PIX_ROUND( zone->cur_ref );++#if 0+        if ( zone->cur_ref > zone->cur_top )+          zone->cur_ref -= 64;+        else if ( zone->cur_ref < zone->cur_bottom )+          zone->cur_ref += 64;+#endif+      }+    }++    /* process the families now */++    for ( num = 0; num < 2; num++ )+    {+      PSH_Blue_Zone   zone1, zone2;+      FT_UInt         count1, count2;+      PSH_Blue_Table  normal, family;+++      switch ( num )+      {+      case 0:+        normal = &blues->normal_top;+        family = &blues->family_top;+        break;++      default:+        normal = &blues->normal_bottom;+        family = &blues->family_bottom;+      }++      zone1  = normal->zones;+      count1 = normal->count;++      for ( ; count1 > 0; count1--, zone1++ )+      {+        /* try to find a family zone whose reference position is less */+        /* than 1 pixel far from the current zone                     */+        zone2  = family->zones;+        count2 = family->count;++        for ( ; count2 > 0; count2--, zone2++ )+        {+          FT_Pos  Delta;+++          Delta = zone1->org_ref - zone2->org_ref;+          if ( Delta < 0 )+            Delta = -Delta;++          if ( FT_MulFix( Delta, scale ) < 64 )+          {+            zone1->cur_top    = zone2->cur_top;+            zone1->cur_bottom = zone2->cur_bottom;+            zone1->cur_ref    = zone2->cur_ref;+            zone1->cur_delta  = zone2->cur_delta;+            break;+          }+        }+      }+    }+  }+++  FT_LOCAL_DEF( void )+  psh_blues_snap_stem( PSH_Blues      blues,+                       FT_Int         stem_top,+                       FT_Int         stem_bot,+                       PSH_Alignment  alignment )+  {+    PSH_Blue_Table  table;+    FT_UInt         count;+    FT_Pos          delta;+    PSH_Blue_Zone   zone;+    FT_Int          no_shoots;+++    alignment->align = PSH_BLUE_ALIGN_NONE;++    no_shoots = blues->no_overshoots;++    /* look up stem top in top zones table */+    table = &blues->normal_top;+    count = table->count;+    zone  = table->zones;++    for ( ; count > 0; count--, zone++ )+    {+      delta = stem_top - zone->org_bottom;+      if ( delta < -blues->blue_fuzz )+        break;++      if ( stem_top <= zone->org_top + blues->blue_fuzz )+      {+        if ( no_shoots || delta <= blues->blue_threshold )+        {+          alignment->align    |= PSH_BLUE_ALIGN_TOP;+          alignment->align_top = zone->cur_ref;+        }+        break;+      }+    }++    /* look up stem bottom in bottom zones table */+    table = &blues->normal_bottom;+    count = table->count;+    zone  = table->zones + count-1;++    for ( ; count > 0; count--, zone-- )+    {+      delta = zone->org_top - stem_bot;+      if ( delta < -blues->blue_fuzz )+        break;++      if ( stem_bot >= zone->org_bottom - blues->blue_fuzz )+      {+        if ( no_shoots || delta < blues->blue_threshold )+        {+          alignment->align    |= PSH_BLUE_ALIGN_BOT;+          alignment->align_bot = zone->cur_ref;+        }+        break;+      }+    }+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                        GLOBAL HINTS                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  psh_globals_destroy( PSH_Globals  globals )+  {+    if ( globals )+    {+      FT_Memory  memory;+++      memory = globals->memory;+      globals->dimension[0].stdw.count = 0;+      globals->dimension[1].stdw.count = 0;++      globals->blues.normal_top.count    = 0;+      globals->blues.normal_bottom.count = 0;+      globals->blues.family_top.count    = 0;+      globals->blues.family_bottom.count = 0;++      FT_FREE( globals );++#ifdef DEBUG_HINTER+      ps_debug_globals = 0;+#endif+    }+  }+++  static FT_Error+  psh_globals_new( FT_Memory     memory,+                   T1_Private*   priv,+                   PSH_Globals  *aglobals )+  {+    PSH_Globals  globals = NULL;+    FT_Error     error;+++    if ( !FT_NEW( globals ) )+    {+      FT_UInt    count;+      FT_Short*  read;+++      globals->memory = memory;++      /* copy standard widths */+      {+        PSH_Dimension  dim   = &globals->dimension[1];+        PSH_Width      write = dim->stdw.widths;+++        write->org = priv->standard_width[0];+        write++;++        read = priv->snap_widths;+        for ( count = priv->num_snap_widths; count > 0; count-- )+        {+          write->org = *read;+          write++;+          read++;+        }++        dim->stdw.count = priv->num_snap_widths + 1;+      }++      /* copy standard heights */+      {+        PSH_Dimension  dim = &globals->dimension[0];+        PSH_Width      write = dim->stdw.widths;+++        write->org = priv->standard_height[0];+        write++;+        read = priv->snap_heights;+        for ( count = priv->num_snap_heights; count > 0; count-- )+        {+          write->org = *read;+          write++;+          read++;+        }++        dim->stdw.count = priv->num_snap_heights + 1;+      }++      /* copy blue zones */+      psh_blues_set_zones( &globals->blues, priv->num_blue_values,+                           priv->blue_values, priv->num_other_blues,+                           priv->other_blues, priv->blue_fuzz, 0 );++      psh_blues_set_zones( &globals->blues, priv->num_family_blues,+                           priv->family_blues, priv->num_family_other_blues,+                           priv->family_other_blues, priv->blue_fuzz, 1 );++      globals->blues.blue_scale = priv->blue_scale;+      globals->blues.blue_shift = priv->blue_shift;+      globals->blues.blue_fuzz  = priv->blue_fuzz;++      globals->dimension[0].scale_mult  = 0;+      globals->dimension[0].scale_delta = 0;+      globals->dimension[1].scale_mult  = 0;+      globals->dimension[1].scale_delta = 0;++#ifdef DEBUG_HINTER+      ps_debug_globals = globals;+#endif+    }++    *aglobals = globals;+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  psh_globals_set_scale( PSH_Globals  globals,+                         FT_Fixed     x_scale,+                         FT_Fixed     y_scale,+                         FT_Fixed     x_delta,+                         FT_Fixed     y_delta )+  {+    PSH_Dimension  dim = &globals->dimension[0];+++    dim = &globals->dimension[0];+    if ( x_scale != dim->scale_mult  ||+         x_delta != dim->scale_delta )+    {+      dim->scale_mult  = x_scale;+      dim->scale_delta = x_delta;++      psh_globals_scale_widths( globals, 0 );+    }++    dim = &globals->dimension[1];+    if ( y_scale != dim->scale_mult  ||+         y_delta != dim->scale_delta )+    {+      dim->scale_mult  = y_scale;+      dim->scale_delta = y_delta;++      psh_globals_scale_widths( globals, 1 );+      psh_blues_scale_zones( &globals->blues, y_scale, y_delta );+    }++    return 0;+  }+++  FT_LOCAL_DEF( void )+  psh_globals_funcs_init( PSH_Globals_FuncsRec*  funcs )+  {+    funcs->create    = psh_globals_new;+    funcs->set_scale = psh_globals_set_scale;+    funcs->destroy   = psh_globals_destroy;+  }+++/* END */
+ src/pshinter/pshglob.h view
@@ -0,0 +1,196 @@+/***************************************************************************/+/*                                                                         */+/*  pshglob.h                                                              */+/*                                                                         */+/*    PostScript hinter global hinting management.                         */+/*                                                                         */+/*  Copyright 2001, 2002, 2003 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSHGLOB_H__+#define __PSHGLOB_H__+++#include FT_FREETYPE_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    GLOBAL HINTS INTERNALS                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* @constant:                                                            */+  /*    PS_GLOBALS_MAX_BLUE_ZONES                                          */+  /*                                                                       */+  /* @description:                                                         */+  /*    The maximum number of blue zones in a font global hints structure. */+  /*    See @PS_Globals_BluesRec.                                          */+  /*                                                                       */+#define PS_GLOBALS_MAX_BLUE_ZONES  16+++  /*************************************************************************/+  /*                                                                       */+  /* @constant:                                                            */+  /*    PS_GLOBALS_MAX_STD_WIDTHS                                          */+  /*                                                                       */+  /* @description:                                                         */+  /*    The maximum number of standard and snap widths in either the       */+  /*    horizontal or vertical direction.  See @PS_Globals_WidthsRec.      */+  /*                                                                       */+#define PS_GLOBALS_MAX_STD_WIDTHS  16+++  /* standard and snap width */+  typedef struct  PSH_WidthRec_+  {+    FT_Int  org;+    FT_Pos  cur;+    FT_Pos  fit;++  } PSH_WidthRec, *PSH_Width;+++  /* standard and snap widths table */+  typedef struct  PSH_WidthsRec_+  {+    FT_UInt       count;+    PSH_WidthRec  widths[PS_GLOBALS_MAX_STD_WIDTHS];++  } PSH_WidthsRec, *PSH_Widths;+++  typedef struct  PSH_DimensionRec_+  {+    PSH_WidthsRec  stdw;+    FT_Fixed       scale_mult;+    FT_Fixed       scale_delta;++  } PSH_DimensionRec, *PSH_Dimension;+++  /* blue zone descriptor */+  typedef struct  PSH_Blue_ZoneRec_+  {+    FT_Int  org_ref;+    FT_Int  org_delta;+    FT_Int  org_top;+    FT_Int  org_bottom;++    FT_Pos  cur_ref;+    FT_Pos  cur_delta;+    FT_Pos  cur_bottom;+    FT_Pos  cur_top;++  } PSH_Blue_ZoneRec, *PSH_Blue_Zone;+++  typedef struct  PSH_Blue_TableRec_+  {+    FT_UInt           count;+    PSH_Blue_ZoneRec  zones[PS_GLOBALS_MAX_BLUE_ZONES];++  } PSH_Blue_TableRec, *PSH_Blue_Table;+++  /* blue zones table */+  typedef struct  PSH_BluesRec_+  {+    PSH_Blue_TableRec  normal_top;+    PSH_Blue_TableRec  normal_bottom;+    PSH_Blue_TableRec  family_top;+    PSH_Blue_TableRec  family_bottom;++    FT_Fixed           blue_scale;+    FT_Int             blue_shift;+    FT_Int             blue_threshold;+    FT_Int             blue_fuzz;+    FT_Bool            no_overshoots;++  } PSH_BluesRec, *PSH_Blues;+++  /* font globals.                                         */+  /* dimension 0 => X coordinates + vertical hints/stems   */+  /* dimension 1 => Y coordinates + horizontal hints/stems */+  typedef struct  PSH_GlobalsRec_+  {+    FT_Memory         memory;+    PSH_DimensionRec  dimension[2];+    PSH_BluesRec      blues;++  } PSH_GlobalsRec;+++#define PSH_BLUE_ALIGN_NONE  0+#define PSH_BLUE_ALIGN_TOP   1+#define PSH_BLUE_ALIGN_BOT   2+++  typedef struct  PSH_AlignmentRec_+  {+    int     align;+    FT_Pos  align_top;+    FT_Pos  align_bot;++  } PSH_AlignmentRec, *PSH_Alignment;+++  FT_LOCAL( void )+  psh_globals_funcs_init( PSH_Globals_FuncsRec*  funcs );+++#if 0+  /* snap a stem width to fitter coordinates.  `org_width' is in font */+  /* units.  The result is in device pixels (26.6 format).            */+  FT_LOCAL( FT_Pos )+  psh_dimension_snap_width( PSH_Dimension  dimension,+                            FT_Int         org_width );+#endif++  FT_LOCAL( FT_Error )+  psh_globals_set_scale( PSH_Globals  globals,+                         FT_Fixed     x_scale,+                         FT_Fixed     y_scale,+                         FT_Fixed     x_delta,+                         FT_Fixed     y_delta );++  /* snap a stem to one or two blue zones */+  FT_LOCAL( void )+  psh_blues_snap_stem( PSH_Blues      blues,+                       FT_Int         stem_top,+                       FT_Int         stem_bot,+                       PSH_Alignment  alignment );+  /* */++#ifdef DEBUG_HINTER+  extern PSH_Globals  ps_debug_globals;+#endif+++FT_END_HEADER+++#endif /* __PSHGLOB_H__ */+++/* END */
+ src/pshinter/pshinter.c view
@@ -0,0 +1,29 @@+/***************************************************************************/+/*                                                                         */+/*  pshinter.c                                                             */+/*                                                                         */+/*    FreeType PostScript Hinting module                                   */+/*                                                                         */+/*  Copyright 2001, 2003 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "pshpic.c"+#include "pshrec.c"+#include "pshglob.c"+#include "pshalgo.c"+#include "pshmod.c"+++/* END */
+ src/pshinter/pshmod.c view
@@ -0,0 +1,118 @@+/***************************************************************************/+/*                                                                         */+/*  pshmod.c                                                               */+/*                                                                         */+/*    FreeType PostScript hinter module implementation (body).             */+/*                                                                         */+/*  Copyright 2001, 2002, 2007 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include "pshrec.h"+#include "pshalgo.h"+#include "pshpic.h"+++  /* the Postscript Hinter module structure */+  typedef struct  PS_Hinter_Module_Rec_+  {+    FT_ModuleRec          root;+    PS_HintsRec           ps_hints;++    PSH_Globals_FuncsRec  globals_funcs;+    T1_Hints_FuncsRec     t1_funcs;+    T2_Hints_FuncsRec     t2_funcs;++  } PS_Hinter_ModuleRec, *PS_Hinter_Module;+++  /* finalize module */+  FT_CALLBACK_DEF( void )+  ps_hinter_done( PS_Hinter_Module  module )+  {+    module->t1_funcs.hints = NULL;+    module->t2_funcs.hints = NULL;++    ps_hints_done( &module->ps_hints );+  }+++  /* initialize module, create hints recorder and the interface */+  FT_CALLBACK_DEF( FT_Error )+  ps_hinter_init( PS_Hinter_Module  module )+  {+    FT_Memory  memory = module->root.memory;+    void*      ph     = &module->ps_hints;+++    ps_hints_init( &module->ps_hints, memory );++    psh_globals_funcs_init( &module->globals_funcs );++    t1_hints_funcs_init( &module->t1_funcs );+    module->t1_funcs.hints = (T1_Hints)ph;++    t2_hints_funcs_init( &module->t2_funcs );+    module->t2_funcs.hints = (T2_Hints)ph;++    return 0;+  }+++  /* returns global hints interface */+  FT_CALLBACK_DEF( PSH_Globals_Funcs )+  pshinter_get_globals_funcs( FT_Module  module )+  {+    return &((PS_Hinter_Module)module)->globals_funcs;+  }+++  /* return Type 1 hints interface */+  FT_CALLBACK_DEF( T1_Hints_Funcs )+  pshinter_get_t1_funcs( FT_Module  module )+  {+    return &((PS_Hinter_Module)module)->t1_funcs;+  }+++  /* return Type 2 hints interface */+  FT_CALLBACK_DEF( T2_Hints_Funcs )+  pshinter_get_t2_funcs( FT_Module  module )+  {+    return &((PS_Hinter_Module)module)->t2_funcs;+  }+++  FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface,+    pshinter_get_globals_funcs,+    pshinter_get_t1_funcs,+    pshinter_get_t2_funcs+  )+++  FT_DEFINE_MODULE(pshinter_module_class,++    0,+    sizeof ( PS_Hinter_ModuleRec ),+    "pshinter",+    0x10000L,+    0x20000L,++    &FTPSHINTER_INTERFACE_GET,            /* module-specific interface */++    (FT_Module_Constructor)ps_hinter_init,+    (FT_Module_Destructor) ps_hinter_done,+    (FT_Module_Requester)  0        /* no additional interface for now */+  )++/* END */
+ src/pshinter/pshmod.h view
@@ -0,0 +1,39 @@+/***************************************************************************/+/*                                                                         */+/*  pshmod.h                                                               */+/*                                                                         */+/*    PostScript hinter module interface (specification).                  */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSHMOD_H__+#define __PSHMOD_H__+++#include <ft2build.h>+#include FT_MODULE_H+++FT_BEGIN_HEADER+++  FT_DECLARE_MODULE( pshinter_module_class )+++FT_END_HEADER+++#endif /* __PSHMOD_H__ */+++/* END */
+ src/pshinter/pshnterr.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  pshnterr.h                                                             */+/*                                                                         */+/*    PS Hinter error codes (specification only).                          */+/*                                                                         */+/*  Copyright 2003 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the PSHinter error enumeration constants. */+  /*                                                                       */+  /*************************************************************************/++#ifndef __PSHNTERR_H__+#define __PSHNTERR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  PSH_Err_+#define FT_ERR_BASE    FT_Mod_Err_PShinter++#include FT_ERRORS_H++#endif /* __PSHNTERR_H__ */+++/* END */
+ src/pshinter/pshpic.c view
@@ -0,0 +1,69 @@+/***************************************************************************/+/*                                                                         */+/*  pshpic.c                                                               */+/*                                                                         */+/*    The FreeType position independent code services for pshinter module. */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "pshpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from pshmod.c */+  void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*);++  void+  pshinter_module_class_pic_free( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->pshinter )+    {+      FT_FREE( pic_container->pshinter );+      pic_container->pshinter = NULL;+    }+  }+++  FT_Error+  pshinter_module_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error         = PSH_Err_Ok;+    PSHinterPIC*       container;+    FT_Memory          memory        = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof ( *container ) );+    pic_container->pshinter = container;+    +    /* add call to initialization function when you add new scripts */+    FT_Init_Class_pshinter_interface(library, &container->pshinter_interface);++/*Exit:*/+    if(error)+      pshinter_module_class_pic_free(library);+    return error;+  }+++#endif /* FT_CONFIG_OPTION_PIC */++/* END */
+ src/pshinter/pshpic.h view
@@ -0,0 +1,53 @@+/***************************************************************************/+/*                                                                         */+/*  pshpic.h                                                               */+/*                                                                         */+/*    The FreeType position independent code services for pshinter module. */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSHPIC_H__+#define __PSHPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC++#define FTPSHINTER_INTERFACE_GET        pshinter_interface++#else /* FT_CONFIG_OPTION_PIC */++#include FT_INTERNAL_POSTSCRIPT_HINTS_H++  typedef struct PSHinterPIC_+  {+    PSHinter_Interface pshinter_interface;+  } PSHinterPIC;++#define GET_PIC(lib)                    ((PSHinterPIC*)((lib)->pic_container.autofit))+#define FTPSHINTER_INTERFACE_GET        (GET_PIC(library)->pshinter_interface)+++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __PSHPIC_H__ */+++/* END */
+ src/pshinter/pshrec.c view
@@ -0,0 +1,1224 @@+/***************************************************************************/+/*                                                                         */+/*  pshrec.c                                                               */+/*                                                                         */+/*    FreeType PostScript hints recorder (body).                           */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2004, 2007, 2009 by                        */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H++#include "pshrec.h"+#include "pshalgo.h"++#include "pshnterr.h"++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_pshrec++#ifdef DEBUG_HINTER+  PS_Hints  ps_debug_hints         = 0;+  int       ps_debug_no_horz_hints = 0;+  int       ps_debug_no_vert_hints = 0;+#endif+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      PS_HINT MANAGEMENT                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* destroy hints table */+  static void+  ps_hint_table_done( PS_Hint_Table  table,+                      FT_Memory      memory )+  {+    FT_FREE( table->hints );+    table->num_hints = 0;+    table->max_hints = 0;+  }+++  /* ensure that a table can contain "count" elements */+  static FT_Error+  ps_hint_table_ensure( PS_Hint_Table  table,+                        FT_UInt        count,+                        FT_Memory      memory )+  {+    FT_UInt   old_max = table->max_hints;+    FT_UInt   new_max = count;+    FT_Error  error   = PSH_Err_Ok;+++    if ( new_max > old_max )+    {+      /* try to grow the table */+      new_max = FT_PAD_CEIL( new_max, 8 );+      if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) )+        table->max_hints = new_max;+    }+    return error;+  }+++  static FT_Error+  ps_hint_table_alloc( PS_Hint_Table  table,+                       FT_Memory      memory,+                       PS_Hint       *ahint )+  {+    FT_Error  error = PSH_Err_Ok;+    FT_UInt   count;+    PS_Hint   hint = 0;+++    count = table->num_hints;+    count++;++    if ( count >= table->max_hints )+    {+      error = ps_hint_table_ensure( table, count, memory );+      if ( error )+        goto Exit;+    }++    hint        = table->hints + count - 1;+    hint->pos   = 0;+    hint->len   = 0;+    hint->flags = 0;++    table->num_hints = count;++  Exit:+    *ahint = hint;+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      PS_MASK MANAGEMENT                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* destroy mask */+  static void+  ps_mask_done( PS_Mask    mask,+                FT_Memory  memory )+  {+    FT_FREE( mask->bytes );+    mask->num_bits  = 0;+    mask->max_bits  = 0;+    mask->end_point = 0;+  }+++  /* ensure that a mask can contain "count" bits */+  static FT_Error+  ps_mask_ensure( PS_Mask    mask,+                  FT_UInt    count,+                  FT_Memory  memory )+  {+    FT_UInt   old_max = ( mask->max_bits + 7 ) >> 3;+    FT_UInt   new_max = ( count          + 7 ) >> 3;+    FT_Error  error   = PSH_Err_Ok;+++    if ( new_max > old_max )+    {+      new_max = FT_PAD_CEIL( new_max, 8 );+      if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) )+        mask->max_bits = new_max * 8;+    }+    return error;+  }+++  /* test a bit value in a given mask */+  static FT_Int+  ps_mask_test_bit( PS_Mask  mask,+                    FT_Int   idx )+  {+    if ( (FT_UInt)idx >= mask->num_bits )+      return 0;++    return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) );+  }+++  /* clear a given bit */+  static void+  ps_mask_clear_bit( PS_Mask  mask,+                     FT_Int   idx )+  {+    FT_Byte*  p;+++    if ( (FT_UInt)idx >= mask->num_bits )+      return;++    p    = mask->bytes + ( idx >> 3 );+    p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) );+  }+++  /* set a given bit, possibly grow the mask */+  static FT_Error+  ps_mask_set_bit( PS_Mask    mask,+                   FT_Int     idx,+                   FT_Memory  memory )+  {+    FT_Error  error = PSH_Err_Ok;+    FT_Byte*  p;+++    if ( idx < 0 )+      goto Exit;++    if ( (FT_UInt)idx >= mask->num_bits )+    {+      error = ps_mask_ensure( mask, idx + 1, memory );+      if ( error )+        goto Exit;++      mask->num_bits = idx + 1;+    }++    p    = mask->bytes + ( idx >> 3 );+    p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) );++  Exit:+    return error;+  }+++  /* destroy mask table */+  static void+  ps_mask_table_done( PS_Mask_Table  table,+                      FT_Memory      memory )+  {+    FT_UInt  count = table->max_masks;+    PS_Mask  mask  = table->masks;+++    for ( ; count > 0; count--, mask++ )+      ps_mask_done( mask, memory );++    FT_FREE( table->masks );+    table->num_masks = 0;+    table->max_masks = 0;+  }+++  /* ensure that a mask table can contain "count" masks */+  static FT_Error+  ps_mask_table_ensure( PS_Mask_Table  table,+                        FT_UInt        count,+                        FT_Memory      memory )+  {+    FT_UInt   old_max = table->max_masks;+    FT_UInt   new_max = count;+    FT_Error  error   = PSH_Err_Ok;+++    if ( new_max > old_max )+    {+      new_max = FT_PAD_CEIL( new_max, 8 );+      if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) )+        table->max_masks = new_max;+    }+    return error;+  }+++  /* allocate a new mask in a table */+  static FT_Error+  ps_mask_table_alloc( PS_Mask_Table  table,+                       FT_Memory      memory,+                       PS_Mask       *amask )+  {+    FT_UInt   count;+    FT_Error  error = PSH_Err_Ok;+    PS_Mask   mask  = 0;+++    count = table->num_masks;+    count++;++    if ( count > table->max_masks )+    {+      error = ps_mask_table_ensure( table, count, memory );+      if ( error )+        goto Exit;+    }++    mask             = table->masks + count - 1;+    mask->num_bits   = 0;+    mask->end_point  = 0;+    table->num_masks = count;++  Exit:+    *amask = mask;+    return error;+  }+++  /* return last hint mask in a table, create one if the table is empty */+  static FT_Error+  ps_mask_table_last( PS_Mask_Table  table,+                      FT_Memory      memory,+                      PS_Mask       *amask )+  {+    FT_Error  error = PSH_Err_Ok;+    FT_UInt   count;+    PS_Mask   mask;+++    count = table->num_masks;+    if ( count == 0 )+    {+      error = ps_mask_table_alloc( table, memory, &mask );+      if ( error )+        goto Exit;+    }+    else+      mask = table->masks + count - 1;++  Exit:+    *amask = mask;+    return error;+  }+++  /* set a new mask to a given bit range */+  static FT_Error+  ps_mask_table_set_bits( PS_Mask_Table   table,+                          const FT_Byte*  source,+                          FT_UInt         bit_pos,+                          FT_UInt         bit_count,+                          FT_Memory       memory )+  {+    FT_Error  error = PSH_Err_Ok;+    PS_Mask   mask;+++    error = ps_mask_table_last( table, memory, &mask );+    if ( error )+      goto Exit;++    error = ps_mask_ensure( mask, bit_count, memory );+    if ( error )+      goto Exit;++    mask->num_bits = bit_count;++    /* now, copy bits */+    {+      FT_Byte*  read  = (FT_Byte*)source + ( bit_pos >> 3 );+      FT_Int    rmask = 0x80 >> ( bit_pos & 7 );+      FT_Byte*  write = mask->bytes;+      FT_Int    wmask = 0x80;+      FT_Int    val;+++      for ( ; bit_count > 0; bit_count-- )+      {+        val = write[0] & ~wmask;++        if ( read[0] & rmask )+          val |= wmask;++        write[0] = (FT_Byte)val;++        rmask >>= 1;+        if ( rmask == 0 )+        {+          read++;+          rmask = 0x80;+        }++        wmask >>= 1;+        if ( wmask == 0 )+        {+          write++;+          wmask = 0x80;+        }+      }+    }++  Exit:+    return error;+  }+++  /* test whether two masks in a table intersect */+  static FT_Int+  ps_mask_table_test_intersect( PS_Mask_Table  table,+                                FT_Int         index1,+                                FT_Int         index2 )+  {+    PS_Mask   mask1  = table->masks + index1;+    PS_Mask   mask2  = table->masks + index2;+    FT_Byte*  p1     = mask1->bytes;+    FT_Byte*  p2     = mask2->bytes;+    FT_UInt   count1 = mask1->num_bits;+    FT_UInt   count2 = mask2->num_bits;+    FT_UInt   count;+++    count = ( count1 <= count2 ) ? count1 : count2;+    for ( ; count >= 8; count -= 8 )+    {+      if ( p1[0] & p2[0] )+        return 1;++      p1++;+      p2++;+    }++    if ( count == 0 )+      return 0;++    return ( p1[0] & p2[0] ) & ~( 0xFF >> count );+  }+++  /* merge two masks, used by ps_mask_table_merge_all */+  static FT_Error+  ps_mask_table_merge( PS_Mask_Table  table,+                       FT_Int         index1,+                       FT_Int         index2,+                       FT_Memory      memory )+  {+    FT_UInt   temp;+    FT_Error  error = PSH_Err_Ok;+++    /* swap index1 and index2 so that index1 < index2 */+    if ( index1 > index2 )+    {+      temp   = index1;+      index1 = index2;+      index2 = temp;+    }++    if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks )+    {+      /* we need to merge the bitsets of index1 and index2 with a */+      /* simple union                                             */+      PS_Mask  mask1  = table->masks + index1;+      PS_Mask  mask2  = table->masks + index2;+      FT_UInt  count1 = mask1->num_bits;+      FT_UInt  count2 = mask2->num_bits;+      FT_Int   delta;+++      if ( count2 > 0 )+      {+        FT_UInt   pos;+        FT_Byte*  read;+        FT_Byte*  write;+++        /* if "count2" is greater than "count1", we need to grow the */+        /* first bitset, and clear the highest bits                  */+        if ( count2 > count1 )+        {+          error = ps_mask_ensure( mask1, count2, memory );+          if ( error )+            goto Exit;++          for ( pos = count1; pos < count2; pos++ )+            ps_mask_clear_bit( mask1, pos );+        }++        /* merge (unite) the bitsets */+        read  = mask2->bytes;+        write = mask1->bytes;+        pos   = (FT_UInt)( ( count2 + 7 ) >> 3 );++        for ( ; pos > 0; pos-- )+        {+          write[0] = (FT_Byte)( write[0] | read[0] );+          write++;+          read++;+        }+      }++      /* Now, remove "mask2" from the list.  We need to keep the masks */+      /* sorted in order of importance, so move table elements.        */+      mask2->num_bits  = 0;+      mask2->end_point = 0;++      delta = table->num_masks - 1 - index2; /* number of masks to move */+      if ( delta > 0 )+      {+        /* move to end of table for reuse */+        PS_MaskRec  dummy = *mask2;+++        ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) );++        mask2[delta] = dummy;+      }++      table->num_masks--;+    }+    else+      FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n",+                  index1, index2 ));++  Exit:+    return error;+  }+++  /* Try to merge all masks in a given table.  This is used to merge */+  /* all counter masks into independent counter "paths".             */+  /*                                                                 */+  static FT_Error+  ps_mask_table_merge_all( PS_Mask_Table  table,+                           FT_Memory      memory )+  {+    FT_Int    index1, index2;+    FT_Error  error = PSH_Err_Ok;+++    for ( index1 = table->num_masks - 1; index1 > 0; index1-- )+    {+      for ( index2 = index1 - 1; index2 >= 0; index2-- )+      {+        if ( ps_mask_table_test_intersect( table, index1, index2 ) )+        {+          error = ps_mask_table_merge( table, index2, index1, memory );+          if ( error )+            goto Exit;++          break;+        }+      }+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    PS_DIMENSION MANAGEMENT                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* finalize a given dimension */+  static void+  ps_dimension_done( PS_Dimension  dimension,+                     FT_Memory     memory )+  {+    ps_mask_table_done( &dimension->counters, memory );+    ps_mask_table_done( &dimension->masks,    memory );+    ps_hint_table_done( &dimension->hints,    memory );+  }+++  /* initialize a given dimension */+  static void+  ps_dimension_init( PS_Dimension  dimension )+  {+    dimension->hints.num_hints    = 0;+    dimension->masks.num_masks    = 0;+    dimension->counters.num_masks = 0;+  }+++#if 0++  /* set a bit at a given index in the current hint mask */+  static FT_Error+  ps_dimension_set_mask_bit( PS_Dimension  dim,+                             FT_UInt       idx,+                             FT_Memory     memory )+  {+    PS_Mask   mask;+    FT_Error  error = PSH_Err_Ok;+++    /* get last hint mask */+    error = ps_mask_table_last( &dim->masks, memory, &mask );+    if ( error )+      goto Exit;++    error = ps_mask_set_bit( mask, idx, memory );++  Exit:+    return error;+  }++#endif++  /* set the end point in a mask, called from "End" & "Reset" methods */+  static void+  ps_dimension_end_mask( PS_Dimension  dim,+                         FT_UInt       end_point )+  {+    FT_UInt  count = dim->masks.num_masks;+    PS_Mask  mask;+++    if ( count > 0 )+    {+      mask            = dim->masks.masks + count - 1;+      mask->end_point = end_point;+    }+  }+++  /* set the end point in the current mask, then create a new empty one */+  /* (called by "Reset" method)                                         */+  static FT_Error+  ps_dimension_reset_mask( PS_Dimension  dim,+                           FT_UInt       end_point,+                           FT_Memory     memory )+  {+    PS_Mask  mask;+++    /* end current mask */+    ps_dimension_end_mask( dim, end_point );++    /* allocate new one */+    return ps_mask_table_alloc( &dim->masks, memory, &mask );+  }+++  /* set a new mask, called from the "T2Stem" method */+  static FT_Error+  ps_dimension_set_mask_bits( PS_Dimension    dim,+                              const FT_Byte*  source,+                              FT_UInt         source_pos,+                              FT_UInt         source_bits,+                              FT_UInt         end_point,+                              FT_Memory       memory )+  {+    FT_Error  error = PSH_Err_Ok;+++    /* reset current mask, if any */+    error = ps_dimension_reset_mask( dim, end_point, memory );+    if ( error )+      goto Exit;++    /* set bits in new mask */+    error = ps_mask_table_set_bits( &dim->masks, source,+                                    source_pos, source_bits, memory );++  Exit:+    return error;+  }+++  /* add a new single stem (called from "T1Stem" method) */+  static FT_Error+  ps_dimension_add_t1stem( PS_Dimension  dim,+                           FT_Int        pos,+                           FT_Int        len,+                           FT_Memory     memory,+                           FT_Int       *aindex )+  {+    FT_Error  error = PSH_Err_Ok;+    FT_UInt   flags = 0;+++    /* detect ghost stem */+    if ( len < 0 )+    {+      flags |= PS_HINT_FLAG_GHOST;+      if ( len == -21 )+      {+        flags |= PS_HINT_FLAG_BOTTOM;+        pos   += len;+      }+      len = 0;+    }++    if ( aindex )+      *aindex = -1;++    /* now, lookup stem in the current hints table */+    {+      PS_Mask  mask;+      FT_UInt  idx;+      FT_UInt  max   = dim->hints.num_hints;+      PS_Hint  hint  = dim->hints.hints;+++      for ( idx = 0; idx < max; idx++, hint++ )+      {+        if ( hint->pos == pos && hint->len == len )+          break;+      }++      /* we need to create a new hint in the table */+      if ( idx >= max )+      {+        error = ps_hint_table_alloc( &dim->hints, memory, &hint );+        if ( error )+          goto Exit;++        hint->pos   = pos;+        hint->len   = len;+        hint->flags = flags;+      }++      /* now, store the hint in the current mask */+      error = ps_mask_table_last( &dim->masks, memory, &mask );+      if ( error )+        goto Exit;++      error = ps_mask_set_bit( mask, idx, memory );+      if ( error )+        goto Exit;++      if ( aindex )+        *aindex = (FT_Int)idx;+    }++  Exit:+    return error;+  }+++  /* add a "hstem3/vstem3" counter to our dimension table */+  static FT_Error+  ps_dimension_add_counter( PS_Dimension  dim,+                            FT_Int        hint1,+                            FT_Int        hint2,+                            FT_Int        hint3,+                            FT_Memory     memory )+  {+    FT_Error  error   = PSH_Err_Ok;+    FT_UInt   count   = dim->counters.num_masks;+    PS_Mask   counter = dim->counters.masks;+++    /* try to find an existing counter mask that already uses */+    /* one of these stems here                                */+    for ( ; count > 0; count--, counter++ )+    {+      if ( ps_mask_test_bit( counter, hint1 ) ||+           ps_mask_test_bit( counter, hint2 ) ||+           ps_mask_test_bit( counter, hint3 ) )+        break;+    }++    /* create a new counter when needed */+    if ( count == 0 )+    {+      error = ps_mask_table_alloc( &dim->counters, memory, &counter );+      if ( error )+        goto Exit;+    }++    /* now, set the bits for our hints in the counter mask */+    error = ps_mask_set_bit( counter, hint1, memory );+    if ( error )+      goto Exit;++    error = ps_mask_set_bit( counter, hint2, memory );+    if ( error )+      goto Exit;++    error = ps_mask_set_bit( counter, hint3, memory );+    if ( error )+      goto Exit;++  Exit:+    return error;+  }+++  /* end of recording session for a given dimension */+  static FT_Error+  ps_dimension_end( PS_Dimension  dim,+                    FT_UInt       end_point,+                    FT_Memory     memory )+  {+    /* end hint mask table */+    ps_dimension_end_mask( dim, end_point );++    /* merge all counter masks into independent "paths" */+    return ps_mask_table_merge_all( &dim->counters, memory );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    PS_RECORDER MANAGEMENT                     *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /* destroy hints */+  FT_LOCAL( void )+  ps_hints_done( PS_Hints  hints )+  {+    FT_Memory  memory = hints->memory;+++    ps_dimension_done( &hints->dimension[0], memory );+    ps_dimension_done( &hints->dimension[1], memory );++    hints->error  = PSH_Err_Ok;+    hints->memory = 0;+  }+++  FT_LOCAL( FT_Error )+  ps_hints_init( PS_Hints   hints,+                 FT_Memory  memory )+  {+    FT_MEM_ZERO( hints, sizeof ( *hints ) );+    hints->memory = memory;+    return PSH_Err_Ok;+  }+++  /* initialize a hints for a new session */+  static void+  ps_hints_open( PS_Hints      hints,+                 PS_Hint_Type  hint_type )+  {+    switch ( hint_type )+    {+    case PS_HINT_TYPE_1:+    case PS_HINT_TYPE_2:+      hints->error     = PSH_Err_Ok;+      hints->hint_type = hint_type;++      ps_dimension_init( &hints->dimension[0] );+      ps_dimension_init( &hints->dimension[1] );+      break;++    default:+      hints->error     = PSH_Err_Invalid_Argument;+      hints->hint_type = hint_type;++      FT_TRACE0(( "ps_hints_open: invalid charstring type\n" ));+      break;+    }+  }+++  /* add one or more stems to the current hints table */+  static void+  ps_hints_stem( PS_Hints  hints,+                 FT_Int    dimension,+                 FT_UInt   count,+                 FT_Long*  stems )+  {+    if ( !hints->error )+    {+      /* limit "dimension" to 0..1 */+      if ( dimension < 0 || dimension > 1 )+      {+        FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n",+                    dimension ));+        dimension = ( dimension != 0 );+      }++      /* record the stems in the current hints/masks table */+      switch ( hints->hint_type )+      {+      case PS_HINT_TYPE_1:  /* Type 1 "hstem" or "vstem" operator */+      case PS_HINT_TYPE_2:  /* Type 2 "hstem" or "vstem" operator */+        {+          PS_Dimension  dim = &hints->dimension[dimension];+++          for ( ; count > 0; count--, stems += 2 )+          {+            FT_Error   error;+            FT_Memory  memory = hints->memory;+++            error = ps_dimension_add_t1stem(+                      dim, (FT_Int)stems[0], (FT_Int)stems[1],+                      memory, NULL );+            if ( error )+            {+              FT_ERROR(( "ps_hints_stem: could not add stem"+                         " (%d,%d) to hints table\n", stems[0], stems[1] ));++              hints->error = error;+              return;+            }+          }+          break;+        }++      default:+        FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n",+                    hints->hint_type ));+        break;+      }+    }+  }+++  /* add one Type1 counter stem to the current hints table */+  static void+  ps_hints_t1stem3( PS_Hints   hints,+                    FT_Int     dimension,+                    FT_Fixed*  stems )+  {+    FT_Error  error = PSH_Err_Ok;+++    if ( !hints->error )+    {+      PS_Dimension  dim;+      FT_Memory     memory = hints->memory;+      FT_Int        count;+      FT_Int        idx[3];+++      /* limit "dimension" to 0..1 */+      if ( dimension < 0 || dimension > 1 )+      {+        FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n",+                    dimension ));+        dimension = ( dimension != 0 );+      }++      dim = &hints->dimension[dimension];++      /* there must be 6 elements in the 'stem' array */+      if ( hints->hint_type == PS_HINT_TYPE_1 )+      {+        /* add the three stems to our hints/masks table */+        for ( count = 0; count < 3; count++, stems += 2 )+        {+          error = ps_dimension_add_t1stem( dim,+                                           (FT_Int)FIXED_TO_INT( stems[0] ),+                                           (FT_Int)FIXED_TO_INT( stems[1] ),+                                           memory, &idx[count] );+          if ( error )+            goto Fail;+        }++        /* now, add the hints to the counters table */+        error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2],+                                          memory );+        if ( error )+          goto Fail;+      }+      else+      {+        FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" ));+        error = PSH_Err_Invalid_Argument;+        goto Fail;+      }+    }++    return;++  Fail:+    FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" ));+    hints->error = error;+  }+++  /* reset hints (only with Type 1 hints) */+  static void+  ps_hints_t1reset( PS_Hints  hints,+                    FT_UInt   end_point )+  {+    FT_Error  error = PSH_Err_Ok;+++    if ( !hints->error )+    {+      FT_Memory  memory = hints->memory;+++      if ( hints->hint_type == PS_HINT_TYPE_1 )+      {+        error = ps_dimension_reset_mask( &hints->dimension[0],+                                         end_point, memory );+        if ( error )+          goto Fail;++        error = ps_dimension_reset_mask( &hints->dimension[1],+                                         end_point, memory );+        if ( error )+          goto Fail;+      }+      else+      {+        /* invalid hint type */+        error = PSH_Err_Invalid_Argument;+        goto Fail;+      }+    }+    return;++  Fail:+    hints->error = error;+  }+++  /* Type2 "hintmask" operator, add a new hintmask to each direction */+  static void+  ps_hints_t2mask( PS_Hints        hints,+                   FT_UInt         end_point,+                   FT_UInt         bit_count,+                   const FT_Byte*  bytes )+  {+    FT_Error  error;+++    if ( !hints->error )+    {+      PS_Dimension  dim    = hints->dimension;+      FT_Memory     memory = hints->memory;+      FT_UInt       count1 = dim[0].hints.num_hints;+      FT_UInt       count2 = dim[1].hints.num_hints;+++      /* check bit count; must be equal to current total hint count */+      if ( bit_count !=  count1 + count2 )+      {+        FT_TRACE0(( "ps_hints_t2mask:"+                    " called with invalid bitcount %d (instead of %d)\n",+                   bit_count, count1 + count2 ));++        /* simply ignore the operator */+        return;+      }++      /* set-up new horizontal and vertical hint mask now */+      error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1,+                                          end_point, memory );+      if ( error )+        goto Fail;++      error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2,+                                          end_point, memory );+      if ( error )+        goto Fail;+    }+    return;++  Fail:+    hints->error = error;+  }+++  static void+  ps_hints_t2counter( PS_Hints        hints,+                      FT_UInt         bit_count,+                      const FT_Byte*  bytes )+  {+    FT_Error  error;+++    if ( !hints->error )+    {+      PS_Dimension  dim    = hints->dimension;+      FT_Memory     memory = hints->memory;+      FT_UInt       count1 = dim[0].hints.num_hints;+      FT_UInt       count2 = dim[1].hints.num_hints;+++      /* check bit count, must be equal to current total hint count */+      if ( bit_count !=  count1 + count2 )+      {+        FT_TRACE0(( "ps_hints_t2counter:"+                    " called with invalid bitcount %d (instead of %d)\n",+                   bit_count, count1 + count2 ));++        /* simply ignore the operator */+        return;+      }++      /* set-up new horizontal and vertical hint mask now */+      error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1,+                                          0, memory );+      if ( error )+        goto Fail;++      error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2,+                                          0, memory );+      if ( error )+        goto Fail;+    }+    return;++  Fail:+    hints->error = error;+  }+++  /* end recording session */+  static FT_Error+  ps_hints_close( PS_Hints  hints,+                  FT_UInt   end_point )+  {+    FT_Error  error;+++    error = hints->error;+    if ( !error )+    {+      FT_Memory     memory = hints->memory;+      PS_Dimension  dim    = hints->dimension;+++      error = ps_dimension_end( &dim[0], end_point, memory );+      if ( !error )+      {+        error = ps_dimension_end( &dim[1], end_point, memory );+      }+    }++#ifdef DEBUG_HINTER+    if ( !error )+      ps_debug_hints = hints;+#endif+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                TYPE 1 HINTS RECORDING INTERFACE               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  t1_hints_open( T1_Hints  hints )+  {+    ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 );+  }++  static void+  t1_hints_stem( T1_Hints   hints,+                 FT_Int     dimension,+                 FT_Fixed*  coords )+  {+    FT_Pos  stems[2];+++    stems[0] = FIXED_TO_INT( coords[0] );+    stems[1] = FIXED_TO_INT( coords[1] );++    ps_hints_stem( (PS_Hints)hints, dimension, 1, stems );+  }+++  FT_LOCAL_DEF( void )+  t1_hints_funcs_init( T1_Hints_FuncsRec*  funcs )+  {+    FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) );++    funcs->open  = (T1_Hints_OpenFunc)    t1_hints_open;+    funcs->close = (T1_Hints_CloseFunc)   ps_hints_close;+    funcs->stem  = (T1_Hints_SetStemFunc) t1_hints_stem;+    funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3;+    funcs->reset = (T1_Hints_ResetFunc)   ps_hints_t1reset;+    funcs->apply = (T1_Hints_ApplyFunc)   ps_hints_apply;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                TYPE 2 HINTS RECORDING INTERFACE               *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static void+  t2_hints_open( T2_Hints  hints )+  {+    ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 );+  }+++  static void+  t2_hints_stems( T2_Hints   hints,+                  FT_Int     dimension,+                  FT_Int     count,+                  FT_Fixed*  coords )+  {+    FT_Pos  stems[32], y, n;+    FT_Int  total = count;+++    y = 0;+    while ( total > 0 )+    {+      /* determine number of stems to write */+      count = total;+      if ( count > 16 )+        count = 16;++      /* compute integer stem positions in font units */+      for ( n = 0; n < count * 2; n++ )+      {+        y       += coords[n];+        stems[n] = FIXED_TO_INT( y );+      }++      /* compute lengths */+      for ( n = 0; n < count * 2; n += 2 )+        stems[n + 1] = stems[n + 1] - stems[n];++      /* add them to the current dimension */+      ps_hints_stem( (PS_Hints)hints, dimension, count, stems );++      total -= count;+    }+  }+++  FT_LOCAL_DEF( void )+  t2_hints_funcs_init( T2_Hints_FuncsRec*  funcs )+  {+    FT_MEM_ZERO( funcs, sizeof ( *funcs ) );++    funcs->open    = (T2_Hints_OpenFunc)   t2_hints_open;+    funcs->close   = (T2_Hints_CloseFunc)  ps_hints_close;+    funcs->stems   = (T2_Hints_StemsFunc)  t2_hints_stems;+    funcs->hintmask= (T2_Hints_MaskFunc)   ps_hints_t2mask;+    funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter;+    funcs->apply   = (T2_Hints_ApplyFunc)  ps_hints_apply;+  }+++/* END */
+ src/pshinter/pshrec.h view
@@ -0,0 +1,176 @@+/***************************************************************************/+/*                                                                         */+/*  pshrec.h                                                               */+/*                                                                         */+/*    Postscript (Type1/Type2) hints recorder (specification).             */+/*                                                                         */+/*  Copyright 2001, 2002, 2003, 2006, 2008 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /**************************************************************************/+  /*                                                                        */+  /*  The functions defined here are called from the Type 1, CID and CFF    */+  /*  font drivers to record the hints of a given character/glyph.          */+  /*                                                                        */+  /*  The hints are recorded in a unified format, and are later processed   */+  /*  by the `optimizer' and `fitter' to adjust the outlines to the pixel   */+  /*  grid.                                                                 */+  /*                                                                        */+  /**************************************************************************/+++#ifndef __PSHREC_H__+#define __PSHREC_H__+++#include <ft2build.h>+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+#include "pshglob.h"+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                 GLYPH HINTS RECORDER INTERNALS                *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /* handle to hint record */+  typedef struct PS_HintRec_*  PS_Hint;++  /* hint types */+  typedef enum  PS_Hint_Type_+  {+    PS_HINT_TYPE_1 = 1,+    PS_HINT_TYPE_2 = 2++  } PS_Hint_Type;+++  /* hint flags */+  typedef enum  PS_Hint_Flags_+  {+    PS_HINT_FLAG_GHOST  = 1,+    PS_HINT_FLAG_BOTTOM = 2++  } PS_Hint_Flags;+++  /* hint descriptor */+  typedef struct  PS_HintRec_+  {+    FT_Int   pos;+    FT_Int   len;+    FT_UInt  flags;++  } PS_HintRec;+++#define ps_hint_is_active( x )  ( (x)->flags & PS_HINT_FLAG_ACTIVE )+#define ps_hint_is_ghost( x )   ( (x)->flags & PS_HINT_FLAG_GHOST  )+#define ps_hint_is_bottom( x )  ( (x)->flags & PS_HINT_FLAG_BOTTOM )+++  /* hints table descriptor */+  typedef struct  PS_Hint_TableRec_+  {+    FT_UInt  num_hints;+    FT_UInt  max_hints;+    PS_Hint  hints;++  } PS_Hint_TableRec, *PS_Hint_Table;+++  /* hint and counter mask descriptor */+  typedef struct  PS_MaskRec_+  {+    FT_UInt   num_bits;+    FT_UInt   max_bits;+    FT_Byte*  bytes;+    FT_UInt   end_point;++  } PS_MaskRec, *PS_Mask;+++  /* masks and counters table descriptor */+  typedef struct  PS_Mask_TableRec_+  {+    FT_UInt  num_masks;+    FT_UInt  max_masks;+    PS_Mask  masks;++  } PS_Mask_TableRec, *PS_Mask_Table;+++ /* dimension-specific hints descriptor */+  typedef struct  PS_DimensionRec_+  {+    PS_Hint_TableRec  hints;+    PS_Mask_TableRec  masks;+    PS_Mask_TableRec  counters;++  } PS_DimensionRec, *PS_Dimension;+++  /* glyph hints descriptor                                */+  /* dimension 0 => X coordinates + vertical hints/stems   */+  /* dimension 1 => Y coordinates + horizontal hints/stems */+  typedef struct  PS_HintsRec_+  {+    FT_Memory        memory;+    FT_Error         error;+    FT_UInt32        magic;+    PS_Hint_Type     hint_type;+    PS_DimensionRec  dimension[2];++  } PS_HintsRec, *PS_Hints;++  /* */++  /* initialize hints recorder */+  FT_LOCAL( FT_Error )+  ps_hints_init( PS_Hints   hints,+                 FT_Memory  memory );++  /* finalize hints recorder */+  FT_LOCAL( void )+  ps_hints_done( PS_Hints  hints );++  /* initialize Type1 hints recorder interface */+  FT_LOCAL( void )+  t1_hints_funcs_init( T1_Hints_FuncsRec*  funcs );++  /* initialize Type2 hints recorder interface */+  FT_LOCAL( void )+  t2_hints_funcs_init( T2_Hints_FuncsRec*  funcs );+++#ifdef DEBUG_HINTER+  extern PS_Hints  ps_debug_hints;+  extern  int      ps_debug_no_horz_hints;+  extern  int      ps_debug_no_vert_hints;+#endif++ /* */+++FT_END_HEADER+++#endif /* __PS_HINTER_RECORD_H__ */+++/* END */
+ src/psnames/psmodule.c view
@@ -0,0 +1,597 @@+/***************************************************************************/+/*                                                                         */+/*  psmodule.c                                                             */+/*                                                                         */+/*    PSNames module implementation (body).                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H++#include "psmodule.h"+#include "pstables.h"++#include "psnamerr.h"+#include "pspic.h"+++#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES+++#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST+++#define VARIANT_BIT         0x80000000UL+#define BASE_GLYPH( code )  ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )+++  /* Return the Unicode value corresponding to a given glyph.  Note that */+  /* we do deal with glyph variants by detecting a non-initial dot in    */+  /* the name, as in `A.swash' or `e.final'; in this case, the           */+  /* VARIANT_BIT is set in the return value.                             */+  /*                                                                     */+  static FT_UInt32+  ps_unicode_value( const char*  glyph_name )+  {+    /* If the name begins with `uni', then the glyph name may be a */+    /* hard-coded unicode character code.                          */+    if ( glyph_name[0] == 'u' &&+         glyph_name[1] == 'n' &&+         glyph_name[2] == 'i' )+    {+      /* determine whether the next four characters following are */+      /* hexadecimal.                                             */++      /* XXX: Add code to deal with ligatures, i.e. glyph names like */+      /*      `uniXXXXYYYYZZZZ'...                                   */++      FT_Int       count;+      FT_UInt32    value = 0;+      const char*  p     = glyph_name + 3;+++      for ( count = 4; count > 0; count--, p++ )+      {+        char          c = *p;+        unsigned int  d;+++        d = (unsigned char)c - '0';+        if ( d >= 10 )+        {+          d = (unsigned char)c - 'A';+          if ( d >= 6 )+            d = 16;+          else+            d += 10;+        }++        /* Exit if a non-uppercase hexadecimal character was found   */+        /* -- this also catches character codes below `0' since such */+        /* negative numbers cast to `unsigned int' are far too big.  */+        if ( d >= 16 )+          break;++        value = ( value << 4 ) + d;+      }++      /* there must be exactly four hex digits */+      if ( count == 0 )+      {+        if ( *p == '\0' )+          return value;+        if ( *p == '.' )+          return (FT_UInt32)( value | VARIANT_BIT );+      }+    }++    /* If the name begins with `u', followed by four to six uppercase */+    /* hexadecimal digits, it is a hard-coded unicode character code. */+    if ( glyph_name[0] == 'u' )+    {+      FT_Int       count;+      FT_UInt32    value = 0;+      const char*  p     = glyph_name + 1;+++      for ( count = 6; count > 0; count--, p++ )+      {+        char          c = *p;+        unsigned int  d;+++        d = (unsigned char)c - '0';+        if ( d >= 10 )+        {+          d = (unsigned char)c - 'A';+          if ( d >= 6 )+            d = 16;+          else+            d += 10;+        }++        if ( d >= 16 )+          break;++        value = ( value << 4 ) + d;+      }++      if ( count <= 2 )+      {+        if ( *p == '\0' )+          return value;+        if ( *p == '.' )+          return (FT_UInt32)( value | VARIANT_BIT );+      }+    }++    /* Look for a non-initial dot in the glyph name in order to */+    /* find variants like `A.swash', `e.final', etc.            */+    {+      const char*  p   = glyph_name;+      const char*  dot = NULL;+++      for ( ; *p; p++ )+      {+        if ( *p == '.' && p > glyph_name )+        {+          dot = p;+          break;+        }+      }++      /* now look up the glyph in the Adobe Glyph List */+      if ( !dot )+        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );+      else+        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |+                            VARIANT_BIT );+    }+  }+++  /* ft_qsort callback to sort the unicode map */+  FT_CALLBACK_DEF( int )+  compare_uni_maps( const void*  a,+                    const void*  b )+  {+    PS_UniMap*  map1 = (PS_UniMap*)a;+    PS_UniMap*  map2 = (PS_UniMap*)b;+    FT_UInt32   unicode1 = BASE_GLYPH( map1->unicode );+    FT_UInt32   unicode2 = BASE_GLYPH( map2->unicode );+++    /* sort base glyphs before glyph variants */+    if ( unicode1 == unicode2 )+    {+      if ( map1->unicode > map2->unicode )+        return 1;+      else if ( map1->unicode < map2->unicode )+        return -1;+      else+        return 0;+    }+    else+    {+      if ( unicode1 > unicode2 )+        return 1;+      else if ( unicode1 < unicode2 )+        return -1;+      else+        return 0;+    }+  }+++  /* support for extra glyphs not handled (well) in AGL; */+  /* we add extra mappings for them if necessary         */++#define EXTRA_GLYPH_LIST_SIZE  10++  static const FT_UInt32  ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =+  {+    /* WGL 4 */+    0x0394,+    0x03A9,+    0x2215,+    0x00AD,+    0x02C9,+    0x03BC,+    0x2219,+    0x00A0,+    /* Romanian */+    0x021A,+    0x021B+  };++  static const char  ft_extra_glyph_names[] =+  {+    'D','e','l','t','a',0,+    'O','m','e','g','a',0,+    'f','r','a','c','t','i','o','n',0,+    'h','y','p','h','e','n',0,+    'm','a','c','r','o','n',0,+    'm','u',0,+    'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,+    's','p','a','c','e',0,+    'T','c','o','m','m','a','a','c','c','e','n','t',0,+    't','c','o','m','m','a','a','c','c','e','n','t',0+  };++  static const FT_Int+  ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =+  {+     0,+     6,+    12,+    21,+    28,+    35,+    38,+    53,+    59,+    72+  };+++  static void+  ps_check_extra_glyph_name( const char*  gname,+                             FT_UInt      glyph,+                             FT_UInt*     extra_glyphs,+                             FT_UInt     *states )+  {+    FT_UInt  n;+++    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )+    {+      if ( ft_strcmp( ft_extra_glyph_names ++                        ft_extra_glyph_name_offsets[n], gname ) == 0 )+      {+        if ( states[n] == 0 )+        {+          /* mark this extra glyph as a candidate for the cmap */+          states[n]     = 1;+          extra_glyphs[n] = glyph;+        }++        return;+      }+    }+  }+++  static void+  ps_check_extra_glyph_unicode( FT_UInt32  uni_char,+                                FT_UInt   *states )+  {+    FT_UInt  n;+++    for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )+    {+      if ( uni_char == ft_extra_glyph_unicodes[n] )+      {+        /* disable this extra glyph from being added to the cmap */+        states[n] = 2;++        return;+      }+    }+  }+++  /* Build a table that maps Unicode values to glyph indices. */+  static FT_Error+  ps_unicodes_init( FT_Memory             memory,+                    PS_Unicodes           table,+                    FT_UInt               num_glyphs,+                    PS_GetGlyphNameFunc   get_glyph_name,+                    PS_FreeGlyphNameFunc  free_glyph_name,+                    FT_Pointer            glyph_data )+  {+    FT_Error  error;++    FT_UInt  extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };+    FT_UInt  extra_glyphs[EXTRA_GLYPH_LIST_SIZE];+++    /* we first allocate the table */+    table->num_maps = 0;+    table->maps     = 0;++    if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )+    {+      FT_UInt     n;+      FT_UInt     count;+      PS_UniMap*  map;+      FT_UInt32   uni_char;+++      map = table->maps;++      for ( n = 0; n < num_glyphs; n++ )+      {+        const char*  gname = get_glyph_name( glyph_data, n );+++        if ( gname )+        {+          ps_check_extra_glyph_name( gname, n,+                                     extra_glyphs, extra_glyph_list_states );+          uni_char = ps_unicode_value( gname );++          if ( BASE_GLYPH( uni_char ) != 0 )+          {+            ps_check_extra_glyph_unicode( uni_char,+                                          extra_glyph_list_states );+            map->unicode     = uni_char;+            map->glyph_index = n;+            map++;+          }++          if ( free_glyph_name )+            free_glyph_name( glyph_data, gname );+        }+      }++      for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )+      {+        if ( extra_glyph_list_states[n] == 1 )+        {+          /* This glyph name has an additional representation. */+          /* Add it to the cmap.                               */++          map->unicode     = ft_extra_glyph_unicodes[n];+          map->glyph_index = extra_glyphs[n];+          map++;+        }+      }++      /* now compress the table a bit */+      count = (FT_UInt)( map - table->maps );++      if ( count == 0 )+      {+        /* No unicode chars here! */+        FT_FREE( table->maps );+        if ( !error )+          error = PSnames_Err_No_Unicode_Glyph_Name;+      }+      else+      {+        /* Reallocate if the number of used entries is much smaller. */+        if ( count < num_glyphs / 2 )+        {+          (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );+          error = PSnames_Err_Ok;+        }++        /* Sort the table in increasing order of unicode values, */+        /* taking care of glyph variants.                        */+        ft_qsort( table->maps, count, sizeof ( PS_UniMap ),+                  compare_uni_maps );+      }++      table->num_maps = count;+    }++    return error;+  }+++  static FT_UInt+  ps_unicodes_char_index( PS_Unicodes  table,+                          FT_UInt32    unicode )+  {+    PS_UniMap  *min, *max, *mid, *result = NULL;+++    /* Perform a binary search on the table. */++    min = table->maps;+    max = min + table->num_maps - 1;++    while ( min <= max )+    {+      FT_UInt32  base_glyph;+++      mid = min + ( ( max - min ) >> 1 );++      if ( mid->unicode == unicode )+      {+        result = mid;+        break;+      }++      base_glyph = BASE_GLYPH( mid->unicode );++      if ( base_glyph == unicode )+        result = mid; /* remember match but continue search for base glyph */++      if ( min == max )+        break;++      if ( base_glyph < unicode )+        min = mid + 1;+      else+        max = mid - 1;+    }++    if ( result )+      return result->glyph_index;+    else+      return 0;+  }+++  static FT_UInt32+  ps_unicodes_char_next( PS_Unicodes  table,+                         FT_UInt32   *unicode )+  {+    FT_UInt    result    = 0;+    FT_UInt32  char_code = *unicode + 1;+++    {+      FT_UInt     min = 0;+      FT_UInt     max = table->num_maps;+      FT_UInt     mid;+      PS_UniMap*  map;+      FT_UInt32   base_glyph;+++      while ( min < max )+      {+        mid = min + ( ( max - min ) >> 1 );+        map = table->maps + mid;++        if ( map->unicode == char_code )+        {+          result = map->glyph_index;+          goto Exit;+        }++        base_glyph = BASE_GLYPH( map->unicode );++        if ( base_glyph == char_code )+          result = map->glyph_index;++        if ( base_glyph < char_code )+          min = mid + 1;+        else+          max = mid;+      }++      if ( result )+        goto Exit;               /* we have a variant glyph */++      /* we didn't find it; check whether we have a map just above it */+      char_code = 0;++      if ( min < table->num_maps )+      {+        map       = table->maps + min;+        result    = map->glyph_index;+        char_code = BASE_GLYPH( map->unicode );+      }+    }++  Exit:+    *unicode = char_code;+    return result;+  }+++#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */+++  static const char*+  ps_get_macintosh_name( FT_UInt  name_index )+  {+    if ( name_index >= FT_NUM_MAC_NAMES )+      name_index = 0;++    return ft_standard_glyph_names + ft_mac_names[name_index];+  }+++  static const char*+  ps_get_standard_strings( FT_UInt  sid )+  {+    if ( sid >= FT_NUM_SID_NAMES )+      return 0;++    return ft_standard_glyph_names + ft_sid_names[sid];+  }+++#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST+  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, +    (PS_Unicode_ValueFunc)     ps_unicode_value,+    (PS_Unicodes_InitFunc)     ps_unicodes_init,+    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,+    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,++    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,+    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,++    t1_standard_encoding,+    t1_expert_encoding+  )++#else++  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, +    0,+    0,+    0,+    0,++    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,+    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,++    t1_standard_encoding,+    t1_expert_encoding+  )++#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */+++  FT_DEFINE_SERVICEDESCREC1(pscmaps_services, +    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET+  )+++++  static FT_Pointer+  psnames_get_service( FT_Module    module,+                       const char*  service_id )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );+  }++#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */+++#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES+#define PUT_PS_NAMES_SERVICE(a) 0+#else+#define PUT_PS_NAMES_SERVICE(a) a+#endif++  FT_DEFINE_MODULE(psnames_module_class,+  +    0,  /* this is not a font driver, nor a renderer */+    sizeof ( FT_ModuleRec ),++    "psnames",  /* driver name                         */+    0x10000L,   /* driver version                      */+    0x20000L,   /* driver requires FreeType 2 or above */++    PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET),   /* module specific interface */+    (FT_Module_Constructor)0,+    (FT_Module_Destructor) 0,+    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE(psnames_get_service)+  )++++/* END */
+ src/psnames/psmodule.h view
@@ -0,0 +1,38 @@+/***************************************************************************/+/*                                                                         */+/*  psmodule.h                                                             */+/*                                                                         */+/*    High-level PSNames module interface (specification).                 */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSMODULE_H__+#define __PSMODULE_H__+++#include <ft2build.h>+#include FT_MODULE_H+++FT_BEGIN_HEADER+++  FT_DECLARE_MODULE( psnames_module_class )+++FT_END_HEADER++#endif /* __PSMODULE_H__ */+++/* END */
+ src/psnames/psnamerr.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  psnamerr.h                                                             */+/*                                                                         */+/*    PS names module error codes (specification only).                    */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the PS names module error enumeration     */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __PSNAMERR_H__+#define __PSNAMERR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  PSnames_Err_+#define FT_ERR_BASE    FT_Mod_Err_PSnames++#include FT_ERRORS_H++#endif /* __PSNAMERR_H__ */+++/* END */
+ src/psnames/psnames.c view
@@ -0,0 +1,26 @@+/***************************************************************************/+/*                                                                         */+/*  psnames.c                                                              */+/*                                                                         */+/*    FreeType PSNames module component (body only).                       */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "pspic.c"+#include "psmodule.c"+++/* END */
+ src/psnames/pspic.c view
@@ -0,0 +1,79 @@+/***************************************************************************/+/*                                                                         */+/*  pspic.c                                                                */+/*                                                                         */+/*    The FreeType position independent code services for psnames module.  */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "pspic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from psmodule.c */+  FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**);+  void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*);+  void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*);++  void+  psnames_module_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->psnames )+    {+      PSModulePIC* container = (PSModulePIC*)pic_container->psnames;+      if(container->pscmaps_services)+        FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services);+      container->pscmaps_services = NULL;+      FT_FREE( container );+      pic_container->psnames = NULL;+    }+  }+++  FT_Error+  psnames_module_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error         = PSnames_Err_Ok;+    PSModulePIC*       container;+    FT_Memory          memory        = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof(*container) );+    pic_container->psnames = container;++    /* initialize pointer table - this is how the module usually expects this data */+    error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services);+    if(error) +      goto Exit;+    FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface);+    +Exit:+    if(error)+      psnames_module_class_pic_free(library);+    return error;+  }+++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/psnames/pspic.h view
@@ -0,0 +1,54 @@+/***************************************************************************/+/*                                                                         */+/*  pspic.h                                                                */+/*                                                                         */+/*    The FreeType position independent code services for psnames module.  */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __PSPIC_H__+#define __PSPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC+#define FT_PSCMAPS_SERVICES_GET     pscmaps_services+#define FT_PSCMAPS_INTERFACE_GET    pscmaps_interface++#else /* FT_CONFIG_OPTION_PIC */++#include FT_SERVICE_POSTSCRIPT_CMAPS_H++  typedef struct PSModulePIC_+  {+    FT_ServiceDescRec* pscmaps_services;+    FT_Service_PsCMapsRec pscmaps_interface;+  } PSModulePIC;++#define GET_PIC(lib)                ((PSModulePIC*)((lib)->pic_container.psnames))+#define FT_PSCMAPS_SERVICES_GET     (GET_PIC(library)->pscmaps_services)+#define FT_PSCMAPS_INTERFACE_GET    (GET_PIC(library)->pscmaps_interface)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __PSPIC_H__ */+++/* END */
+ src/psnames/pstables.h view
@@ -0,0 +1,4095 @@+/***************************************************************************/+/*                                                                         */+/*  pstables.h                                                             */+/*                                                                         */+/*    PostScript glyph names.                                              */+/*                                                                         */+/*  Copyright 2005, 2008 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /* This file has been generated automatically -- do not edit! */+++  static const char  ft_standard_glyph_names[3696] =+  {+    '.','n','u','l','l', 0,+    'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0,+    'n','o','t','e','q','u','a','l', 0,+    'i','n','f','i','n','i','t','y', 0,+    'l','e','s','s','e','q','u','a','l', 0,+    'g','r','e','a','t','e','r','e','q','u','a','l', 0,+    'p','a','r','t','i','a','l','d','i','f','f', 0,+    's','u','m','m','a','t','i','o','n', 0,+    'p','r','o','d','u','c','t', 0,+    'p','i', 0,+    'i','n','t','e','g','r','a','l', 0,+    'O','m','e','g','a', 0,+    'r','a','d','i','c','a','l', 0,+    'a','p','p','r','o','x','e','q','u','a','l', 0,+    'D','e','l','t','a', 0,+    'n','o','n','b','r','e','a','k','i','n','g','s','p','a','c','e', 0,+    'l','o','z','e','n','g','e', 0,+    'a','p','p','l','e', 0,+    'f','r','a','n','c', 0,+    'G','b','r','e','v','e', 0,+    'g','b','r','e','v','e', 0,+    'I','d','o','t','a','c','c','e','n','t', 0,+    'S','c','e','d','i','l','l','a', 0,+    's','c','e','d','i','l','l','a', 0,+    'C','a','c','u','t','e', 0,+    'c','a','c','u','t','e', 0,+    'C','c','a','r','o','n', 0,+    'c','c','a','r','o','n', 0,+    'd','c','r','o','a','t', 0,+    '.','n','o','t','d','e','f', 0,+    's','p','a','c','e', 0,+    'e','x','c','l','a','m', 0,+    'q','u','o','t','e','d','b','l', 0,+    'n','u','m','b','e','r','s','i','g','n', 0,+    'd','o','l','l','a','r', 0,+    'p','e','r','c','e','n','t', 0,+    'a','m','p','e','r','s','a','n','d', 0,+    'q','u','o','t','e','r','i','g','h','t', 0,+    'p','a','r','e','n','l','e','f','t', 0,+    'p','a','r','e','n','r','i','g','h','t', 0,+    'a','s','t','e','r','i','s','k', 0,+    'p','l','u','s', 0,+    'c','o','m','m','a', 0,+    'h','y','p','h','e','n', 0,+    'p','e','r','i','o','d', 0,+    's','l','a','s','h', 0,+    'z','e','r','o', 0,+    'o','n','e', 0,+    't','w','o', 0,+    't','h','r','e','e', 0,+    'f','o','u','r', 0,+    'f','i','v','e', 0,+    's','i','x', 0,+    's','e','v','e','n', 0,+    'e','i','g','h','t', 0,+    'n','i','n','e', 0,+    'c','o','l','o','n', 0,+    's','e','m','i','c','o','l','o','n', 0,+    'l','e','s','s', 0,+    'e','q','u','a','l', 0,+    'g','r','e','a','t','e','r', 0,+    'q','u','e','s','t','i','o','n', 0,+    'a','t', 0,+    'A', 0,+    'B', 0,+    'C', 0,+    'D', 0,+    'E', 0,+    'F', 0,+    'G', 0,+    'H', 0,+    'I', 0,+    'J', 0,+    'K', 0,+    'L', 0,+    'M', 0,+    'N', 0,+    'O', 0,+    'P', 0,+    'Q', 0,+    'R', 0,+    'S', 0,+    'T', 0,+    'U', 0,+    'V', 0,+    'W', 0,+    'X', 0,+    'Y', 0,+    'Z', 0,+    'b','r','a','c','k','e','t','l','e','f','t', 0,+    'b','a','c','k','s','l','a','s','h', 0,+    'b','r','a','c','k','e','t','r','i','g','h','t', 0,+    'a','s','c','i','i','c','i','r','c','u','m', 0,+    'u','n','d','e','r','s','c','o','r','e', 0,+    'q','u','o','t','e','l','e','f','t', 0,+    'a', 0,+    'b', 0,+    'c', 0,+    'd', 0,+    'e', 0,+    'f', 0,+    'g', 0,+    'h', 0,+    'i', 0,+    'j', 0,+    'k', 0,+    'l', 0,+    'm', 0,+    'n', 0,+    'o', 0,+    'p', 0,+    'q', 0,+    'r', 0,+    's', 0,+    't', 0,+    'u', 0,+    'v', 0,+    'w', 0,+    'x', 0,+    'y', 0,+    'z', 0,+    'b','r','a','c','e','l','e','f','t', 0,+    'b','a','r', 0,+    'b','r','a','c','e','r','i','g','h','t', 0,+    'a','s','c','i','i','t','i','l','d','e', 0,+    'e','x','c','l','a','m','d','o','w','n', 0,+    'c','e','n','t', 0,+    's','t','e','r','l','i','n','g', 0,+    'f','r','a','c','t','i','o','n', 0,+    'y','e','n', 0,+    'f','l','o','r','i','n', 0,+    's','e','c','t','i','o','n', 0,+    'c','u','r','r','e','n','c','y', 0,+    'q','u','o','t','e','s','i','n','g','l','e', 0,+    'q','u','o','t','e','d','b','l','l','e','f','t', 0,+    'g','u','i','l','l','e','m','o','t','l','e','f','t', 0,+    'g','u','i','l','s','i','n','g','l','l','e','f','t', 0,+    'g','u','i','l','s','i','n','g','l','r','i','g','h','t', 0,+    'f','i', 0,+    'f','l', 0,+    'e','n','d','a','s','h', 0,+    'd','a','g','g','e','r', 0,+    'd','a','g','g','e','r','d','b','l', 0,+    'p','e','r','i','o','d','c','e','n','t','e','r','e','d', 0,+    'p','a','r','a','g','r','a','p','h', 0,+    'b','u','l','l','e','t', 0,+    'q','u','o','t','e','s','i','n','g','l','b','a','s','e', 0,+    'q','u','o','t','e','d','b','l','b','a','s','e', 0,+    'q','u','o','t','e','d','b','l','r','i','g','h','t', 0,+    'g','u','i','l','l','e','m','o','t','r','i','g','h','t', 0,+    'e','l','l','i','p','s','i','s', 0,+    'p','e','r','t','h','o','u','s','a','n','d', 0,+    'q','u','e','s','t','i','o','n','d','o','w','n', 0,+    'g','r','a','v','e', 0,+    'a','c','u','t','e', 0,+    'c','i','r','c','u','m','f','l','e','x', 0,+    't','i','l','d','e', 0,+    'm','a','c','r','o','n', 0,+    'b','r','e','v','e', 0,+    'd','o','t','a','c','c','e','n','t', 0,+    'd','i','e','r','e','s','i','s', 0,+    'r','i','n','g', 0,+    'c','e','d','i','l','l','a', 0,+    'h','u','n','g','a','r','u','m','l','a','u','t', 0,+    'o','g','o','n','e','k', 0,+    'c','a','r','o','n', 0,+    'e','m','d','a','s','h', 0,+    'A','E', 0,+    'o','r','d','f','e','m','i','n','i','n','e', 0,+    'L','s','l','a','s','h', 0,+    'O','s','l','a','s','h', 0,+    'O','E', 0,+    'o','r','d','m','a','s','c','u','l','i','n','e', 0,+    'a','e', 0,+    'd','o','t','l','e','s','s','i', 0,+    'l','s','l','a','s','h', 0,+    'o','s','l','a','s','h', 0,+    'o','e', 0,+    'g','e','r','m','a','n','d','b','l','s', 0,+    'o','n','e','s','u','p','e','r','i','o','r', 0,+    'l','o','g','i','c','a','l','n','o','t', 0,+    'm','u', 0,+    't','r','a','d','e','m','a','r','k', 0,+    'E','t','h', 0,+    'o','n','e','h','a','l','f', 0,+    'p','l','u','s','m','i','n','u','s', 0,+    'T','h','o','r','n', 0,+    'o','n','e','q','u','a','r','t','e','r', 0,+    'd','i','v','i','d','e', 0,+    'b','r','o','k','e','n','b','a','r', 0,+    'd','e','g','r','e','e', 0,+    't','h','o','r','n', 0,+    't','h','r','e','e','q','u','a','r','t','e','r','s', 0,+    't','w','o','s','u','p','e','r','i','o','r', 0,+    'r','e','g','i','s','t','e','r','e','d', 0,+    'm','i','n','u','s', 0,+    'e','t','h', 0,+    'm','u','l','t','i','p','l','y', 0,+    't','h','r','e','e','s','u','p','e','r','i','o','r', 0,+    'c','o','p','y','r','i','g','h','t', 0,+    'A','a','c','u','t','e', 0,+    'A','c','i','r','c','u','m','f','l','e','x', 0,+    'A','d','i','e','r','e','s','i','s', 0,+    'A','g','r','a','v','e', 0,+    'A','r','i','n','g', 0,+    'A','t','i','l','d','e', 0,+    'C','c','e','d','i','l','l','a', 0,+    'E','a','c','u','t','e', 0,+    'E','c','i','r','c','u','m','f','l','e','x', 0,+    'E','d','i','e','r','e','s','i','s', 0,+    'E','g','r','a','v','e', 0,+    'I','a','c','u','t','e', 0,+    'I','c','i','r','c','u','m','f','l','e','x', 0,+    'I','d','i','e','r','e','s','i','s', 0,+    'I','g','r','a','v','e', 0,+    'N','t','i','l','d','e', 0,+    'O','a','c','u','t','e', 0,+    'O','c','i','r','c','u','m','f','l','e','x', 0,+    'O','d','i','e','r','e','s','i','s', 0,+    'O','g','r','a','v','e', 0,+    'O','t','i','l','d','e', 0,+    'S','c','a','r','o','n', 0,+    'U','a','c','u','t','e', 0,+    'U','c','i','r','c','u','m','f','l','e','x', 0,+    'U','d','i','e','r','e','s','i','s', 0,+    'U','g','r','a','v','e', 0,+    'Y','a','c','u','t','e', 0,+    'Y','d','i','e','r','e','s','i','s', 0,+    'Z','c','a','r','o','n', 0,+    'a','a','c','u','t','e', 0,+    'a','c','i','r','c','u','m','f','l','e','x', 0,+    'a','d','i','e','r','e','s','i','s', 0,+    'a','g','r','a','v','e', 0,+    'a','r','i','n','g', 0,+    'a','t','i','l','d','e', 0,+    'c','c','e','d','i','l','l','a', 0,+    'e','a','c','u','t','e', 0,+    'e','c','i','r','c','u','m','f','l','e','x', 0,+    'e','d','i','e','r','e','s','i','s', 0,+    'e','g','r','a','v','e', 0,+    'i','a','c','u','t','e', 0,+    'i','c','i','r','c','u','m','f','l','e','x', 0,+    'i','d','i','e','r','e','s','i','s', 0,+    'i','g','r','a','v','e', 0,+    'n','t','i','l','d','e', 0,+    'o','a','c','u','t','e', 0,+    'o','c','i','r','c','u','m','f','l','e','x', 0,+    'o','d','i','e','r','e','s','i','s', 0,+    'o','g','r','a','v','e', 0,+    'o','t','i','l','d','e', 0,+    's','c','a','r','o','n', 0,+    'u','a','c','u','t','e', 0,+    'u','c','i','r','c','u','m','f','l','e','x', 0,+    'u','d','i','e','r','e','s','i','s', 0,+    'u','g','r','a','v','e', 0,+    'y','a','c','u','t','e', 0,+    'y','d','i','e','r','e','s','i','s', 0,+    'z','c','a','r','o','n', 0,+    'e','x','c','l','a','m','s','m','a','l','l', 0,+    'H','u','n','g','a','r','u','m','l','a','u','t','s','m','a','l','l', 0,+    'd','o','l','l','a','r','o','l','d','s','t','y','l','e', 0,+    'd','o','l','l','a','r','s','u','p','e','r','i','o','r', 0,+    'a','m','p','e','r','s','a','n','d','s','m','a','l','l', 0,+    'A','c','u','t','e','s','m','a','l','l', 0,+    'p','a','r','e','n','l','e','f','t','s','u','p','e','r','i','o','r', 0,+    'p','a','r','e','n','r','i','g','h','t','s','u','p','e','r','i','o','r', 0,+    't','w','o','d','o','t','e','n','l','e','a','d','e','r', 0,+    'o','n','e','d','o','t','e','n','l','e','a','d','e','r', 0,+    'z','e','r','o','o','l','d','s','t','y','l','e', 0,+    'o','n','e','o','l','d','s','t','y','l','e', 0,+    't','w','o','o','l','d','s','t','y','l','e', 0,+    't','h','r','e','e','o','l','d','s','t','y','l','e', 0,+    'f','o','u','r','o','l','d','s','t','y','l','e', 0,+    'f','i','v','e','o','l','d','s','t','y','l','e', 0,+    's','i','x','o','l','d','s','t','y','l','e', 0,+    's','e','v','e','n','o','l','d','s','t','y','l','e', 0,+    'e','i','g','h','t','o','l','d','s','t','y','l','e', 0,+    'n','i','n','e','o','l','d','s','t','y','l','e', 0,+    'c','o','m','m','a','s','u','p','e','r','i','o','r', 0,+    't','h','r','e','e','q','u','a','r','t','e','r','s','e','m','d','a','s','h', 0,+    'p','e','r','i','o','d','s','u','p','e','r','i','o','r', 0,+    'q','u','e','s','t','i','o','n','s','m','a','l','l', 0,+    'a','s','u','p','e','r','i','o','r', 0,+    'b','s','u','p','e','r','i','o','r', 0,+    'c','e','n','t','s','u','p','e','r','i','o','r', 0,+    'd','s','u','p','e','r','i','o','r', 0,+    'e','s','u','p','e','r','i','o','r', 0,+    'i','s','u','p','e','r','i','o','r', 0,+    'l','s','u','p','e','r','i','o','r', 0,+    'm','s','u','p','e','r','i','o','r', 0,+    'n','s','u','p','e','r','i','o','r', 0,+    'o','s','u','p','e','r','i','o','r', 0,+    'r','s','u','p','e','r','i','o','r', 0,+    's','s','u','p','e','r','i','o','r', 0,+    't','s','u','p','e','r','i','o','r', 0,+    'f','f', 0,+    'f','f','i', 0,+    'f','f','l', 0,+    'p','a','r','e','n','l','e','f','t','i','n','f','e','r','i','o','r', 0,+    'p','a','r','e','n','r','i','g','h','t','i','n','f','e','r','i','o','r', 0,+    'C','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'h','y','p','h','e','n','s','u','p','e','r','i','o','r', 0,+    'G','r','a','v','e','s','m','a','l','l', 0,+    'A','s','m','a','l','l', 0,+    'B','s','m','a','l','l', 0,+    'C','s','m','a','l','l', 0,+    'D','s','m','a','l','l', 0,+    'E','s','m','a','l','l', 0,+    'F','s','m','a','l','l', 0,+    'G','s','m','a','l','l', 0,+    'H','s','m','a','l','l', 0,+    'I','s','m','a','l','l', 0,+    'J','s','m','a','l','l', 0,+    'K','s','m','a','l','l', 0,+    'L','s','m','a','l','l', 0,+    'M','s','m','a','l','l', 0,+    'N','s','m','a','l','l', 0,+    'O','s','m','a','l','l', 0,+    'P','s','m','a','l','l', 0,+    'Q','s','m','a','l','l', 0,+    'R','s','m','a','l','l', 0,+    'S','s','m','a','l','l', 0,+    'T','s','m','a','l','l', 0,+    'U','s','m','a','l','l', 0,+    'V','s','m','a','l','l', 0,+    'W','s','m','a','l','l', 0,+    'X','s','m','a','l','l', 0,+    'Y','s','m','a','l','l', 0,+    'Z','s','m','a','l','l', 0,+    'c','o','l','o','n','m','o','n','e','t','a','r','y', 0,+    'o','n','e','f','i','t','t','e','d', 0,+    'r','u','p','i','a','h', 0,+    'T','i','l','d','e','s','m','a','l','l', 0,+    'e','x','c','l','a','m','d','o','w','n','s','m','a','l','l', 0,+    'c','e','n','t','o','l','d','s','t','y','l','e', 0,+    'L','s','l','a','s','h','s','m','a','l','l', 0,+    'S','c','a','r','o','n','s','m','a','l','l', 0,+    'Z','c','a','r','o','n','s','m','a','l','l', 0,+    'D','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'B','r','e','v','e','s','m','a','l','l', 0,+    'C','a','r','o','n','s','m','a','l','l', 0,+    'D','o','t','a','c','c','e','n','t','s','m','a','l','l', 0,+    'M','a','c','r','o','n','s','m','a','l','l', 0,+    'f','i','g','u','r','e','d','a','s','h', 0,+    'h','y','p','h','e','n','i','n','f','e','r','i','o','r', 0,+    'O','g','o','n','e','k','s','m','a','l','l', 0,+    'R','i','n','g','s','m','a','l','l', 0,+    'C','e','d','i','l','l','a','s','m','a','l','l', 0,+    'q','u','e','s','t','i','o','n','d','o','w','n','s','m','a','l','l', 0,+    'o','n','e','e','i','g','h','t','h', 0,+    't','h','r','e','e','e','i','g','h','t','h','s', 0,+    'f','i','v','e','e','i','g','h','t','h','s', 0,+    's','e','v','e','n','e','i','g','h','t','h','s', 0,+    'o','n','e','t','h','i','r','d', 0,+    't','w','o','t','h','i','r','d','s', 0,+    'z','e','r','o','s','u','p','e','r','i','o','r', 0,+    'f','o','u','r','s','u','p','e','r','i','o','r', 0,+    'f','i','v','e','s','u','p','e','r','i','o','r', 0,+    's','i','x','s','u','p','e','r','i','o','r', 0,+    's','e','v','e','n','s','u','p','e','r','i','o','r', 0,+    'e','i','g','h','t','s','u','p','e','r','i','o','r', 0,+    'n','i','n','e','s','u','p','e','r','i','o','r', 0,+    'z','e','r','o','i','n','f','e','r','i','o','r', 0,+    'o','n','e','i','n','f','e','r','i','o','r', 0,+    't','w','o','i','n','f','e','r','i','o','r', 0,+    't','h','r','e','e','i','n','f','e','r','i','o','r', 0,+    'f','o','u','r','i','n','f','e','r','i','o','r', 0,+    'f','i','v','e','i','n','f','e','r','i','o','r', 0,+    's','i','x','i','n','f','e','r','i','o','r', 0,+    's','e','v','e','n','i','n','f','e','r','i','o','r', 0,+    'e','i','g','h','t','i','n','f','e','r','i','o','r', 0,+    'n','i','n','e','i','n','f','e','r','i','o','r', 0,+    'c','e','n','t','i','n','f','e','r','i','o','r', 0,+    'd','o','l','l','a','r','i','n','f','e','r','i','o','r', 0,+    'p','e','r','i','o','d','i','n','f','e','r','i','o','r', 0,+    'c','o','m','m','a','i','n','f','e','r','i','o','r', 0,+    'A','g','r','a','v','e','s','m','a','l','l', 0,+    'A','a','c','u','t','e','s','m','a','l','l', 0,+    'A','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'A','t','i','l','d','e','s','m','a','l','l', 0,+    'A','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'A','r','i','n','g','s','m','a','l','l', 0,+    'A','E','s','m','a','l','l', 0,+    'C','c','e','d','i','l','l','a','s','m','a','l','l', 0,+    'E','g','r','a','v','e','s','m','a','l','l', 0,+    'E','a','c','u','t','e','s','m','a','l','l', 0,+    'E','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'E','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'I','g','r','a','v','e','s','m','a','l','l', 0,+    'I','a','c','u','t','e','s','m','a','l','l', 0,+    'I','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'I','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'E','t','h','s','m','a','l','l', 0,+    'N','t','i','l','d','e','s','m','a','l','l', 0,+    'O','g','r','a','v','e','s','m','a','l','l', 0,+    'O','a','c','u','t','e','s','m','a','l','l', 0,+    'O','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'O','t','i','l','d','e','s','m','a','l','l', 0,+    'O','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'O','E','s','m','a','l','l', 0,+    'O','s','l','a','s','h','s','m','a','l','l', 0,+    'U','g','r','a','v','e','s','m','a','l','l', 0,+    'U','a','c','u','t','e','s','m','a','l','l', 0,+    'U','c','i','r','c','u','m','f','l','e','x','s','m','a','l','l', 0,+    'U','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    'Y','a','c','u','t','e','s','m','a','l','l', 0,+    'T','h','o','r','n','s','m','a','l','l', 0,+    'Y','d','i','e','r','e','s','i','s','s','m','a','l','l', 0,+    '0','0','1','.','0','0','0', 0,+    '0','0','1','.','0','0','1', 0,+    '0','0','1','.','0','0','2', 0,+    '0','0','1','.','0','0','3', 0,+    'B','l','a','c','k', 0,+    'B','o','l','d', 0,+    'B','o','o','k', 0,+    'L','i','g','h','t', 0,+    'M','e','d','i','u','m', 0,+    'R','e','g','u','l','a','r', 0,+    'R','o','m','a','n', 0,+    'S','e','m','i','b','o','l','d', 0,+  };+++#define FT_NUM_MAC_NAMES  258++  /* Values are offsets into the `ft_standard_glyph_names' table */++  static const short  ft_mac_names[FT_NUM_MAC_NAMES] =+  {+     253,   0,   6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351,+     360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430,+     436, 441, 447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498,+     500, 502, 504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526,+     528, 530, 532, 534, 536, 538, 540, 552, 562, 575, 587, 979, 608, 610,+     612, 614, 616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638,+     640, 642, 644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685,+    1375,1392,1405,1414,1486,1512,1562,1603,1632,1610,1622,1645,1639,1652,+    1661,1690,1668,1680,1697,1726,1704,1716,1733,1740,1769,1747,1759,1776,+    1790,1819,1797,1809, 839,1263, 707, 712, 741, 881, 871,1160,1302,1346,+    1197, 985,1031,  23,1086,1108,  32,1219,  41,  51, 730,1194,  64,  76,+      86,  94,  97,1089,1118, 106,1131,1150, 966, 696,1183, 112, 734, 120,+     132, 783, 930, 945, 138,1385,1398,1529,1115,1157, 832,1079, 770, 916,+     598, 319,1246, 155,1833,1586, 721, 749, 797, 811, 826, 829, 846, 856,+     888, 903, 954,1363,1421,1356,1433,1443,1450,1457,1469,1479,1493,1500,+     163,1522,1543,1550,1572,1134, 991,1002,1008,1015,1021,1040,1045,1053,+    1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229,+    1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200,+     209, 218, 225, 232, 239, 246+  };+++#define FT_NUM_SID_NAMES  391++  /* Values are offsets into the `ft_standard_glyph_names' table */++  static const short  ft_sid_names[FT_NUM_SID_NAMES] =+  {+     253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365,+     371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441,+     447, 457, 462, 468, 476, 485, 488, 490, 492, 494, 496, 498, 500, 502,+     504, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530,+     532, 534, 536, 538, 540, 552, 562, 575, 587, 598, 608, 610, 612, 614,+     616, 618, 620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 642,+     644, 646, 648, 650, 652, 654, 656, 658, 660, 670, 674, 685, 696, 707,+     712, 721, 730, 734, 741, 749, 758, 770, 783, 797, 811, 826, 829, 832,+     839, 846, 856, 871, 881, 888, 903, 916, 930, 945, 954, 966, 979, 985,+     991,1002,1008,1015,1021,1031,1040,1045,1053,1066,1073,1079,1086,1089,+    1101,1108,1115,1118,1131,1134,1143,1150,1157,1160,1171,1183,1194,1197,+    1207,1211,1219,1229,1235,1246,1253,1263,1270,1276,1290,1302,1313,1319,+    1323,1332,1346,1356,1363,1375,1385,1392,1398,1405,1414,1421,1433,1443,+    1450,1457,1469,1479,1486,1493,1500,1512,1522,1529,1536,1543,1550,1562,+    1572,1579,1586,1596,1603,1610,1622,1632,1639,1645,1652,1661,1668,1680,+    1690,1697,1704,1716,1726,1733,1740,1747,1759,1769,1776,1783,1790,1797,+    1809,1819,1826,1833,1843,1850,1862,1880,1895,1910,1925,1936,1954,1973,+    1988,2003,2016,2028,2040,2054,2067,2080,2092,2106,2120,2133,2147,2167,+    2182,2196,2206,2216,2229,2239,2249,2259,2269,2279,2289,2299,2309,2319,+    2329,2332,2336,2340,2358,2377,2393,2408,2419,2426,2433,2440,2447,2454,+    2461,2468,2475,2482,2489,2496,2503,2510,2517,2524,2531,2538,2545,2552,+    2559,2566,2573,2580,2587,2594,2601,2615,2625,2632,2643,2659,2672,2684,+    2696,2708,2722,2733,2744,2759,2771,2782,2797,2809,2819,2832,2850,2860,+    2873,2885,2898,2907,2917,2930,2943,2956,2968,2982,2996,3009,3022,3034,+    3046,3060,3073,3086,3098,3112,3126,3139,3152,3167,3182,3196,3208,3220,+    3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409,+    3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586,+    3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687+  };+++  /* the following are indices into the SID name table */+  static const unsigned short  t1_standard_encoding[256] =+  {+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,+     17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,+     33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,+     49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,+     65, 66, 67, 68, 69, 70, 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,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,+      0,111,112,113,114,  0,115,116,117,118,119,120,121,122,  0,123,+      0,124,125,126,127,128,129,130,131,  0,132,133,  0,134,135,136,+    137,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,138,  0,139,  0,  0,  0,  0,140,141,142,143,  0,  0,  0,  0,+      0,144,  0,  0,  0,145,  0,  0,146,147,148,149,  0,  0,  0,  0+  };+++  /* the following are indices into the SID name table */+  static const unsigned short  t1_expert_encoding[256] =+  {+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      1,229,230,  0,231,232,233,234,235,236,237,238, 13, 14, 15, 99,+    239,240,241,242,243,244,245,246,247,248, 27, 28,249,250,251,252,+      0,253,254,255,256,257,  0,  0,  0,258,  0,  0,259,260,261,262,+      0,  0,263,264,265,  0,266,109,110,267,268,269,  0,270,271,272,+    273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,+    289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,+      0,304,305,306,  0,  0,307,308,309,310,311,  0,312,  0,  0,313,+      0,  0,314,315,  0,  0,316,317,318,  0,  0,  0,158,155,163,319,+    320,321,322,323,324,325,  0,  0,326,150,164,169,327,328,329,330,+    331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,+    347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,+    363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378+  };+++  /*+   *  This table is a compressed version of the Adobe Glyph List (AGL),+   *  optimized for efficient searching.  It has been generated by the+   *  `glnames.py' python script located in the `src/tools' directory.+   *+   *  The lookup function to get the Unicode value for a given string+   *  is defined below the table.+   */++#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST++  static const unsigned char  ft_adobe_glyph_list[54791L] =+  {+      0, 52,  0,106,  2,167,  3, 63,  4,220,  6,125,  9,143, 10, 23,+     11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88,+     22,110, 23, 32, 23, 71, 24, 77, 27,156, 29, 73, 31,247, 32,107,+     32,222, 33, 55, 34,154, 35,218, 53, 84, 59,196, 68,  6, 75,183,+     83,178, 88,135, 93,242,101,165,109,185,111, 55,117,254,123, 73,+    130,238,138,206,145, 31,153,182,156,189,163,249,178,221,193, 17,+    197, 99,199,240,204, 27,204,155,210,100, 65,143,  0, 65,  0,140,+      0,175,  0,193,  1, 15,  1,147,  1,233,  1,251,  2,  7,  2, 40,+      2, 57,  2, 82,  2, 91,  2,128,  2,136,  2,154, 69,131,  0,198,+      0,150,  0,158,  0,167,225,227,245,244,101,128,  1,252,237,225,+    227,242,239,110,128,  1,226,243,237,225,236,108,128,247,230,225,+    227,245,244,101,129,  0,193,  0,185,243,237,225,236,108,128,247,+    225,226,242,229,246,101,134,  1,  2,  0,213,  0,221,  0,232,  0,+    243,  0,251,  1,  7,225,227,245,244,101,128, 30,174,227,249,242,+    233,236,236,233, 99,128,  4,208,228,239,244,226,229,236,239,119,+    128, 30,182,231,242,225,246,101,128, 30,176,232,239,239,235,225,+    226,239,246,101,128, 30,178,244,233,236,228,101,128, 30,180, 99,+      4,  1, 25,  1, 32,  1,121,  1,137,225,242,239,110,128,  1,205,+    233,242, 99,  2,  1, 40,  1, 45,236,101,128, 36,182,245,237,230,+    236,229,120,134,  0,194,  1, 66,  1, 74,  1, 85,  1, 93,  1,105,+      1,113,225,227,245,244,101,128, 30,164,228,239,244,226,229,236,+    239,119,128, 30,172,231,242,225,246,101,128, 30,166,232,239,239,+    235,225,226,239,246,101,128, 30,168,243,237,225,236,108,128,247,+    226,244,233,236,228,101,128, 30,170,245,244,101,129,246,201,  1,+    129,243,237,225,236,108,128,247,180,249,242,233,236,236,233, 99,+    128,  4, 16,100,  3,  1,155,  1,165,  1,209,226,236,231,242,225,+    246,101,128,  2,  0,233,229,242,229,243,233,115,131,  0,196,  1,+    181,  1,192,  1,201,227,249,242,233,236,236,233, 99,128,  4,210,+    237,225,227,242,239,110,128,  1,222,243,237,225,236,108,128,247,+    228,239,116,  2,  1,216,  1,224,226,229,236,239,119,128, 30,160,+    237,225,227,242,239,110,128,  1,224,231,242,225,246,101,129,  0,+    192,  1,243,243,237,225,236,108,128,247,224,232,239,239,235,225,+    226,239,246,101,128, 30,162,105,  2,  2, 13,  2, 25,229,227,249,+    242,233,236,236,233, 99,128,  4,212,238,246,229,242,244,229,228,+    226,242,229,246,101,128,  2,  2,236,240,232, 97,129,  3,145,  2,+     49,244,239,238,239,115,128,  3,134,109,  2,  2, 63,  2, 71,225,+    227,242,239,110,128,  1,  0,239,238,239,243,240,225,227,101,128,+    255, 33,239,231,239,238,229,107,128,  1,  4,242,233,238,103,131,+      0,197,  2,104,  2,112,  2,120,225,227,245,244,101,128,  1,250,+    226,229,236,239,119,128, 30,  0,243,237,225,236,108,128,247,229,+    243,237,225,236,108,128,247, 97,244,233,236,228,101,129,  0,195,+      2,146,243,237,225,236,108,128,247,227,249,226,225,242,237,229,+    238,233,225,110,128,  5, 49, 66,137,  0, 66,  2,189,  2,198,  2,+    223,  3,  3,  3, 10,  3, 22,  3, 34,  3, 46,  3, 54,227,233,242,+    227,236,101,128, 36,183,228,239,116,  2,  2,206,  2,215,225,227,+    227,229,238,116,128, 30,  2,226,229,236,239,119,128, 30,  4,101,+      3,  2,231,  2,242,  2,254,227,249,242,233,236,236,233, 99,128,+      4, 17,238,225,242,237,229,238,233,225,110,128,  5, 50,244, 97,+    128,  3,146,232,239,239,107,128,  1,129,236,233,238,229,226,229,+    236,239,119,128, 30,  6,237,239,238,239,243,240,225,227,101,128,+    255, 34,242,229,246,229,243,237,225,236,108,128,246,244,243,237,+    225,236,108,128,247, 98,244,239,240,226,225,114,128,  1,130, 67,+    137,  0, 67,  3, 85,  3,127,  3,193,  3,210,  3,224,  4,171,  4,+    188,  4,200,  4,212, 97,  3,  3, 93,  3,104,  3,111,225,242,237,+    229,238,233,225,110,128,  5, 62,227,245,244,101,128,  1,  6,242,+    239,110,129,246,202,  3,119,243,237,225,236,108,128,246,245, 99,+      3,  3,135,  3,142,  3,171,225,242,239,110,128,  1, 12,229,228,+    233,236,236, 97,130,  0,199,  3,155,  3,163,225,227,245,244,101,+    128, 30,  8,243,237,225,236,108,128,247,231,233,242, 99,  2,  3,+    179,  3,184,236,101,128, 36,184,245,237,230,236,229,120,128,  1,+      8,228,239,116,129,  1, 10,  3,201,225,227,227,229,238,116,128,+      1, 10,229,228,233,236,236,225,243,237,225,236,108,128,247,184,+    104,  4,  3,234,  3,246,  4,161,  4,165,225,225,242,237,229,238,+    233,225,110,128,  5, 73,101,  6,  4,  4,  4, 24,  4, 35,  4,103,+      4,115,  4,136,225,226,235,232,225,243,233,225,238,227,249,242,+    233,236,236,233, 99,128,  4,188,227,249,242,233,236,236,233, 99,+    128,  4, 39,100,  2,  4, 41,  4, 85,229,243,227,229,238,228,229,+    114,  2,  4, 54,  4, 74,225,226,235,232,225,243,233,225,238,227,+    249,242,233,236,236,233, 99,128,  4,190,227,249,242,233,236,236,+    233, 99,128,  4,182,233,229,242,229,243,233,243,227,249,242,233,+    236,236,233, 99,128,  4,244,232,225,242,237,229,238,233,225,110,+    128,  5, 67,235,232,225,235,225,243,243,233,225,238,227,249,242,+    233,236,236,233, 99,128,  4,203,246,229,242,244,233,227,225,236,+    243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128,  4,+    184,105,128,  3,167,239,239,107,128,  1,135,233,242,227,245,237,+    230,236,229,248,243,237,225,236,108,128,246,246,237,239,238,239,+    243,240,225,227,101,128,255, 35,239,225,242,237,229,238,233,225,+    110,128,  5, 81,243,237,225,236,108,128,247, 99, 68,142,  0, 68,+      4,252,  5, 10,  5, 36,  5, 96,  5,121,  5,166,  5,173,  5,231,+      5,244,  6,  0,  6, 12,  6, 28,  6, 48,  6, 57, 90,129,  1,241,+      5,  2,227,225,242,239,110,128,  1,196, 97,  2,  5, 16,  5, 27,+    225,242,237,229,238,233,225,110,128,  5, 52,230,242,233,227,225,+    110,128,  1,137, 99,  4,  5, 46,  5, 53,  5, 62,  5, 89,225,242,+    239,110,128,  1, 14,229,228,233,236,236, 97,128, 30, 16,233,242,+     99,  2,  5, 70,  5, 75,236,101,128, 36,185,245,237,230,236,229,+    248,226,229,236,239,119,128, 30, 18,242,239,225,116,128,  1, 16,+    228,239,116,  2,  5,104,  5,113,225,227,227,229,238,116,128, 30,+     10,226,229,236,239,119,128, 30, 12,101,  3,  5,129,  5,140,  5,+    150,227,249,242,233,236,236,233, 99,128,  4, 20,233,227,239,240,+    244,233, 99,128,  3,238,236,244, 97,129, 34,  6,  5,158,231,242,+    229,229,107,128,  3,148,232,239,239,107,128,  1,138,105,  2,  5,+    179,  5,218,229,242,229,243,233,115,131,246,203,  5,194,  5,202,+      5,210,193,227,245,244,101,128,246,204,199,242,225,246,101,128,+    246,205,243,237,225,236,108,128,247,168,231,225,237,237,225,231,+    242,229,229,107,128,  3,220,234,229,227,249,242,233,236,236,233,+     99,128,  4,  2,236,233,238,229,226,229,236,239,119,128, 30, 14,+    237,239,238,239,243,240,225,227,101,128,255, 36,239,244,225,227,+    227,229,238,244,243,237,225,236,108,128,246,247,115,  2,  6, 34,+      6, 41,236,225,243,104,128,  1, 16,237,225,236,108,128,247,100,+    244,239,240,226,225,114,128,  1,139,122,131,  1,242,  6, 67,  6,+     75,  6,112,227,225,242,239,110,128,  1,197,101,  2,  6, 81,  6,+    101,225,226,235,232,225,243,233,225,238,227,249,242,233,236,236,+    233, 99,128,  4,224,227,249,242,233,236,236,233, 99,128,  4,  5,+    232,229,227,249,242,233,236,236,233, 99,128,  4, 15, 69,146,  0,+     69,  6,165,  6,183,  6,191,  7, 89,  7,153,  7,165,  7,183,  7,+    211,  8,  7,  8, 36,  8, 94,  8,169,  8,189,  8,208,  8,248,  9,+     44,  9,109,  9,115,225,227,245,244,101,129,  0,201,  6,175,243,+    237,225,236,108,128,247,233,226,242,229,246,101,128,  1, 20, 99,+      5,  6,203,  6,210,  6,224,  6,236,  7, 79,225,242,239,110,128,+      1, 26,229,228,233,236,236,225,226,242,229,246,101,128, 30, 28,+    232,225,242,237,229,238,233,225,110,128,  5, 53,233,242, 99,  2,+      6,244,  6,249,236,101,128, 36,186,245,237,230,236,229,120,135,+      0,202,  7, 16,  7, 24,  7, 32,  7, 43,  7, 51,  7, 63,  7, 71,+    225,227,245,244,101,128, 30,190,226,229,236,239,119,128, 30, 24,+    228,239,244,226,229,236,239,119,128, 30,198,231,242,225,246,101,+    128, 30,192,232,239,239,235,225,226,239,246,101,128, 30,194,243,+    237,225,236,108,128,247,234,244,233,236,228,101,128, 30,196,249,+    242,233,236,236,233, 99,128,  4,  4,100,  3,  7, 97,  7,107,  7,+    127,226,236,231,242,225,246,101,128,  2,  4,233,229,242,229,243,+    233,115,129,  0,203,  7,119,243,237,225,236,108,128,247,235,239,+    116,130,  1, 22,  7,136,  7,145,225,227,227,229,238,116,128,  1,+     22,226,229,236,239,119,128, 30,184,230,227,249,242,233,236,236,+    233, 99,128,  4, 36,231,242,225,246,101,129,  0,200,  7,175,243,+    237,225,236,108,128,247,232,104,  2,  7,189,  7,200,225,242,237,+    229,238,233,225,110,128,  5, 55,239,239,235,225,226,239,246,101,+    128, 30,186,105,  3,  7,219,  7,230,  7,245,231,232,244,242,239,+    237,225,110,128, 33,103,238,246,229,242,244,229,228,226,242,229,+    246,101,128,  2,  6,239,244,233,230,233,229,228,227,249,242,233,+    236,236,233, 99,128,  4,100,108,  2,  8, 13,  8, 24,227,249,242,+    233,236,236,233, 99,128,  4, 27,229,246,229,238,242,239,237,225,+    110,128, 33,106,109,  3,  8, 44,  8, 72,  8, 83,225,227,242,239,+    110,130,  1, 18,  8, 56,  8, 64,225,227,245,244,101,128, 30, 22,+    231,242,225,246,101,128, 30, 20,227,249,242,233,236,236,233, 99,+    128,  4, 28,239,238,239,243,240,225,227,101,128,255, 37,110,  4,+      8,104,  8,115,  8,135,  8,154,227,249,242,233,236,236,233, 99,+    128,  4, 29,228,229,243,227,229,238,228,229,242,227,249,242,233,+    236,236,233, 99,128,  4,162,103,129,  1, 74,  8,141,232,229,227,+    249,242,233,236,236,233, 99,128,  4,164,232,239,239,235,227,249,+    242,233,236,236,233, 99,128,  4,199,111,  2,  8,175,  8,183,231,+    239,238,229,107,128,  1, 24,240,229,110,128,  1,144,240,243,233,+    236,239,110,129,  3,149,  8,200,244,239,238,239,115,128,  3,136,+    114,  2,  8,214,  8,225,227,249,242,233,236,236,233, 99,128,  4,+     32,229,246,229,242,243,229,100,129,  1,142,  8,237,227,249,242,+    233,236,236,233, 99,128,  4, 45,115,  4,  9,  2,  9, 13,  9, 33,+      9, 37,227,249,242,233,236,236,233, 99,128,  4, 33,228,229,243,+    227,229,238,228,229,242,227,249,242,233,236,236,233, 99,128,  4,+    170,104,128,  1,169,237,225,236,108,128,247,101,116,  3,  9, 52,+      9, 78,  9, 92, 97,130,  3,151,  9, 60,  9, 70,242,237,229,238,+    233,225,110,128,  5, 56,244,239,238,239,115,128,  3,137,104,129,+      0,208,  9, 84,243,237,225,236,108,128,247,240,233,236,228,101,+    129, 30,188,  9,101,226,229,236,239,119,128, 30, 26,245,242,111,+    128, 32,172,250,104,130,  1,183,  9,124,  9,132,227,225,242,239,+    110,128,  1,238,242,229,246,229,242,243,229,100,128,  1,184, 70,+    136,  0, 70,  9,163,  9,172,  9,184,  9,212,  9,219,  9,248, 10,+      4, 10, 15,227,233,242,227,236,101,128, 36,187,228,239,244,225,+    227,227,229,238,116,128, 30, 30,101,  2,  9,190,  9,202,232,225,+    242,237,229,238,233,225,110,128,  5, 86,233,227,239,240,244,233,+     99,128,  3,228,232,239,239,107,128,  1,145,105,  2,  9,225,  9,+    238,244,225,227,249,242,233,236,236,233, 99,128,  4,114,246,229,+    242,239,237,225,110,128, 33,100,237,239,238,239,243,240,225,227,+    101,128,255, 38,239,245,242,242,239,237,225,110,128, 33, 99,243,+    237,225,236,108,128,247,102, 71,140,  0, 71, 10, 51, 10, 61, 10,+    107, 10,115, 10,176, 10,193, 10,205, 11, 39, 11, 52, 11, 65, 11,+     90, 11,107,194,243,241,245,225,242,101,128, 51,135, 97,  3, 10,+     69, 10, 76, 10, 94,227,245,244,101,128,  1,244,237,237, 97,129,+      3,147, 10, 84,225,230,242,233,227,225,110,128,  1,148,238,231,+    233,225,227,239,240,244,233, 99,128,  3,234,226,242,229,246,101,+    128,  1, 30, 99,  4, 10,125, 10,132, 10,141, 10,163,225,242,239,+    110,128,  1,230,229,228,233,236,236, 97,128,  1, 34,233,242, 99,+      2, 10,149, 10,154,236,101,128, 36,188,245,237,230,236,229,120,+    128,  1, 28,239,237,237,225,225,227,227,229,238,116,128,  1, 34,+    228,239,116,129,  1, 32, 10,184,225,227,227,229,238,116,128,  1,+     32,229,227,249,242,233,236,236,233, 99,128,  4, 19,104,  3, 10,+    213, 10,226, 11, 33,225,228,225,242,237,229,238,233,225,110,128,+      5, 66,101,  3, 10,234, 10,255, 11, 16,237,233,228,228,236,229,+    232,239,239,235,227,249,242,233,236,236,233, 99,128,  4,148,243,+    244,242,239,235,229,227,249,242,233,236,236,233, 99,128,  4,146,+    245,240,244,245,242,238,227,249,242,233,236,236,233, 99,128,  4,+    144,239,239,107,128,  1,147,233,237,225,242,237,229,238,233,225,+    110,128,  5, 51,234,229,227,249,242,233,236,236,233, 99,128,  4,+      3,109,  2, 11, 71, 11, 79,225,227,242,239,110,128, 30, 32,239,+    238,239,243,240,225,227,101,128,255, 39,242,225,246,101,129,246,+    206, 11, 99,243,237,225,236,108,128,247, 96,115,  2, 11,113, 11,+    129,237,225,236,108,129,247,103, 11,122,232,239,239,107,128,  2,+    155,244,242,239,235,101,128,  1,228, 72,140,  0, 72, 11,165, 11,+    190, 11,198, 11,208, 12, 17, 12, 40, 12, 77, 12,117, 12,129, 12,+    157, 12,165, 12,189,177,184, 53,  3, 11,175, 11,180, 11,185,179,+     51,128, 37,207,180, 51,128, 37,170,181, 49,128, 37,171,178,178,+    176,183, 51,128, 37,161,208,243,241,245,225,242,101,128, 51,203,+     97,  3, 11,216, 11,236, 12,  0,225,226,235,232,225,243,233,225,+    238,227,249,242,233,236,236,233, 99,128,  4,168,228,229,243,227,+    229,238,228,229,242,227,249,242,233,236,236,233, 99,128,  4,178,+    242,228,243,233,231,238,227,249,242,233,236,236,233, 99,128,  4,+     42, 98,  2, 12, 23, 12, 28,225,114,128,  1, 38,242,229,246,229,+    226,229,236,239,119,128, 30, 42, 99,  2, 12, 46, 12, 55,229,228,+    233,236,236, 97,128, 30, 40,233,242, 99,  2, 12, 63, 12, 68,236,+    101,128, 36,189,245,237,230,236,229,120,128,  1, 36,100,  2, 12,+     83, 12, 93,233,229,242,229,243,233,115,128, 30, 38,239,116,  2,+     12,100, 12,109,225,227,227,229,238,116,128, 30, 34,226,229,236,+    239,119,128, 30, 36,237,239,238,239,243,240,225,227,101,128,255,+     40,111,  2, 12,135, 12,146,225,242,237,229,238,233,225,110,128,+      5, 64,242,233,227,239,240,244,233, 99,128,  3,232,243,237,225,+    236,108,128,247,104,245,238,231,225,242,245,237,236,225,245,116,+    129,246,207, 12,181,243,237,225,236,108,128,246,248,250,243,241,+    245,225,242,101,128, 51,144, 73,146,  0, 73, 12,239, 12,251, 12,+    255, 13, 11, 13, 29, 13, 37, 13, 94, 13,181, 13,214, 13,224, 13,+    242, 13,254, 14, 48, 14, 86, 14, 99, 14,166, 14,187, 14,205,193,+    227,249,242,233,236,236,233, 99,128,  4, 47, 74,128,  1, 50,213,+    227,249,242,233,236,236,233, 99,128,  4, 46,225,227,245,244,101,+    129,  0,205, 13, 21,243,237,225,236,108,128,247,237,226,242,229,+    246,101,128,  1, 44, 99,  3, 13, 45, 13, 52, 13, 84,225,242,239,+    110,128,  1,207,233,242, 99,  2, 13, 60, 13, 65,236,101,128, 36,+    190,245,237,230,236,229,120,129,  0,206, 13, 76,243,237,225,236,+    108,128,247,238,249,242,233,236,236,233, 99,128,  4,  6,100,  3,+     13,102, 13,112, 13,155,226,236,231,242,225,246,101,128,  2,  8,+    233,229,242,229,243,233,115,131,  0,207, 13,128, 13,136, 13,147,+    225,227,245,244,101,128, 30, 46,227,249,242,233,236,236,233, 99,+    128,  4,228,243,237,225,236,108,128,247,239,239,116,130,  1, 48,+     13,164, 13,173,225,227,227,229,238,116,128,  1, 48,226,229,236,+    239,119,128, 30,202,101,  2, 13,187, 13,203,226,242,229,246,229,+    227,249,242,233,236,236,233, 99,128,  4,214,227,249,242,233,236,+    236,233, 99,128,  4, 21,230,242,225,235,244,245,114,128, 33, 17,+    231,242,225,246,101,129,  0,204, 13,234,243,237,225,236,108,128,+    247,236,232,239,239,235,225,226,239,246,101,128, 30,200,105,  3,+     14,  6, 14, 17, 14, 32,227,249,242,233,236,236,233, 99,128,  4,+     24,238,246,229,242,244,229,228,226,242,229,246,101,128,  2, 10,+    243,232,239,242,244,227,249,242,233,236,236,233, 99,128,  4, 25,+    109,  2, 14, 54, 14, 75,225,227,242,239,110,129,  1, 42, 14, 64,+    227,249,242,233,236,236,233, 99,128,  4,226,239,238,239,243,240,+    225,227,101,128,255, 41,238,233,225,242,237,229,238,233,225,110,+    128,  5, 59,111,  3, 14,107, 14,118, 14,126,227,249,242,233,236,+    236,233, 99,128,  4,  1,231,239,238,229,107,128,  1, 46,244, 97,+    131,  3,153, 14,137, 14,147, 14,158,225,230,242,233,227,225,110,+    128,  1,150,228,233,229,242,229,243,233,115,128,  3,170,244,239,+    238,239,115,128,  3,138,115,  2, 14,172, 14,179,237,225,236,108,+    128,247,105,244,242,239,235,101,128,  1,151,244,233,236,228,101,+    129,  1, 40, 14,197,226,229,236,239,119,128, 30, 44,250,232,233,+    244,243, 97,  2, 14,216, 14,227,227,249,242,233,236,236,233, 99,+    128,  4,116,228,226,236,231,242,225,246,229,227,249,242,233,236,+    236,233, 99,128,  4,118, 74,134,  0, 74, 15,  6, 15, 18, 15, 41,+     15, 53, 15, 67, 15, 79,225,225,242,237,229,238,233,225,110,128,+      5, 65,227,233,242, 99,  2, 15, 27, 15, 32,236,101,128, 36,191,+    245,237,230,236,229,120,128,  1, 52,229,227,249,242,233,236,236,+    233, 99,128,  4,  8,232,229,232,225,242,237,229,238,233,225,110,+    128,  5, 75,237,239,238,239,243,240,225,227,101,128,255, 42,243,+    237,225,236,108,128,247,106, 75,140,  0, 75, 15,115, 15,125, 15,+    135, 16, 18, 16, 65, 16, 76, 16,106, 16,143, 16,156, 16,168, 16,+    180, 16,208,194,243,241,245,225,242,101,128, 51,133,203,243,241,+    245,225,242,101,128, 51,205, 97,  7, 15,151, 15,169, 15,191, 15,+    211, 15,226, 15,232, 15,249,226,225,243,232,235,233,242,227,249,+    242,233,236,236,233, 99,128,  4,160, 99,  2, 15,175, 15,181,245,+    244,101,128, 30, 48,249,242,233,236,236,233, 99,128,  4, 26,228,+    229,243,227,229,238,228,229,242,227,249,242,233,236,236,233, 99,+    128,  4,154,232,239,239,235,227,249,242,233,236,236,233, 99,128,+      4,195,240,240, 97,128,  3,154,243,244,242,239,235,229,227,249,+    242,233,236,236,233, 99,128,  4,158,246,229,242,244,233,227,225,+    236,243,244,242,239,235,229,227,249,242,233,236,236,233, 99,128,+      4,156, 99,  4, 16, 28, 16, 35, 16, 44, 16, 52,225,242,239,110,+    128,  1,232,229,228,233,236,236, 97,128,  1, 54,233,242,227,236,+    101,128, 36,192,239,237,237,225,225,227,227,229,238,116,128,  1,+     54,228,239,244,226,229,236,239,119,128, 30, 50,101,  2, 16, 82,+     16, 94,232,225,242,237,229,238,233,225,110,128,  5, 84,238,225,+    242,237,229,238,233,225,110,128,  5, 63,104,  3, 16,114, 16,126,+     16,137,225,227,249,242,233,236,236,233, 99,128,  4, 37,229,233,+    227,239,240,244,233, 99,128,  3,230,239,239,107,128,  1,152,234,+    229,227,249,242,233,236,236,233, 99,128,  4, 12,236,233,238,229,+    226,229,236,239,119,128, 30, 52,237,239,238,239,243,240,225,227,+    101,128,255, 43,239,240,240, 97,  2, 16,189, 16,200,227,249,242,+    233,236,236,233, 99,128,  4,128,231,242,229,229,107,128,  3,222,+    115,  2, 16,214, 16,226,233,227,249,242,233,236,236,233, 99,128,+      4,110,237,225,236,108,128,247,107, 76,138,  0, 76, 17,  1, 17,+      5, 17,  9, 17, 29, 17, 95, 17,133, 17,147, 17,165, 17,177, 17,+    189, 74,128,  1,199, 76,128,246,191, 97,  2, 17, 15, 17, 22,227,+    245,244,101,128,  1, 57,237,226,228, 97,128,  3,155, 99,  4, 17,+     39, 17, 46, 17, 55, 17, 82,225,242,239,110,128,  1, 61,229,228,+    233,236,236, 97,128,  1, 59,233,242, 99,  2, 17, 63, 17, 68,236,+    101,128, 36,193,245,237,230,236,229,248,226,229,236,239,119,128,+     30, 60,239,237,237,225,225,227,227,229,238,116,128,  1, 59,228,+    239,116,130,  1, 63, 17,105, 17,114,225,227,227,229,238,116,128,+      1, 63,226,229,236,239,119,129, 30, 54, 17,124,237,225,227,242,+    239,110,128, 30, 56,233,247,238,225,242,237,229,238,233,225,110,+    128,  5, 60,106,129,  1,200, 17,153,229,227,249,242,233,236,236,+    233, 99,128,  4,  9,236,233,238,229,226,229,236,239,119,128, 30,+     58,237,239,238,239,243,240,225,227,101,128,255, 44,115,  2, 17,+    195, 17,212,236,225,243,104,129,  1, 65, 17,204,243,237,225,236,+    108,128,246,249,237,225,236,108,128,247,108, 77,137,  0, 77, 17,+    241, 17,251, 18, 24, 18, 33, 18, 58, 18, 71, 18, 83, 18, 91, 18,+    100,194,243,241,245,225,242,101,128, 51,134,225, 99,  2, 18,  2,+     18, 18,242,239,110,129,246,208, 18, 10,243,237,225,236,108,128,+    247,175,245,244,101,128, 30, 62,227,233,242,227,236,101,128, 36,+    194,228,239,116,  2, 18, 41, 18, 50,225,227,227,229,238,116,128,+     30, 64,226,229,236,239,119,128, 30, 66,229,238,225,242,237,229,+    238,233,225,110,128,  5, 68,237,239,238,239,243,240,225,227,101,+    128,255, 45,243,237,225,236,108,128,247,109,244,245,242,238,229,+    100,128,  1,156,117,128,  3,156, 78,141,  0, 78, 18,134, 18,138,+     18,146, 18,212, 18,237, 18,248, 19,  3, 19, 21, 19, 33, 19, 45,+     19, 58, 19, 66, 19, 84, 74,128,  1,202,225,227,245,244,101,128,+      1, 67, 99,  4, 18,156, 18,163, 18,172, 18,199,225,242,239,110,+    128,  1, 71,229,228,233,236,236, 97,128,  1, 69,233,242, 99,  2,+     18,180, 18,185,236,101,128, 36,195,245,237,230,236,229,248,226,+    229,236,239,119,128, 30, 74,239,237,237,225,225,227,227,229,238,+    116,128,  1, 69,228,239,116,  2, 18,220, 18,229,225,227,227,229,+    238,116,128, 30, 68,226,229,236,239,119,128, 30, 70,232,239,239,+    235,236,229,230,116,128,  1,157,233,238,229,242,239,237,225,110,+    128, 33,104,106,129,  1,203, 19,  9,229,227,249,242,233,236,236,+    233, 99,128,  4, 10,236,233,238,229,226,229,236,239,119,128, 30,+     72,237,239,238,239,243,240,225,227,101,128,255, 46,239,247,225,+    242,237,229,238,233,225,110,128,  5, 70,243,237,225,236,108,128,+    247,110,244,233,236,228,101,129,  0,209, 19, 76,243,237,225,236,+    108,128,247,241,117,128,  3,157, 79,141,  0, 79, 19,118, 19,132,+     19,150, 19,203, 20, 78, 20,152, 20,187, 21, 48, 21, 69, 21,213,+     21,223, 21,254, 22, 53, 69,129,  1, 82, 19,124,243,237,225,236,+    108,128,246,250,225,227,245,244,101,129,  0,211, 19,142,243,237,+    225,236,108,128,247,243, 98,  2, 19,156, 19,196,225,242,242,229,+    100,  2, 19,166, 19,177,227,249,242,233,236,236,233, 99,128,  4,+    232,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233,+     99,128,  4,234,242,229,246,101,128,  1, 78, 99,  4, 19,213, 19,+    220, 19,235, 20, 68,225,242,239,110,128,  1,209,229,238,244,229,+    242,229,228,244,233,236,228,101,128,  1,159,233,242, 99,  2, 19,+    243, 19,248,236,101,128, 36,196,245,237,230,236,229,120,134,  0,+    212, 20, 13, 20, 21, 20, 32, 20, 40, 20, 52, 20, 60,225,227,245,+    244,101,128, 30,208,228,239,244,226,229,236,239,119,128, 30,216,+    231,242,225,246,101,128, 30,210,232,239,239,235,225,226,239,246,+    101,128, 30,212,243,237,225,236,108,128,247,244,244,233,236,228,+    101,128, 30,214,249,242,233,236,236,233, 99,128,  4, 30,100,  3,+     20, 86, 20,109, 20,142,226,108,  2, 20, 93, 20,101,225,227,245,+    244,101,128,  1, 80,231,242,225,246,101,128,  2, 12,233,229,242,+    229,243,233,115,130,  0,214, 20,123, 20,134,227,249,242,233,236,+    236,233, 99,128,  4,230,243,237,225,236,108,128,247,246,239,244,+    226,229,236,239,119,128, 30,204,103,  2, 20,158, 20,170,239,238,+    229,235,243,237,225,236,108,128,246,251,242,225,246,101,129,  0,+    210, 20,179,243,237,225,236,108,128,247,242,104,  4, 20,197, 20,+    208, 20,212, 21, 34,225,242,237,229,238,233,225,110,128,  5, 85,+    109,128, 33, 38,111,  2, 20,218, 20,228,239,235,225,226,239,246,+    101,128, 30,206,242,110,133,  1,160, 20,243, 20,251, 21,  6, 21,+     14, 21, 26,225,227,245,244,101,128, 30,218,228,239,244,226,229,+    236,239,119,128, 30,226,231,242,225,246,101,128, 30,220,232,239,+    239,235,225,226,239,246,101,128, 30,222,244,233,236,228,101,128,+     30,224,245,238,231,225,242,245,237,236,225,245,116,128,  1, 80,+    105,129,  1,162, 21, 54,238,246,229,242,244,229,228,226,242,229,+    246,101,128,  2, 14,109,  4, 21, 79, 21,107, 21,184, 21,202,225,+    227,242,239,110,130,  1, 76, 21, 91, 21, 99,225,227,245,244,101,+    128, 30, 82,231,242,225,246,101,128, 30, 80,229,231, 97,132, 33,+     38, 21,121, 21,132, 21,140, 21,156,227,249,242,233,236,236,233,+     99,128,  4, 96,231,242,229,229,107,128,  3,169,242,239,245,238,+    228,227,249,242,233,236,236,233, 99,128,  4,122,116,  2, 21,162,+     21,177,233,244,236,239,227,249,242,233,236,236,233, 99,128,  4,+    124,239,238,239,115,128,  3,143,233,227,242,239,110,129,  3,159,+     21,194,244,239,238,239,115,128,  3,140,239,238,239,243,240,225,+    227,101,128,255, 47,238,229,242,239,237,225,110,128, 33, 96,111,+      2, 21,229, 21,248,231,239,238,229,107,129,  1,234, 21,239,237,+    225,227,242,239,110,128,  1,236,240,229,110,128,  1,134,115,  3,+     22,  6, 22, 33, 22, 40,236,225,243,104,130,  0,216, 22, 17, 22,+     25,225,227,245,244,101,128,  1,254,243,237,225,236,108,128,247,+    248,237,225,236,108,128,247,111,244,242,239,235,229,225,227,245,+    244,101,128,  1,254,116,  2, 22, 59, 22, 70,227,249,242,233,236,+    236,233, 99,128,  4,126,233,236,228,101,131,  0,213, 22, 83, 22,+     91, 22,102,225,227,245,244,101,128, 30, 76,228,233,229,242,229,+    243,233,115,128, 30, 78,243,237,225,236,108,128,247,245, 80,136,+      0, 80, 22,130, 22,138, 22,147, 22,159, 22,211, 22,227, 22,246,+     23,  2,225,227,245,244,101,128, 30, 84,227,233,242,227,236,101,+    128, 36,197,228,239,244,225,227,227,229,238,116,128, 30, 86,101,+      3, 22,167, 22,178, 22,190,227,249,242,233,236,236,233, 99,128,+      4, 31,232,225,242,237,229,238,233,225,110,128,  5, 74,237,233,+    228,228,236,229,232,239,239,235,227,249,242,233,236,236,233, 99,+    128,  4,166,104,  2, 22,217, 22,221,105,128,  3,166,239,239,107,+    128,  1,164,105,129,  3,160, 22,233,247,242,225,242,237,229,238,+    233,225,110,128,  5, 83,237,239,238,239,243,240,225,227,101,128,+    255, 48,115,  2, 23,  8, 23, 25,105,129,  3,168, 23, 14,227,249,+    242,233,236,236,233, 99,128,  4,112,237,225,236,108,128,247,112,+     81,131,  0, 81, 23, 42, 23, 51, 23, 63,227,233,242,227,236,101,+    128, 36,198,237,239,238,239,243,240,225,227,101,128,255, 49,243,+    237,225,236,108,128,247,113, 82,138,  0, 82, 23, 95, 23,119, 23,+    166, 23,217, 23,230, 23,240, 23,245, 24, 19, 24, 31, 24, 43, 97,+      2, 23,101, 23,112,225,242,237,229,238,233,225,110,128,  5, 76,+    227,245,244,101,128,  1, 84, 99,  4, 23,129, 23,136, 23,145, 23,+    153,225,242,239,110,128,  1, 88,229,228,233,236,236, 97,128,  1,+     86,233,242,227,236,101,128, 36,199,239,237,237,225,225,227,227,+    229,238,116,128,  1, 86,100,  2, 23,172, 23,182,226,236,231,242,+    225,246,101,128,  2, 16,239,116,  2, 23,189, 23,198,225,227,227,+    229,238,116,128, 30, 88,226,229,236,239,119,129, 30, 90, 23,208,+    237,225,227,242,239,110,128, 30, 92,229,232,225,242,237,229,238,+    233,225,110,128,  5, 80,230,242,225,235,244,245,114,128, 33, 28,+    232,111,128,  3,161,233,110,  2, 23,252, 24,  5,231,243,237,225,+    236,108,128,246,252,246,229,242,244,229,228,226,242,229,246,101,+    128,  2, 18,236,233,238,229,226,229,236,239,119,128, 30, 94,237,+    239,238,239,243,240,225,227,101,128,255, 50,243,237,225,236,108,+    129,247,114, 24, 53,233,238,246,229,242,244,229,100,129,  2,129,+     24, 66,243,245,240,229,242,233,239,114,128,  2,182, 83,139,  0,+     83, 24,103, 26, 17, 26, 55, 26,182, 26,221, 26,250, 27, 84, 27,+    105, 27,117, 27,135, 27,143, 70,  6, 24,117, 24,209, 24,241, 25,+     77, 25,119, 25,221, 48,  9, 24,137, 24,145, 24,153, 24,161, 24,+    169, 24,177, 24,185, 24,193, 24,201,177,176,176,176, 48,128, 37,+     12,178,176,176,176, 48,128, 37, 20,179,176,176,176, 48,128, 37,+     16,180,176,176,176, 48,128, 37, 24,181,176,176,176, 48,128, 37,+     60,182,176,176,176, 48,128, 37, 44,183,176,176,176, 48,128, 37,+     52,184,176,176,176, 48,128, 37, 28,185,176,176,176, 48,128, 37,+     36, 49,  3, 24,217, 24,225, 24,233,176,176,176,176, 48,128, 37,+      0,177,176,176,176, 48,128, 37,  2,185,176,176,176, 48,128, 37,+     97, 50,  9, 25,  5, 25, 13, 25, 21, 25, 29, 25, 37, 25, 45, 25,+     53, 25, 61, 25, 69,176,176,176,176, 48,128, 37, 98,177,176,176,+    176, 48,128, 37, 86,178,176,176,176, 48,128, 37, 85,179,176,176,+    176, 48,128, 37, 99,180,176,176,176, 48,128, 37, 81,181,176,176,+    176, 48,128, 37, 87,182,176,176,176, 48,128, 37, 93,183,176,176,+    176, 48,128, 37, 92,184,176,176,176, 48,128, 37, 91, 51,  4, 25,+     87, 25, 95, 25,103, 25,111,182,176,176,176, 48,128, 37, 94,183,+    176,176,176, 48,128, 37, 95,184,176,176,176, 48,128, 37, 90,185,+    176,176,176, 48,128, 37, 84, 52, 10, 25,141, 25,149, 25,157, 25,+    165, 25,173, 25,181, 25,189, 25,197, 25,205, 25,213,176,176,176,+    176, 48,128, 37,105,177,176,176,176, 48,128, 37,102,178,176,176,+    176, 48,128, 37, 96,179,176,176,176, 48,128, 37, 80,180,176,176,+    176, 48,128, 37,108,181,176,176,176, 48,128, 37,103,182,176,176,+    176, 48,128, 37,104,183,176,176,176, 48,128, 37,100,184,176,176,+    176, 48,128, 37,101,185,176,176,176, 48,128, 37, 89, 53,  5, 25,+    233, 25,241, 25,249, 26,  1, 26,  9,176,176,176,176, 48,128, 37,+     88,177,176,176,176, 48,128, 37, 82,178,176,176,176, 48,128, 37,+     83,179,176,176,176, 48,128, 37,107,180,176,176,176, 48,128, 37,+    106, 97,  2, 26, 23, 26, 44,227,245,244,101,129,  1, 90, 26, 32,+    228,239,244,225,227,227,229,238,116,128, 30,100,237,240,233,231,+    242,229,229,107,128,  3,224, 99,  5, 26, 67, 26, 98, 26,107, 26,+    147, 26,169,225,242,239,110,130,  1, 96, 26, 78, 26, 90,228,239,+    244,225,227,227,229,238,116,128, 30,102,243,237,225,236,108,128,+    246,253,229,228,233,236,236, 97,128,  1, 94,232,247, 97,130,  1,+    143, 26,117, 26,128,227,249,242,233,236,236,233, 99,128,  4,216,+    228,233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,+    128,  4,218,233,242, 99,  2, 26,155, 26,160,236,101,128, 36,200,+    245,237,230,236,229,120,128,  1, 92,239,237,237,225,225,227,227,+    229,238,116,128,  2, 24,228,239,116,  2, 26,190, 26,199,225,227,+    227,229,238,116,128, 30, 96,226,229,236,239,119,129, 30, 98, 26,+    209,228,239,244,225,227,227,229,238,116,128, 30,104,101,  2, 26,+    227, 26,239,232,225,242,237,229,238,233,225,110,128,  5, 77,246,+    229,238,242,239,237,225,110,128, 33,102,104,  5, 27,  6, 27, 34,+     27, 48, 27, 59, 27, 72, 97,  2, 27, 12, 27, 23,225,242,237,229,+    238,233,225,110,128,  5, 71,227,249,242,233,236,236,233, 99,128,+      4, 40,227,232,225,227,249,242,233,236,236,233, 99,128,  4, 41,+    229,233,227,239,240,244,233, 99,128,  3,226,232,225,227,249,242,+    233,236,236,233, 99,128,  4,186,233,237,225,227,239,240,244,233,+     99,128,  3,236,105,  2, 27, 90, 27, 96,231,237, 97,128,  3,163,+    248,242,239,237,225,110,128, 33,101,237,239,238,239,243,240,225,+    227,101,128,255, 51,239,230,244,243,233,231,238,227,249,242,233,+    236,236,233, 99,128,  4, 44,243,237,225,236,108,128,247,115,244,+    233,231,237,225,231,242,229,229,107,128,  3,218, 84,141,  0, 84,+     27,186, 27,191, 27,197, 28,  7, 28, 32, 28, 96, 28,147, 28,177,+     28,189, 28,201, 28,246, 29,  6, 29, 46,225,117,128,  3,164,226,+    225,114,128,  1,102, 99,  4, 27,207, 27,214, 27,223, 27,250,225,+    242,239,110,128,  1,100,229,228,233,236,236, 97,128,  1, 98,233,+    242, 99,  2, 27,231, 27,236,236,101,128, 36,201,245,237,230,236,+    229,248,226,229,236,239,119,128, 30,112,239,237,237,225,225,227,+    227,229,238,116,128,  1, 98,228,239,116,  2, 28, 15, 28, 24,225,+    227,227,229,238,116,128, 30,106,226,229,236,239,119,128, 30,108,+    101,  4, 28, 42, 28, 53, 28, 73, 28, 82,227,249,242,233,236,236,+    233, 99,128,  4, 34,228,229,243,227,229,238,228,229,242,227,249,+    242,233,236,236,233, 99,128,  4,172,238,242,239,237,225,110,128,+     33,105,244,243,229,227,249,242,233,236,236,233, 99,128,  4,180,+    104,  3, 28,104, 28,110, 28,136,229,244, 97,128,  3,152,111,  2,+     28,116, 28,121,239,107,128,  1,172,242,110,129,  0,222, 28,128,+    243,237,225,236,108,128,247,254,242,229,229,242,239,237,225,110,+    128, 33, 98,105,  2, 28,153, 28,164,236,228,229,243,237,225,236,+    108,128,246,254,247,238,225,242,237,229,238,233,225,110,128,  5,+     79,236,233,238,229,226,229,236,239,119,128, 30,110,237,239,238,+    239,243,240,225,227,101,128,255, 52,111,  2, 28,207, 28,218,225,+    242,237,229,238,233,225,110,128,  5, 57,238,101,  3, 28,227, 28,+    234, 28,240,230,233,246,101,128,  1,188,243,233,120,128,  1,132,+    244,247,111,128,  1,167,242,229,244,242,239,230,236,229,248,232,+    239,239,107,128,  1,174,115,  3, 29, 14, 29, 26, 29, 39,229,227,+    249,242,233,236,236,233, 99,128,  4, 38,232,229,227,249,242,233,+    236,236,233, 99,128,  4, 11,237,225,236,108,128,247,116,119,  2,+     29, 52, 29, 64,229,236,246,229,242,239,237,225,110,128, 33,107,+    239,242,239,237,225,110,128, 33, 97, 85,142,  0, 85, 29,105, 29,+    123, 29,131, 29,198, 30, 69, 30, 87, 30,198, 30,214, 30,226, 31,+     21, 31, 30, 31,142, 31,149, 31,219,225,227,245,244,101,129,  0,+    218, 29,115,243,237,225,236,108,128,247,250,226,242,229,246,101,+    128,  1,108, 99,  3, 29,139, 29,146, 29,188,225,242,239,110,128,+      1,211,233,242, 99,  2, 29,154, 29,159,236,101,128, 36,202,245,+    237,230,236,229,120,130,  0,219, 29,172, 29,180,226,229,236,239,+    119,128, 30,118,243,237,225,236,108,128,247,251,249,242,233,236,+    236,233, 99,128,  4, 35,100,  3, 29,206, 29,229, 30, 59,226,108,+      2, 29,213, 29,221,225,227,245,244,101,128,  1,112,231,242,225,+    246,101,128,  2, 20,233,229,242,229,243,233,115,134,  0,220, 29,+    251, 30,  3, 30, 11, 30, 34, 30, 42, 30, 51,225,227,245,244,101,+    128,  1,215,226,229,236,239,119,128, 30,114, 99,  2, 30, 17, 30,+     24,225,242,239,110,128,  1,217,249,242,233,236,236,233, 99,128,+      4,240,231,242,225,246,101,128,  1,219,237,225,227,242,239,110,+    128,  1,213,243,237,225,236,108,128,247,252,239,244,226,229,236,+    239,119,128, 30,228,231,242,225,246,101,129,  0,217, 30, 79,243,+    237,225,236,108,128,247,249,104,  2, 30, 93, 30,171,111,  2, 30,+     99, 30,109,239,235,225,226,239,246,101,128, 30,230,242,110,133,+      1,175, 30,124, 30,132, 30,143, 30,151, 30,163,225,227,245,244,+    101,128, 30,232,228,239,244,226,229,236,239,119,128, 30,240,231,+    242,225,246,101,128, 30,234,232,239,239,235,225,226,239,246,101,+    128, 30,236,244,233,236,228,101,128, 30,238,245,238,231,225,242,+    245,237,236,225,245,116,129,  1,112, 30,187,227,249,242,233,236,+    236,233, 99,128,  4,242,233,238,246,229,242,244,229,228,226,242,+    229,246,101,128,  2, 22,235,227,249,242,233,236,236,233, 99,128,+      4,120,109,  2, 30,232, 31, 10,225,227,242,239,110,130,  1,106,+     30,244, 30,255,227,249,242,233,236,236,233, 99,128,  4,238,228,+    233,229,242,229,243,233,115,128, 30,122,239,238,239,243,240,225,+    227,101,128,255, 53,239,231,239,238,229,107,128,  1,114,240,243,+    233,236,239,110,133,  3,165, 31, 49, 31, 53, 31, 90, 31,121, 31,+    134, 49,128,  3,210, 97,  2, 31, 59, 31, 81,227,245,244,229,232,+    239,239,235,243,249,237,226,239,236,231,242,229,229,107,128,  3,+    211,230,242,233,227,225,110,128,  1,177,228,233,229,242,229,243,+    233,115,129,  3,171, 31,103,232,239,239,235,243,249,237,226,239,+    236,231,242,229,229,107,128,  3,212,232,239,239,235,243,249,237,+    226,239,108,128,  3,210,244,239,238,239,115,128,  3,142,242,233,+    238,103,128,  1,110,115,  3, 31,157, 31,172, 31,179,232,239,242,+    244,227,249,242,233,236,236,233, 99,128,  4, 14,237,225,236,108,+    128,247,117,244,242,225,233,231,232,116,  2, 31,191, 31,202,227,+    249,242,233,236,236,233, 99,128,  4,174,243,244,242,239,235,229,+    227,249,242,233,236,236,233, 99,128,  4,176,244,233,236,228,101,+    130,  1,104, 31,231, 31,239,225,227,245,244,101,128, 30,120,226,+    229,236,239,119,128, 30,116, 86,136,  0, 86, 32, 11, 32, 20, 32,+     31, 32, 60, 32, 67, 32, 79, 32, 91, 32, 99,227,233,242,227,236,+    101,128, 36,203,228,239,244,226,229,236,239,119,128, 30,126,101,+      2, 32, 37, 32, 48,227,249,242,233,236,236,233, 99,128,  4, 18,+    247,225,242,237,229,238,233,225,110,128,  5, 78,232,239,239,107,+    128,  1,178,237,239,238,239,243,240,225,227,101,128,255, 54,239,+    225,242,237,229,238,233,225,110,128,  5, 72,243,237,225,236,108,+    128,247,118,244,233,236,228,101,128, 30,124, 87,134,  0, 87, 32,+    123, 32,131, 32,154, 32,194, 32,202, 32,214,225,227,245,244,101,+    128, 30,130,227,233,242, 99,  2, 32,140, 32,145,236,101,128, 36,+    204,245,237,230,236,229,120,128,  1,116,100,  2, 32,160, 32,170,+    233,229,242,229,243,233,115,128, 30,132,239,116,  2, 32,177, 32,+    186,225,227,227,229,238,116,128, 30,134,226,229,236,239,119,128,+     30,136,231,242,225,246,101,128, 30,128,237,239,238,239,243,240,+    225,227,101,128,255, 55,243,237,225,236,108,128,247,119, 88,134,+      0, 88, 32,238, 32,247, 33, 18, 33, 31, 33, 35, 33, 47,227,233,+    242,227,236,101,128, 36,205,100,  2, 32,253, 33,  7,233,229,242,+    229,243,233,115,128, 30,140,239,244,225,227,227,229,238,116,128,+     30,138,229,232,225,242,237,229,238,233,225,110,128,  5, 61,105,+    128,  3,158,237,239,238,239,243,240,225,227,101,128,255, 56,243,+    237,225,236,108,128,247,120, 89,139,  0, 89, 33, 81, 33,116, 33,+    139, 33,189, 33,228, 33,236, 33,253, 34, 40, 34, 52, 34, 60, 34,+     68, 97,  2, 33, 87, 33,104,227,245,244,101,129,  0,221, 33, 96,+    243,237,225,236,108,128,247,253,244,227,249,242,233,236,236,233,+     99,128,  4, 98,227,233,242, 99,  2, 33,125, 33,130,236,101,128,+     36,206,245,237,230,236,229,120,128,  1,118,100,  2, 33,145, 33,+    165,233,229,242,229,243,233,115,129,  1,120, 33,157,243,237,225,+    236,108,128,247,255,239,116,  2, 33,172, 33,181,225,227,227,229,+    238,116,128, 30,142,226,229,236,239,119,128, 30,244,229,114,  2,+     33,196, 33,208,233,227,249,242,233,236,236,233, 99,128,  4, 43,+    245,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233,+     99,128,  4,248,231,242,225,246,101,128, 30,242,232,239,239,107,+    129,  1,179, 33,245,225,226,239,246,101,128, 30,246,105,  3, 34,+      5, 34, 16, 34, 27,225,242,237,229,238,233,225,110,128,  5, 69,+    227,249,242,233,236,236,233, 99,128,  4,  7,247,238,225,242,237,+    229,238,233,225,110,128,  5, 82,237,239,238,239,243,240,225,227,+    101,128,255, 57,243,237,225,236,108,128,247,121,244,233,236,228,+    101,128, 30,248,245,115,  2, 34, 75, 34,113,226,233,103,  2, 34,+     83, 34, 94,227,249,242,233,236,236,233, 99,128,  4,106,233,239,+    244,233,230,233,229,228,227,249,242,233,236,236,233, 99,128,  4,+    108,236,233,244,244,236,101,  2, 34,124, 34,135,227,249,242,233,+    236,236,233, 99,128,  4,102,233,239,244,233,230,233,229,228,227,+    249,242,233,236,236,233, 99,128,  4,104, 90,136,  0, 90, 34,174,+     34,198, 34,243, 35, 14, 35, 81, 35,173, 35,185, 35,197, 97,  2,+     34,180, 34,191,225,242,237,229,238,233,225,110,128,  5, 54,227,+    245,244,101,128,  1,121, 99,  2, 34,204, 34,221,225,242,239,110,+    129,  1,125, 34,213,243,237,225,236,108,128,246,255,233,242, 99,+      2, 34,229, 34,234,236,101,128, 36,207,245,237,230,236,229,120,+    128, 30,144,228,239,116,130,  1,123, 34,253, 35,  6,225,227,227,+    229,238,116,128,  1,123,226,229,236,239,119,128, 30,146,101,  3,+     35, 22, 35, 33, 35, 76,227,249,242,233,236,236,233, 99,128,  4,+     23,100,  2, 35, 39, 35, 58,229,243,227,229,238,228,229,242,227,+    249,242,233,236,236,233, 99,128,  4,152,233,229,242,229,243,233,+    243,227,249,242,233,236,236,233, 99,128,  4,222,244, 97,128,  3,+    150,232,101,  4, 35, 92, 35,103, 35,119, 35,130,225,242,237,229,+    238,233,225,110,128,  5, 58,226,242,229,246,229,227,249,242,233,+    236,236,233, 99,128,  4,193,227,249,242,233,236,236,233, 99,128,+      4, 22,100,  2, 35,136, 35,155,229,243,227,229,238,228,229,242,+    227,249,242,233,236,236,233, 99,128,  4,150,233,229,242,229,243,+    233,243,227,249,242,233,236,236,233, 99,128,  4,220,236,233,238,+    229,226,229,236,239,119,128, 30,148,237,239,238,239,243,240,225,+    227,101,128,255, 58,115,  2, 35,203, 35,210,237,225,236,108,128,+    247,122,244,242,239,235,101,128,  1,181, 97,149,  0, 97, 36,  8,+     36,144, 37, 35, 37,211, 38, 55, 38, 91, 45, 10, 45, 47, 45, 74,+     46, 43, 46, 81, 47,170, 47,242, 48,197, 48,206, 49, 79, 51, 87,+     52, 77, 52,124, 53, 19, 53, 33, 97,  7, 36, 24, 36, 34, 36, 41,+     36, 48, 36, 73, 36, 89, 36,100,226,229,238,231,225,236,105,128,+      9,134,227,245,244,101,128,  0,225,228,229,246, 97,128,  9,  6,+    231,117,  2, 36, 55, 36, 64,234,225,242,225,244,105,128, 10,134,+    242,237,245,235,232,105,128, 10,  6,237,225,244,242,225,231,245,+    242,237,245,235,232,105,128, 10, 62,242,245,243,241,245,225,242,+    101,128, 51,  3,246,239,247,229,236,243,233,231,110,  3, 36,116,+     36,126, 36,133,226,229,238,231,225,236,105,128,  9,190,228,229,+    246, 97,128,  9, 62,231,245,234,225,242,225,244,105,128, 10,190,+     98,  4, 36,154, 36,195, 36,204, 36,214,226,242,229,246,233,225,+    244,233,239,110,  2, 36,169, 36,184,237,225,242,235,225,242,237,+    229,238,233,225,110,128,  5, 95,243,233,231,238,228,229,246, 97,+    128,  9,112,229,238,231,225,236,105,128,  9,133,239,240,239,237,+    239,230,111,128, 49, 26,242,229,246,101,134,  1,  3, 36,233, 36,+    241, 36,252, 37,  7, 37, 15, 37, 27,225,227,245,244,101,128, 30,+    175,227,249,242,233,236,236,233, 99,128,  4,209,228,239,244,226,+    229,236,239,119,128, 30,183,231,242,225,246,101,128, 30,177,232,+    239,239,235,225,226,239,246,101,128, 30,179,244,233,236,228,101,+    128, 30,181, 99,  4, 37, 45, 37, 52, 37,131, 37,201,225,242,239,+    110,128,  1,206,233,242, 99,  2, 37, 60, 37, 65,236,101,128, 36,+    208,245,237,230,236,229,120,133,  0,226, 37, 84, 37, 92, 37,103,+     37,111, 37,123,225,227,245,244,101,128, 30,165,228,239,244,226,+    229,236,239,119,128, 30,173,231,242,225,246,101,128, 30,167,232,+    239,239,235,225,226,239,246,101,128, 30,169,244,233,236,228,101,+    128, 30,171,245,244,101,133,  0,180, 37,147, 37,158, 37,175, 37,+    182, 37,191,226,229,236,239,247,227,237, 98,128,  3, 23, 99,  2,+     37,164, 37,169,237, 98,128,  3,  1,239,237, 98,128,  3,  1,228,+    229,246, 97,128,  9, 84,236,239,247,237,239,100,128,  2,207,244,+    239,238,229,227,237, 98,128,  3, 65,249,242,233,236,236,233, 99,+    128,  4, 48,100,  5, 37,223, 37,233, 37,247, 37,253, 38, 31,226,+    236,231,242,225,246,101,128,  2,  1,228,225,235,231,245,242,237,+    245,235,232,105,128, 10,113,229,246, 97,128,  9,  5,233,229,242,+    229,243,233,115,130,  0,228, 38, 11, 38, 22,227,249,242,233,236,+    236,233, 99,128,  4,211,237,225,227,242,239,110,128,  1,223,239,+    116,  2, 38, 38, 38, 46,226,229,236,239,119,128, 30,161,237,225,+    227,242,239,110,128,  1,225,101,131,  0,230, 38, 65, 38, 73, 38,+     82,225,227,245,244,101,128,  1,253,235,239,242,229,225,110,128,+     49, 80,237,225,227,242,239,110,128,  1,227,230,233,105,  6, 38,+    107, 38,127, 41, 64, 41, 70, 41, 85, 44,185, 48,  2, 38,113, 38,+    120,176,178,176, 56,128, 32, 21,184,185,180, 49,128, 32,164,177,+     48,  3, 38,136, 40,160, 41, 39, 48,  9, 38,156, 38,176, 38,238,+     39, 44, 39,106, 39,168, 39,230, 40, 36, 40, 98, 49,  3, 38,164,+     38,168, 38,172, 55,128,  4, 16, 56,128,  4, 17, 57,128,  4, 18,+     50, 10, 38,198, 38,202, 38,206, 38,210, 38,214, 38,218, 38,222,+     38,226, 38,230, 38,234, 48,128,  4, 19, 49,128,  4, 20, 50,128,+      4, 21, 51,128,  4,  1, 52,128,  4, 22, 53,128,  4, 23, 54,128,+      4, 24, 55,128,  4, 25, 56,128,  4, 26, 57,128,  4, 27, 51, 10,+     39,  4, 39,  8, 39, 12, 39, 16, 39, 20, 39, 24, 39, 28, 39, 32,+     39, 36, 39, 40, 48,128,  4, 28, 49,128,  4, 29, 50,128,  4, 30,+     51,128,  4, 31, 52,128,  4, 32, 53,128,  4, 33, 54,128,  4, 34,+     55,128,  4, 35, 56,128,  4, 36, 57,128,  4, 37, 52, 10, 39, 66,+     39, 70, 39, 74, 39, 78, 39, 82, 39, 86, 39, 90, 39, 94, 39, 98,+     39,102, 48,128,  4, 38, 49,128,  4, 39, 50,128,  4, 40, 51,128,+      4, 41, 52,128,  4, 42, 53,128,  4, 43, 54,128,  4, 44, 55,128,+      4, 45, 56,128,  4, 46, 57,128,  4, 47, 53, 10, 39,128, 39,132,+     39,136, 39,140, 39,144, 39,148, 39,152, 39,156, 39,160, 39,164,+     48,128,  4,144, 49,128,  4,  2, 50,128,  4,  3, 51,128,  4,  4,+     52,128,  4,  5, 53,128,  4,  6, 54,128,  4,  7, 55,128,  4,  8,+     56,128,  4,  9, 57,128,  4, 10, 54, 10, 39,190, 39,194, 39,198,+     39,202, 39,206, 39,210, 39,214, 39,218, 39,222, 39,226, 48,128,+      4, 11, 49,128,  4, 12, 50,128,  4, 14, 51,128,246,196, 52,128,+    246,197, 53,128,  4, 48, 54,128,  4, 49, 55,128,  4, 50, 56,128,+      4, 51, 57,128,  4, 52, 55, 10, 39,252, 40,  0, 40,  4, 40,  8,+     40, 12, 40, 16, 40, 20, 40, 24, 40, 28, 40, 32, 48,128,  4, 53,+     49,128,  4, 81, 50,128,  4, 54, 51,128,  4, 55, 52,128,  4, 56,+     53,128,  4, 57, 54,128,  4, 58, 55,128,  4, 59, 56,128,  4, 60,+     57,128,  4, 61, 56, 10, 40, 58, 40, 62, 40, 66, 40, 70, 40, 74,+     40, 78, 40, 82, 40, 86, 40, 90, 40, 94, 48,128,  4, 62, 49,128,+      4, 63, 50,128,  4, 64, 51,128,  4, 65, 52,128,  4, 66, 53,128,+      4, 67, 54,128,  4, 68, 55,128,  4, 69, 56,128,  4, 70, 57,128,+      4, 71, 57, 10, 40,120, 40,124, 40,128, 40,132, 40,136, 40,140,+     40,144, 40,148, 40,152, 40,156, 48,128,  4, 72, 49,128,  4, 73,+     50,128,  4, 74, 51,128,  4, 75, 52,128,  4, 76, 53,128,  4, 77,+     54,128,  4, 78, 55,128,  4, 79, 56,128,  4,145, 57,128,  4, 82,+     49,  4, 40,170, 40,232, 40,237, 41,  7, 48, 10, 40,192, 40,196,+     40,200, 40,204, 40,208, 40,212, 40,216, 40,220, 40,224, 40,228,+     48,128,  4, 83, 49,128,  4, 84, 50,128,  4, 85, 51,128,  4, 86,+     52,128,  4, 87, 53,128,  4, 88, 54,128,  4, 89, 55,128,  4, 90,+     56,128,  4, 91, 57,128,  4, 92,177, 48,128,  4, 94, 52,  4, 40,+    247, 40,251, 40,255, 41,  3, 53,128,  4, 15, 54,128,  4, 98, 55,+    128,  4,114, 56,128,  4,116, 57,  5, 41, 19, 41, 23, 41, 27, 41,+     31, 41, 35, 50,128,246,198, 51,128,  4, 95, 52,128,  4, 99, 53,+    128,  4,115, 54,128,  4,117, 56,  2, 41, 45, 41, 59, 51,  2, 41,+     51, 41, 55, 49,128,246,199, 50,128,246,200,180, 54,128,  4,217,+    178,185, 57,128, 32, 14,179, 48,  2, 41, 77, 41, 81, 48,128, 32,+     15, 49,128, 32, 13,181, 55,  7, 41,102, 41,172, 42,237, 43, 58,+     44, 15, 44,108, 44,179, 51,  2, 41,108, 41,122, 56,  2, 41,114,+     41,118, 49,128,  6,106, 56,128,  6, 12, 57,  8, 41,140, 41,144,+     41,148, 41,152, 41,156, 41,160, 41,164, 41,168, 50,128,  6, 96,+     51,128,  6, 97, 52,128,  6, 98, 53,128,  6, 99, 54,128,  6,100,+     55,128,  6,101, 56,128,  6,102, 57,128,  6,103, 52,  7, 41,188,+     41,220, 42, 26, 42, 88, 42,120, 42,176, 42,232, 48,  5, 41,200,+     41,204, 41,208, 41,212, 41,216, 48,128,  6,104, 49,128,  6,105,+     51,128,  6, 27, 55,128,  6, 31, 57,128,  6, 33, 49, 10, 41,242,+     41,246, 41,250, 41,254, 42,  2, 42,  6, 42, 10, 42, 14, 42, 18,+     42, 22, 48,128,  6, 34, 49,128,  6, 35, 50,128,  6, 36, 51,128,+      6, 37, 52,128,  6, 38, 53,128,  6, 39, 54,128,  6, 40, 55,128,+      6, 41, 56,128,  6, 42, 57,128,  6, 43, 50, 10, 42, 48, 42, 52,+     42, 56, 42, 60, 42, 64, 42, 68, 42, 72, 42, 76, 42, 80, 42, 84,+     48,128,  6, 44, 49,128,  6, 45, 50,128,  6, 46, 51,128,  6, 47,+     52,128,  6, 48, 53,128,  6, 49, 54,128,  6, 50, 55,128,  6, 51,+     56,128,  6, 52, 57,128,  6, 53, 51,  5, 42,100, 42,104, 42,108,+     42,112, 42,116, 48,128,  6, 54, 49,128,  6, 55, 50,128,  6, 56,+     51,128,  6, 57, 52,128,  6, 58, 52,  9, 42,140, 42,144, 42,148,+     42,152, 42,156, 42,160, 42,164, 42,168, 42,172, 48,128,  6, 64,+     49,128,  6, 65, 50,128,  6, 66, 51,128,  6, 67, 52,128,  6, 68,+     53,128,  6, 69, 54,128,  6, 70, 56,128,  6, 72, 57,128,  6, 73,+     53,  9, 42,196, 42,200, 42,204, 42,208, 42,212, 42,216, 42,220,+     42,224, 42,228, 48,128,  6, 74, 49,128,  6, 75, 50,128,  6, 76,+     51,128,  6, 77, 52,128,  6, 78, 53,128,  6, 79, 54,128,  6, 80,+     55,128,  6, 81, 56,128,  6, 82,183, 48,128,  6, 71, 53,  3, 42,+    245, 43, 21, 43, 53, 48,  5, 43,  1, 43,  5, 43,  9, 43, 13, 43,+     17, 53,128,  6,164, 54,128,  6,126, 55,128,  6,134, 56,128,  6,+    152, 57,128,  6,175, 49,  5, 43, 33, 43, 37, 43, 41, 43, 45, 43,+     49, 49,128,  6,121, 50,128,  6,136, 51,128,  6,145, 52,128,  6,+    186, 57,128,  6,210,179, 52,128,  6,213, 54,  7, 43, 74, 43, 79,+     43, 84, 43, 89, 43,127, 43,189, 43,251,179, 54,128, 32,170,180,+     53,128,  5,190,181, 56,128,  5,195, 54,  6, 43,103, 43,107, 43,+    111, 43,115, 43,119, 43,123, 52,128,  5,208, 53,128,  5,209, 54,+    128,  5,210, 55,128,  5,211, 56,128,  5,212, 57,128,  5,213, 55,+     10, 43,149, 43,153, 43,157, 43,161, 43,165, 43,169, 43,173, 43,+    177, 43,181, 43,185, 48,128,  5,214, 49,128,  5,215, 50,128,  5,+    216, 51,128,  5,217, 52,128,  5,218, 53,128,  5,219, 54,128,  5,+    220, 55,128,  5,221, 56,128,  5,222, 57,128,  5,223, 56, 10, 43,+    211, 43,215, 43,219, 43,223, 43,227, 43,231, 43,235, 43,239, 43,+    243, 43,247, 48,128,  5,224, 49,128,  5,225, 50,128,  5,226, 51,+    128,  5,227, 52,128,  5,228, 53,128,  5,229, 54,128,  5,230, 55,+    128,  5,231, 56,128,  5,232, 57,128,  5,233, 57,  3, 44,  3, 44,+      7, 44, 11, 48,128,  5,234, 52,128,251, 42, 53,128,251, 43, 55,+      4, 44, 25, 44, 39, 44, 59, 44, 64, 48,  2, 44, 31, 44, 35, 48,+    128,251, 75, 53,128,251, 31, 49,  3, 44, 47, 44, 51, 44, 55, 54,+    128,  5,240, 55,128,  5,241, 56,128,  5,242,178, 51,128,251, 53,+     57,  7, 44, 80, 44, 84, 44, 88, 44, 92, 44, 96, 44,100, 44,104,+     51,128,  5,180, 52,128,  5,181, 53,128,  5,182, 54,128,  5,187,+     55,128,  5,184, 56,128,  5,183, 57,128,  5,176, 56,  3, 44,116,+     44,160, 44,165, 48,  7, 44,132, 44,136, 44,140, 44,144, 44,148,+     44,152, 44,156, 48,128,  5,178, 49,128,  5,177, 50,128,  5,179,+     51,128,  5,194, 52,128,  5,193, 54,128,  5,185, 55,128,  5,188,+    179, 57,128,  5,189, 52,  2, 44,171, 44,175, 49,128,  5,191, 50,+    128,  5,192,185,178, 57,128,  2,188, 54,  3, 44,193, 44,252, 45,+      3, 49,  4, 44,203, 44,219, 44,225, 44,246, 50,  2, 44,209, 44,+    214,180, 56,128, 33,  5,184, 57,128, 33, 19,179,181, 50,128, 33,+     22,181, 55,  3, 44,234, 44,238, 44,242, 51,128, 32, 44, 52,128,+     32, 45, 53,128, 32, 46,182,182, 52,128, 32, 12,179,177,182, 55,+    128,  6,109,180,185,179, 55,128,  2,189,103,  2, 45, 16, 45, 23,+    242,225,246,101,128,  0,224,117,  2, 45, 29, 45, 38,234,225,242,+    225,244,105,128, 10,133,242,237,245,235,232,105,128, 10,  5,104,+      2, 45, 53, 45, 63,233,242,225,231,225,238, 97,128, 48, 66,239,+    239,235,225,226,239,246,101,128, 30,163,105,  7, 45, 90, 45,115,+     45,122, 45,134, 45,159, 45,175, 45,255, 98,  2, 45, 96, 45,105,+    229,238,231,225,236,105,128,  9,144,239,240,239,237,239,230,111,+    128, 49, 30,228,229,246, 97,128,  9, 16,229,227,249,242,233,236,+    236,233, 99,128,  4,213,231,117,  2, 45,141, 45,150,234,225,242,+    225,244,105,128, 10,144,242,237,245,235,232,105,128, 10, 16,237,+    225,244,242,225,231,245,242,237,245,235,232,105,128, 10, 72,110,+      5, 45,187, 45,196, 45,210, 45,226, 45,241,225,242,225,226,233,+     99,128,  6, 57,230,233,238,225,236,225,242,225,226,233, 99,128,+    254,202,233,238,233,244,233,225,236,225,242,225,226,233, 99,128,+    254,203,237,229,228,233,225,236,225,242,225,226,233, 99,128,254,+    204,246,229,242,244,229,228,226,242,229,246,101,128,  2,  3,246,+    239,247,229,236,243,233,231,110,  3, 46, 15, 46, 25, 46, 32,226,+    229,238,231,225,236,105,128,  9,200,228,229,246, 97,128,  9, 72,+    231,245,234,225,242,225,244,105,128, 10,200,107,  2, 46, 49, 46,+     73,225,244,225,235,225,238, 97,129, 48,162, 46, 61,232,225,236,+    230,247,233,228,244,104,128,255,113,239,242,229,225,110,128, 49,+     79,108,  3, 46, 89, 47,145, 47,154,101,  2, 46, 95, 47,140,102,+    136,  5,208, 46,115, 46,124, 46,139, 46,153, 46,242, 47,  0, 47,+    111, 47,125,225,242,225,226,233, 99,128,  6, 39,228,225,231,229,+    243,232,232,229,226,242,229,119,128,251, 48,230,233,238,225,236,+    225,242,225,226,233, 99,128,254,142,104,  2, 46,159, 46,234,225,+    237,250, 97,  2, 46,168, 46,201,225,226,239,246,101,  2, 46,178,+     46,187,225,242,225,226,233, 99,128,  6, 35,230,233,238,225,236,+    225,242,225,226,233, 99,128,254,132,226,229,236,239,119,  2, 46,+    211, 46,220,225,242,225,226,233, 99,128,  6, 37,230,233,238,225,+    236,225,242,225,226,233, 99,128,254,136,229,226,242,229,119,128,+      5,208,236,225,237,229,228,232,229,226,242,229,119,128,251, 79,+    237, 97,  2, 47,  7, 47, 43,228,228,225,225,226,239,246,101,  2,+     47, 20, 47, 29,225,242,225,226,233, 99,128,  6, 34,230,233,238,+    225,236,225,242,225,226,233, 99,128,254,130,235,243,245,242, 97,+      4, 47, 57, 47, 66, 47, 80, 47, 96,225,242,225,226,233, 99,128,+      6, 73,230,233,238,225,236,225,242,225,226,233, 99,128,254,240,+    233,238,233,244,233,225,236,225,242,225,226,233, 99,128,254,243,+    237,229,228,233,225,236,225,242,225,226,233, 99,128,254,244,240,+    225,244,225,232,232,229,226,242,229,119,128,251, 46,241,225,237,+    225,244,243,232,229,226,242,229,119,128,251, 47,240,104,128, 33,+     53,236,229,241,245,225,108,128, 34, 76,240,232, 97,129,  3,177,+     47,162,244,239,238,239,115,128,  3,172,109,  4, 47,180, 47,188,+     47,199, 47,233,225,227,242,239,110,128,  1,  1,239,238,239,243,+    240,225,227,101,128,255, 65,240,229,242,243,225,238,100,130,  0,+     38, 47,213, 47,225,237,239,238,239,243,240,225,227,101,128,255,+      6,243,237,225,236,108,128,247, 38,243,241,245,225,242,101,128,+     51,194,110,  4, 47,252, 48,  7, 48,129, 48,139,226,239,240,239,+    237,239,230,111,128, 49, 34,103,  4, 48, 17, 48, 28, 48, 42, 48,+    121,226,239,240,239,237,239,230,111,128, 49, 36,235,232,225,238,+    235,232,245,244,232,225,105,128, 14, 90,236,101,131, 34, 32, 48,+     53, 48,106, 48,113,226,242,225,227,235,229,116,  2, 48, 65, 48,+     85,236,229,230,116,129, 48,  8, 48, 74,246,229,242,244,233,227,+    225,108,128,254, 63,242,233,231,232,116,129, 48,  9, 48, 95,246,+    229,242,244,233,227,225,108,128,254, 64,236,229,230,116,128, 35,+     41,242,233,231,232,116,128, 35, 42,243,244,242,239,109,128, 33,+     43,239,244,229,236,229,233, 97,128,  3,135,117,  2, 48,145, 48,+    157,228,225,244,244,225,228,229,246, 97,128,  9, 82,243,246,225,+    242, 97,  3, 48,169, 48,179, 48,186,226,229,238,231,225,236,105,+    128,  9,130,228,229,246, 97,128,  9,  2,231,245,234,225,242,225,+    244,105,128, 10,130,239,231,239,238,229,107,128,  1,  5,112,  3,+     48,214, 48,238, 49, 12, 97,  2, 48,220, 48,232,225,244,239,243,+    241,245,225,242,101,128, 51,  0,242,229,110,128, 36,156,239,243,+    244,242,239,240,232,101,  2, 48,251, 49,  6,225,242,237,229,238,+    233,225,110,128,  5, 90,237,239,100,128,  2,188,112,  2, 49, 18,+     49, 23,236,101,128,248,255,242,111,  2, 49, 30, 49, 38,225,227,+    232,229,115,128, 34, 80,120,  2, 49, 44, 49, 64,229,241,245,225,+    108,129, 34, 72, 49, 54,239,242,233,237,225,231,101,128, 34, 82,+    233,237,225,244,229,236,249,229,241,245,225,108,128, 34, 69,114,+      4, 49, 89, 49,116, 49,120, 49,165,225,229, 97,  2, 49, 97, 49,+    107,229,235,239,242,229,225,110,128, 49,142,235,239,242,229,225,+    110,128, 49,141, 99,128, 35, 18,105,  2, 49,126, 49,140,231,232,+    244,232,225,236,230,242,233,238,103,128, 30,154,238,103,130,  0,+    229, 49,149, 49,157,225,227,245,244,101,128,  1,251,226,229,236,+    239,119,128, 30,  1,242,239,119,  8, 49,185, 49,192, 50, 65, 50,+    131, 50,181, 50,236, 51,  3, 51, 78,226,239,244,104,128, 33,148,+    100,  3, 49,200, 49,239, 50, 30,225,243,104,  4, 49,212, 49,219,+     49,226, 49,234,228,239,247,110,128, 33,227,236,229,230,116,128,+     33,224,242,233,231,232,116,128, 33,226,245,112,128, 33,225,226,+    108,  5, 49,252, 50,  3, 50, 10, 50, 17, 50, 25,226,239,244,104,+    128, 33,212,228,239,247,110,128, 33,211,236,229,230,116,128, 33,+    208,242,233,231,232,116,128, 33,210,245,112,128, 33,209,239,247,+    110,131, 33,147, 50, 42, 50, 49, 50, 57,236,229,230,116,128, 33,+    153,242,233,231,232,116,128, 33,152,247,232,233,244,101,128, 33,+    233,104,  2, 50, 71, 50,122,229,225,100,  4, 50, 83, 50, 93, 50,+    103, 50,114,228,239,247,238,237,239,100,128,  2,197,236,229,230,+    244,237,239,100,128,  2,194,242,233,231,232,244,237,239,100,128,+      2,195,245,240,237,239,100,128,  2,196,239,242,233,250,229,120,+    128,248,231,236,229,230,116,131, 33,144, 50,144, 50,161, 50,173,+    228,226,108,129, 33,208, 50,152,243,244,242,239,235,101,128, 33,+    205,239,246,229,242,242,233,231,232,116,128, 33,198,247,232,233,+    244,101,128, 33,230,242,233,231,232,116,132, 33,146, 50,197, 50,+    209, 50,217, 50,228,228,226,236,243,244,242,239,235,101,128, 33,+    207,232,229,225,246,121,128, 39,158,239,246,229,242,236,229,230,+    116,128, 33,196,247,232,233,244,101,128, 33,232,244,225, 98,  2,+     50,244, 50,251,236,229,230,116,128, 33,228,242,233,231,232,116,+    128, 33,229,245,112,132, 33,145, 51, 16, 51, 44, 51, 62, 51, 70,+    100,  2, 51, 22, 51, 34,110,129, 33,149, 51, 28,226,243,101,128,+     33,168,239,247,238,226,225,243,101,128, 33,168,236,229,230,116,+    129, 33,150, 51, 53,239,230,228,239,247,110,128, 33,197,242,233,+    231,232,116,128, 33,151,247,232,233,244,101,128, 33,231,246,229,+    242,244,229,120,128,248,230,115,  5, 51, 99, 51,175, 51,220, 52,+     47, 52, 57, 99,  2, 51,105, 51,157,233,105,  2, 51,112, 51,135,+    227,233,242,227,245,109,129,  0, 94, 51,123,237,239,238,239,243,+    240,225,227,101,128,255, 62,244,233,236,228,101,129,  0,126, 51,+    145,237,239,238,239,243,240,225,227,101,128,255, 94,242,233,240,+    116,129,  2, 81, 51,166,244,245,242,238,229,100,128,  2, 82,237,+    225,236,108,  2, 51,184, 51,195,232,233,242,225,231,225,238, 97,+    128, 48, 65,235,225,244,225,235,225,238, 97,129, 48,161, 51,208,+    232,225,236,230,247,233,228,244,104,128,255,103,244,229,242,233,+    115,  2, 51,230, 52, 43,107,131,  0, 42, 51,240, 52, 12, 52, 35,+     97,  2, 51,246, 52,  4,236,244,239,238,229,225,242,225,226,233,+     99,128,  6,109,242,225,226,233, 99,128,  6,109,109,  2, 52, 18,+     52, 24,225,244,104,128, 34, 23,239,238,239,243,240,225,227,101,+    128,255, 10,243,237,225,236,108,128,254, 97,109,128, 32, 66,245,+    240,229,242,233,239,114,128,246,233,249,237,240,244,239,244,233,+    227,225,236,236,249,229,241,245,225,108,128, 34, 67,116,132,  0,+     64, 52, 89, 52, 96, 52,108, 52,116,233,236,228,101,128,  0,227,+    237,239,238,239,243,240,225,227,101,128,255, 32,243,237,225,236,+    108,128,254,107,245,242,238,229,100,128,  2, 80,117,  6, 52,138,+     52,163, 52,170, 52,195, 52,215, 52,231, 98,  2, 52,144, 52,153,+    229,238,231,225,236,105,128,  9,148,239,240,239,237,239,230,111,+    128, 49, 32,228,229,246, 97,128,  9, 20,231,117,  2, 52,177, 52,+    186,234,225,242,225,244,105,128, 10,148,242,237,245,235,232,105,+    128, 10, 20,236,229,238,231,244,232,237,225,242,235,226,229,238,+    231,225,236,105,128,  9,215,237,225,244,242,225,231,245,242,237,+    245,235,232,105,128, 10, 76,246,239,247,229,236,243,233,231,110,+      3, 52,247, 53,  1, 53,  8,226,229,238,231,225,236,105,128,  9,+    204,228,229,246, 97,128,  9, 76,231,245,234,225,242,225,244,105,+    128, 10,204,246,225,231,242,225,232,225,228,229,246, 97,128,  9,+     61,121,  2, 53, 39, 53, 51,226,225,242,237,229,238,233,225,110,+    128,  5, 97,233,110,130,  5,226, 53, 60, 53, 75,225,236,244,239,+    238,229,232,229,226,242,229,119,128,251, 32,232,229,226,242,229,+    119,128,  5,226, 98,144,  0, 98, 53,120, 53,255, 54, 10, 54, 19,+     54, 44, 55, 85, 55,147, 55,220, 57,146, 57,158, 57,201, 57,209,+     57,219, 59, 89, 59,113, 59,122, 97,  7, 53,136, 53,146, 53,170,+     53,177, 53,202, 53,226, 53,237,226,229,238,231,225,236,105,128,+      9,172,227,235,243,236,225,243,104,129,  0, 92, 53,158,237,239,+    238,239,243,240,225,227,101,128,255, 60,228,229,246, 97,128,  9,+     44,231,117,  2, 53,184, 53,193,234,225,242,225,244,105,128, 10,+    172,242,237,245,235,232,105,128, 10, 44,104,  2, 53,208, 53,218,+    233,242,225,231,225,238, 97,128, 48,112,244,244,232,225,105,128,+     14, 63,235,225,244,225,235,225,238, 97,128, 48,208,114,129,  0,+    124, 53,243,237,239,238,239,243,240,225,227,101,128,255, 92,226,+    239,240,239,237,239,230,111,128, 49,  5,227,233,242,227,236,101,+    128, 36,209,228,239,116,  2, 54, 27, 54, 36,225,227,227,229,238,+    116,128, 30,  3,226,229,236,239,119,128, 30,  5,101,  6, 54, 58,+     54, 79, 54,102, 54,244, 54,255, 55, 11,225,237,229,228,243,233,+    248,244,229,229,238,244,232,238,239,244,229,115,128, 38,108, 99,+      2, 54, 85, 54, 92,225,245,243,101,128, 34, 53,249,242,233,236,+    236,233, 99,128,  4, 49,104,  5, 54,114, 54,123, 54,137, 54,167,+     54,226,225,242,225,226,233, 99,128,  6, 40,230,233,238,225,236,+    225,242,225,226,233, 99,128,254,144,105,  2, 54,143, 54,158,238,+    233,244,233,225,236,225,242,225,226,233, 99,128,254,145,242,225,+    231,225,238, 97,128, 48,121,237,101,  2, 54,174, 54,187,228,233,+    225,236,225,242,225,226,233, 99,128,254,146,229,237,105,  2, 54,+    195, 54,210,238,233,244,233,225,236,225,242,225,226,233, 99,128,+    252,159,243,239,236,225,244,229,228,225,242,225,226,233, 99,128,+    252,  8,238,239,239,238,230,233,238,225,236,225,242,225,226,233,+     99,128,252,109,235,225,244,225,235,225,238, 97,128, 48,217,238,+    225,242,237,229,238,233,225,110,128,  5, 98,116,132,  5,209, 55,+     23, 55, 43, 55, 63, 55, 72, 97,129,  3,178, 55, 29,243,249,237,+    226,239,236,231,242,229,229,107,128,  3,208,228,225,231,229,243,+    104,129,251, 49, 55, 54,232,229,226,242,229,119,128,251, 49,232,+    229,226,242,229,119,128,  5,209,242,225,230,229,232,229,226,242,+    229,119,128,251, 76,104,  2, 55, 91, 55,141, 97,  3, 55, 99, 55,+    109, 55,116,226,229,238,231,225,236,105,128,  9,173,228,229,246,+     97,128,  9, 45,231,117,  2, 55,123, 55,132,234,225,242,225,244,+    105,128, 10,173,242,237,245,235,232,105,128, 10, 45,239,239,107,+    128,  2, 83,105,  5, 55,159, 55,170, 55,181, 55,195, 55,209,232,+    233,242,225,231,225,238, 97,128, 48,115,235,225,244,225,235,225,+    238, 97,128, 48,211,236,225,226,233,225,236,227,236,233,227,107,+    128,  2,152,238,228,233,231,245,242,237,245,235,232,105,128, 10,+      2,242,245,243,241,245,225,242,101,128, 51, 49,108,  3, 55,228,+     57,129, 57,140, 97,  2, 55,234, 57,124,227,107,  6, 55,249, 56,+      2, 56, 39, 56,188, 56,243, 57, 39,227,233,242,227,236,101,128,+     37,207,100,  2, 56,  8, 56, 17,233,225,237,239,238,100,128, 37,+    198,239,247,238,240,239,233,238,244,233,238,231,244,242,233,225,+    238,231,236,101,128, 37,188,108,  2, 56, 45, 56,148,101,  2, 56,+     51, 56, 87,230,244,240,239,233,238,244,233,238,103,  2, 56, 66,+     56, 76,240,239,233,238,244,229,114,128, 37,196,244,242,233,225,+    238,231,236,101,128, 37,192,238,244,233,227,245,236,225,242,226,+    242,225,227,235,229,116,  2, 56,107, 56,127,236,229,230,116,129,+     48, 16, 56,116,246,229,242,244,233,227,225,108,128,254, 59,242,+    233,231,232,116,129, 48, 17, 56,137,246,229,242,244,233,227,225,+    108,128,254, 60,239,247,229,114,  2, 56,157, 56,172,236,229,230,+    244,244,242,233,225,238,231,236,101,128, 37,227,242,233,231,232,+    244,244,242,233,225,238,231,236,101,128, 37,226,114,  2, 56,194,+     56,205,229,227,244,225,238,231,236,101,128, 37,172,233,231,232,+    244,240,239,233,238,244,233,238,103,  2, 56,222, 56,232,240,239,+    233,238,244,229,114,128, 37,186,244,242,233,225,238,231,236,101,+    128, 37,182,115,  3, 56,251, 57, 25, 57, 33,109,  2, 57,  1, 57,+     13,225,236,236,243,241,245,225,242,101,128, 37,170,233,236,233,+    238,231,230,225,227,101,128, 38, 59,241,245,225,242,101,128, 37,+    160,244,225,114,128, 38,  5,245,240,112,  2, 57, 47, 57, 85,229,+    114,  2, 57, 54, 57, 69,236,229,230,244,244,242,233,225,238,231,+    236,101,128, 37,228,242,233,231,232,244,244,242,233,225,238,231,+    236,101,128, 37,229,239,233,238,244,233,238,103,  2, 57, 97, 57,+    113,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37,+    180,244,242,233,225,238,231,236,101,128, 37,178,238,107,128, 36,+     35,233,238,229,226,229,236,239,119,128, 30,  7,239,227,107,128,+     37,136,237,239,238,239,243,240,225,227,101,128,255, 66,111,  3,+     57,166, 57,179, 57,190,226,225,233,237,225,233,244,232,225,105,+    128, 14, 26,232,233,242,225,231,225,238, 97,128, 48,124,235,225,+    244,225,235,225,238, 97,128, 48,220,240,225,242,229,110,128, 36,+    157,241,243,241,245,225,242,101,128, 51,195,114,  4, 57,229, 58,+    223, 59, 40, 59, 79,225, 99,  2, 57,236, 58,130,101,  3, 57,244,+     57,249, 58, 61,229,120,128,248,244,236,229,230,116,133,  0,123,+     58, 10, 58, 15, 58, 37, 58, 45, 58, 50,226,116,128,248,243,109,+      2, 58, 21, 58, 26,233,100,128,248,242,239,238,239,243,240,225,+    227,101,128,255, 91,243,237,225,236,108,128,254, 91,244,112,128,+    248,241,246,229,242,244,233,227,225,108,128,254, 55,242,233,231,+    232,116,133,  0,125, 58, 79, 58, 84, 58,106, 58,114, 58,119,226,+    116,128,248,254,109,  2, 58, 90, 58, 95,233,100,128,248,253,239,+    238,239,243,240,225,227,101,128,255, 93,243,237,225,236,108,128,+    254, 92,244,112,128,248,252,246,229,242,244,233,227,225,108,128,+    254, 56,235,229,116,  2, 58,138, 58,180,236,229,230,116,132,  0,+     91, 58,153, 58,158, 58,163, 58,175,226,116,128,248,240,229,120,+    128,248,239,237,239,238,239,243,240,225,227,101,128,255, 59,244,+    112,128,248,238,242,233,231,232,116,132,  0, 93, 58,196, 58,201,+     58,206, 58,218,226,116,128,248,251,229,120,128,248,250,237,239,+    238,239,243,240,225,227,101,128,255, 61,244,112,128,248,249,229,+    246,101,131,  2,216, 58,235, 58,246, 58,252,226,229,236,239,247,+    227,237, 98,128,  3, 46,227,237, 98,128,  3,  6,233,238,246,229,+    242,244,229,100,  3, 59, 11, 59, 22, 59, 28,226,229,236,239,247,+    227,237, 98,128,  3, 47,227,237, 98,128,  3, 17,228,239,245,226,+    236,229,227,237, 98,128,  3, 97,233,228,231,101,  2, 59, 49, 59,+     60,226,229,236,239,247,227,237, 98,128,  3, 42,233,238,246,229,+    242,244,229,228,226,229,236,239,247,227,237, 98,128,  3, 58,239,+    235,229,238,226,225,114,128,  0,166,115,  2, 59, 95, 59,103,244,+    242,239,235,101,128,  1,128,245,240,229,242,233,239,114,128,246,+    234,244,239,240,226,225,114,128,  1,131,117,  3, 59,130, 59,141,+     59,152,232,233,242,225,231,225,238, 97,128, 48,118,235,225,244,+    225,235,225,238, 97,128, 48,214,236,108,  2, 59,159, 59,189,229,+    116,130, 32, 34, 59,168, 59,178,233,238,246,229,242,243,101,128,+     37,216,239,240,229,242,225,244,239,114,128, 34, 25,243,229,249,+    101,128, 37,206, 99,143,  0, 99, 59,230, 60,179, 60,190, 60,254,+     61, 29, 61,122, 63, 33, 64, 17, 64,117, 64,166, 67,158, 67,166,+     67,176, 67,188, 67,221, 97,  9, 59,250, 60,  5, 60, 15, 60, 22,+     60, 29, 60, 54, 60, 64, 60,116, 60,125,225,242,237,229,238,233,+    225,110,128,  5,110,226,229,238,231,225,236,105,128,  9,154,227,+    245,244,101,128,  1,  7,228,229,246, 97,128,  9, 26,231,117,  2,+     60, 36, 60, 45,234,225,242,225,244,105,128, 10,154,242,237,245,+    235,232,105,128, 10, 26,236,243,241,245,225,242,101,128, 51,136,+    238,228,242,225,226,233,238,228,117,  4, 60, 82, 60, 92, 60, 98,+     60,105,226,229,238,231,225,236,105,128,  9,129,227,237, 98,128,+      3, 16,228,229,246, 97,128,  9,  1,231,245,234,225,242,225,244,+    105,128, 10,129,240,243,236,239,227,107,128, 33,234,114,  3, 60,+    133, 60,139, 60,165,229,239,102,128, 33,  5,239,110,130,  2,199,+     60,148, 60,159,226,229,236,239,247,227,237, 98,128,  3, 44,227,+    237, 98,128,  3, 12,242,233,225,231,229,242,229,244,245,242,110,+    128, 33,181,226,239,240,239,237,239,230,111,128, 49, 24, 99,  4,+     60,200, 60,207, 60,226, 60,248,225,242,239,110,128,  1, 13,229,+    228,233,236,236, 97,129,  0,231, 60,218,225,227,245,244,101,128,+     30,  9,233,242, 99,  2, 60,234, 60,239,236,101,128, 36,210,245,+    237,230,236,229,120,128,  1,  9,245,242,108,128,  2, 85,100,  2,+     61,  4, 61, 20,239,116,129,  1, 11, 61, 11,225,227,227,229,238,+    116,128,  1, 11,243,241,245,225,242,101,128, 51,197,101,  2, 61,+     35, 61, 51,228,233,236,236, 97,129,  0,184, 61, 45,227,237, 98,+    128,  3, 39,238,116,132,  0,162, 61, 64, 61, 88, 61,100, 61,111,+    105,  2, 61, 70, 61, 78,231,242,225,228,101,128, 33,  3,238,230,+    229,242,233,239,114,128,246,223,237,239,238,239,243,240,225,227,+    101,128,255,224,239,236,228,243,244,249,236,101,128,247,162,243,+    245,240,229,242,233,239,114,128,246,224,104,  5, 61,134, 61,197,+     61,208, 62,136, 62,228, 97,  4, 61,144, 61,155, 61,165, 61,172,+    225,242,237,229,238,233,225,110,128,  5,121,226,229,238,231,225,+    236,105,128,  9,155,228,229,246, 97,128,  9, 27,231,117,  2, 61,+    179, 61,188,234,225,242,225,244,105,128, 10,155,242,237,245,235,+    232,105,128, 10, 27,226,239,240,239,237,239,230,111,128, 49, 20,+    101,  6, 61,222, 61,242, 62, 10, 62, 78, 62, 90, 62,111,225,226,+    235,232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128,+      4,189, 99,  2, 61,248, 62,  0,235,237,225,242,107,128, 39, 19,+    249,242,233,236,236,233, 99,128,  4, 71,100,  2, 62, 16, 62, 60,+    229,243,227,229,238,228,229,114,  2, 62, 29, 62, 49,225,226,235,+    232,225,243,233,225,238,227,249,242,233,236,236,233, 99,128,  4,+    191,227,249,242,233,236,236,233, 99,128,  4,183,233,229,242,229,+    243,233,243,227,249,242,233,236,236,233, 99,128,  4,245,232,225,+    242,237,229,238,233,225,110,128,  5,115,235,232,225,235,225,243,+    243,233,225,238,227,249,242,233,236,236,233, 99,128,  4,204,246,+    229,242,244,233,227,225,236,243,244,242,239,235,229,227,249,242,+    233,236,236,233, 99,128,  4,185,105,129,  3,199, 62,142,229,245,+    227,104,  4, 62,155, 62,190, 62,205, 62,214, 97,  2, 62,161, 62,+    176,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,119,+    240,225,242,229,238,235,239,242,229,225,110,128, 50, 23,227,233,+    242,227,236,229,235,239,242,229,225,110,128, 50,105,235,239,242,+    229,225,110,128, 49, 74,240,225,242,229,238,235,239,242,229,225,+    110,128, 50,  9,111,  2, 62,234, 63, 28,227,104,  3, 62,243, 63,+      9, 63, 19,225,110,  2, 62,250, 63,  2,231,244,232,225,105,128,+     14, 10,244,232,225,105,128, 14,  8,233,238,231,244,232,225,105,+    128, 14,  9,239,229,244,232,225,105,128, 14, 12,239,107,128,  1,+    136,105,  2, 63, 39, 63,141,229,245, 99,  5, 63, 53, 63, 88, 63,+    103, 63,112, 63,126, 97,  2, 63, 59, 63, 74,227,233,242,227,236,+    229,235,239,242,229,225,110,128, 50,118,240,225,242,229,238,235,+    239,242,229,225,110,128, 50, 22,227,233,242,227,236,229,235,239,+    242,229,225,110,128, 50,104,235,239,242,229,225,110,128, 49, 72,+    240,225,242,229,238,235,239,242,229,225,110,128, 50,  8,245,240,+    225,242,229,238,235,239,242,229,225,110,128, 50, 28,242, 99,  2,+     63,148, 63,243,236,101,132, 37,203, 63,161, 63,172, 63,177, 63,+    201,237,245,236,244,233,240,236,121,128, 34,151,239,116,128, 34,+    153,112,  2, 63,183, 63,189,236,245,115,128, 34,149,239,243,244,+    225,236,237,225,242,107,128, 48, 54,247,233,244,104,  2, 63,210,+     63,226,236,229,230,244,232,225,236,230,226,236,225,227,107,128,+     37,208,242,233,231,232,244,232,225,236,230,226,236,225,227,107,+    128, 37,209,245,237,230,236,229,120,130,  2,198, 64,  0, 64, 11,+    226,229,236,239,247,227,237, 98,128,  3, 45,227,237, 98,128,  3,+      2,108,  3, 64, 25, 64, 31, 64, 85,229,225,114,128, 35, 39,233,+    227,107,  4, 64, 43, 64, 54, 64, 63, 64, 73,225,236,246,229,239,+    236,225,114,128,  1,194,228,229,238,244,225,108,128,  1,192,236,+    225,244,229,242,225,108,128,  1,193,242,229,244,242,239,230,236,+    229,120,128,  1,195,245, 98,129, 38, 99, 64, 92,243,245,233,116,+      2, 64,101, 64,109,226,236,225,227,107,128, 38, 99,247,232,233,+    244,101,128, 38,103,109,  3, 64,125, 64,139, 64,150,227,245,226,+    229,228,243,241,245,225,242,101,128, 51,164,239,238,239,243,240,+    225,227,101,128,255, 67,243,241,245,225,242,229,228,243,241,245,+    225,242,101,128, 51,160,111,  8, 64,184, 64,195, 65, 26, 65,224,+     66,253, 67, 28, 67,135, 67,144,225,242,237,229,238,233,225,110,+    128,  5,129,236,239,110,131,  0, 58, 64,207, 64,232, 64,251,237,+    239,110,  2, 64,215, 64,223,229,244,225,242,121,128, 32,161,239,+    243,240,225,227,101,128,255, 26,115,  2, 64,238, 64,244,233,231,+    110,128, 32,161,237,225,236,108,128,254, 85,244,242,233,225,238,+    231,245,236,225,114,  2, 65, 10, 65, 20,232,225,236,230,237,239,+    100,128,  2,209,237,239,100,128,  2,208,109,  2, 65, 32, 65,217,+    237, 97,134,  0, 44, 65, 49, 65,113, 65,124, 65,136, 65,166, 65,+    189, 97,  3, 65, 57, 65, 83, 65, 91,226,239,246,101,  2, 65, 66,+     65, 72,227,237, 98,128,  3, 19,242,233,231,232,244,227,237, 98,+    128,  3, 21,227,227,229,238,116,128,246,195,114,  2, 65, 97, 65,+    104,225,226,233, 99,128,  6, 12,237,229,238,233,225,110,128,  5,+     93,233,238,230,229,242,233,239,114,128,246,225,237,239,238,239,+    243,240,225,227,101,128,255, 12,242,229,246,229,242,243,229,100,+      2, 65,149, 65,160,225,226,239,246,229,227,237, 98,128,  3, 20,+    237,239,100,128,  2,189,115,  2, 65,172, 65,179,237,225,236,108,+    128,254, 80,245,240,229,242,233,239,114,128,246,226,244,245,242,+    238,229,100,  2, 65,200, 65,211,225,226,239,246,229,227,237, 98,+    128,  3, 18,237,239,100,128,  2,187,240,225,243,115,128, 38, 60,+    110,  2, 65,230, 65,239,231,242,245,229,238,116,128, 34, 69,116,+      2, 65,245, 66,  3,239,245,242,233,238,244,229,231,242,225,108,+    128, 34, 46,242,239,108,142, 35,  3, 66, 37, 66, 43, 66, 58, 66,+     73, 66,117, 66,162, 66,176, 66,181, 66,186, 66,191, 66,197, 66,+    202, 66,243, 66,248,193,195, 75,128,  0,  6, 66,  2, 66, 49, 66,+     54,197, 76,128,  0,  7, 83,128,  0,  8, 67,  2, 66, 64, 66, 69,+    193, 78,128,  0, 24, 82,128,  0, 13, 68,  3, 66, 81, 66,107, 66,+    112, 67,  4, 66, 91, 66, 95, 66, 99, 66,103, 49,128,  0, 17, 50,+    128,  0, 18, 51,128,  0, 19, 52,128,  0, 20,197, 76,128,  0,127,+    204, 69,128,  0, 16, 69,  5, 66,129, 66,133, 66,138, 66,143, 66,+    148, 77,128,  0, 25,206, 81,128,  0,  5,207, 84,128,  0,  4,211,+     67,128,  0, 27, 84,  2, 66,154, 66,158, 66,128,  0, 23, 88,128,+      0,  3, 70,  2, 66,168, 66,172, 70,128,  0, 12, 83,128,  0, 28,+    199, 83,128,  0, 29,200, 84,128,  0,  9,204, 70,128,  0, 10,206,+    193, 75,128,  0, 21,210, 83,128,  0, 30, 83,  5, 66,214, 66,218,+     66,228, 66,233, 66,238, 73,128,  0, 15, 79,129,  0, 14, 66,224,+     84,128,  0,  2,212, 88,128,  0,  1,213, 66,128,  0, 26,217, 78,+    128,  0, 22,213, 83,128,  0, 31,214, 84,128,  0, 11,240,249,242,+    233,231,232,116,129,  0,169, 67,  9,115,  2, 67, 15, 67, 21,225,+    238,115,128,248,233,229,242,233,102,128,246,217,114,  2, 67, 34,+     67,118,238,229,242,226,242,225,227,235,229,116,  2, 67, 49, 67,+     83,236,229,230,116,130, 48, 12, 67, 60, 67, 72,232,225,236,230,+    247,233,228,244,104,128,255, 98,246,229,242,244,233,227,225,108,+    128,254, 65,242,233,231,232,116,130, 48, 13, 67, 95, 67,107,232,+    225,236,230,247,233,228,244,104,128,255, 99,246,229,242,244,233,+    227,225,108,128,254, 66,240,239,242,225,244,233,239,238,243,241,+    245,225,242,101,128, 51,127,243,241,245,225,242,101,128, 51,199,+    246,229,242,235,231,243,241,245,225,242,101,128, 51,198,240,225,+    242,229,110,128, 36,158,242,245,250,229,233,242,111,128, 32,162,+    243,244,242,229,244,227,232,229,100,128,  2,151,245,114,  2, 67,+    195, 67,213,236,121,  2, 67,202, 67,208,225,238,100,128, 34,207,+    239,114,128, 34,206,242,229,238,227,121,128,  0,164,249,114,  4,+     67,232, 67,240, 67,247, 67,255,194,242,229,246,101,128,246,209,+    198,236,229,120,128,246,210,226,242,229,246,101,128,246,212,230,+    236,229,120,128,246,213,100,146,  0,100, 68, 46, 69,184, 70,208,+     71, 12, 71,188, 72,142, 72,204, 73,133, 73,146, 73,155, 73,181,+     73,206, 73,215, 75, 26, 75, 34, 75, 45, 75, 65, 75, 93, 97, 11,+     68, 70, 68, 81, 68, 91, 68,163, 68,226, 68,237, 68,248, 69, 61,+     69,123, 69,129, 69,159,225,242,237,229,238,233,225,110,128,  5,+    100,226,229,238,231,225,236,105,128,  9,166,100,  5, 68,103, 68,+    112, 68,118, 68,132, 68,148,225,242,225,226,233, 99,128,  6, 54,+    229,246, 97,128,  9, 38,230,233,238,225,236,225,242,225,226,233,+     99,128,254,190,233,238,233,244,233,225,236,225,242,225,226,233,+     99,128,254,191,237,229,228,233,225,236,225,242,225,226,233, 99,+    128,254,192,103,  3, 68,171, 68,188, 68,202,229,243,104,129,  5,+    188, 68,179,232,229,226,242,229,119,128,  5,188,231,229,114,129,+     32, 32, 68,196,228,226,108,128, 32, 33,117,  2, 68,208, 68,217,+    234,225,242,225,244,105,128, 10,166,242,237,245,235,232,105,128,+     10, 38,232,233,242,225,231,225,238, 97,128, 48, 96,235,225,244,+    225,235,225,238, 97,128, 48,192,108,  3, 69,  0, 69,  9, 69, 47,+    225,242,225,226,233, 99,128,  6, 47,229,116,130,  5,211, 69, 18,+     69, 38,228,225,231,229,243,104,129,251, 51, 69, 29,232,229,226,+    242,229,119,128,251, 51,232,229,226,242,229,119,128,  5,211,230,+    233,238,225,236,225,242,225,226,233, 99,128,254,170,237,237, 97,+      3, 69, 71, 69, 80, 69, 92,225,242,225,226,233, 99,128,  6, 79,+    236,239,247,225,242,225,226,233, 99,128,  6, 79,244,225,238, 97,+      2, 69,101, 69,115,236,244,239,238,229,225,242,225,226,233, 99,+    128,  6, 76,242,225,226,233, 99,128,  6, 76,238,228, 97,128,  9,+    100,242,231, 97,  2, 69,137, 69,146,232,229,226,242,229,119,128,+      5,167,236,229,230,244,232,229,226,242,229,119,128,  5,167,243,+    233,225,240,238,229,245,237,225,244,225,227,249,242,233,236,236,+    233,227,227,237, 98,128,  4,133, 98,  3, 69,192, 70,189, 70,199,+    108,  9, 69,212, 69,220, 70, 77, 70, 85, 70,101, 70,112, 70,130,+     70,144, 70,155,199,242,225,246,101,128,246,211, 97,  2, 69,226,+     70, 27,238,231,236,229,226,242,225,227,235,229,116,  2, 69,242,+     70,  6,236,229,230,116,129, 48, 10, 69,251,246,229,242,244,233,+    227,225,108,128,254, 61,242,233,231,232,116,129, 48, 11, 70, 16,+    246,229,242,244,233,227,225,108,128,254, 62,114,  2, 70, 33, 70,+     54,227,232,233,238,246,229,242,244,229,228,226,229,236,239,247,+    227,237, 98,128,  3, 43,242,239,119,  2, 70, 62, 70, 69,236,229,+    230,116,128, 33,212,242,233,231,232,116,128, 33,210,228,225,238,+    228, 97,128,  9,101,231,242,225,246,101,129,246,214, 70, 95,227,+    237, 98,128,  3, 15,233,238,244,229,231,242,225,108,128, 34, 44,+    236,239,247,236,233,238,101,129, 32, 23, 70,124,227,237, 98,128,+      3, 51,239,246,229,242,236,233,238,229,227,237, 98,128,  3, 63,+    240,242,233,237,229,237,239,100,128,  2,186,246,229,242,244,233,+    227,225,108,  2, 70,168, 70,174,226,225,114,128, 32, 22,236,233,+    238,229,225,226,239,246,229,227,237, 98,128,  3, 14,239,240,239,+    237,239,230,111,128, 49,  9,243,241,245,225,242,101,128, 51,200,+     99,  4, 70,218, 70,225, 70,234, 71,  5,225,242,239,110,128,  1,+     15,229,228,233,236,236, 97,128, 30, 17,233,242, 99,  2, 70,242,+     70,247,236,101,128, 36,211,245,237,230,236,229,248,226,229,236,+    239,119,128, 30, 19,242,239,225,116,128,  1, 17,100,  4, 71, 22,+     71,103, 71,113, 71,164, 97,  4, 71, 32, 71, 42, 71, 49, 71, 74,+    226,229,238,231,225,236,105,128,  9,161,228,229,246, 97,128,  9,+     33,231,117,  2, 71, 56, 71, 65,234,225,242,225,244,105,128, 10,+    161,242,237,245,235,232,105,128, 10, 33,108,  2, 71, 80, 71, 89,+    225,242,225,226,233, 99,128,  6,136,230,233,238,225,236,225,242,+    225,226,233, 99,128,251,137,228,232,225,228,229,246, 97,128,  9,+     92,232, 97,  3, 71,122, 71,132, 71,139,226,229,238,231,225,236,+    105,128,  9,162,228,229,246, 97,128,  9, 34,231,117,  2, 71,146,+     71,155,234,225,242,225,244,105,128, 10,162,242,237,245,235,232,+    105,128, 10, 34,239,116,  2, 71,171, 71,180,225,227,227,229,238,+    116,128, 30, 11,226,229,236,239,119,128, 30, 13,101,  8, 71,206,+     72,  3, 72, 10, 72, 35, 72, 45, 72, 56, 72,101, 72,137, 99,  2,+     71,212, 71,249,233,237,225,236,243,229,240,225,242,225,244,239,+    114,  2, 71,230, 71,239,225,242,225,226,233, 99,128,  6,107,240,+    229,242,243,233,225,110,128,  6,107,249,242,233,236,236,233, 99,+    128,  4, 52,231,242,229,101,128,  0,176,232,105,  2, 72, 17, 72,+     26,232,229,226,242,229,119,128,  5,173,242,225,231,225,238, 97,+    128, 48,103,233,227,239,240,244,233, 99,128,  3,239,235,225,244,+    225,235,225,238, 97,128, 48,199,108,  2, 72, 62, 72, 85,229,244,+    101,  2, 72, 70, 72, 77,236,229,230,116,128, 35, 43,242,233,231,+    232,116,128, 35, 38,244, 97,129,  3,180, 72, 92,244,245,242,238,+    229,100,128,  1,141,238,239,237,233,238,225,244,239,242,237,233,+    238,245,243,239,238,229,238,245,237,229,242,225,244,239,242,226,+    229,238,231,225,236,105,128,  9,248,250,104,128,  2,164,104,  2,+     72,148, 72,198, 97,  3, 72,156, 72,166, 72,173,226,229,238,231,+    225,236,105,128,  9,167,228,229,246, 97,128,  9, 39,231,117,  2,+     72,180, 72,189,234,225,242,225,244,105,128, 10,167,242,237,245,+    235,232,105,128, 10, 39,239,239,107,128,  2, 87,105,  6, 72,218,+     73, 11, 73, 71, 73, 82, 73, 93, 73,103, 97,  2, 72,224, 72,246,+    236,249,244,233,235,225,244,239,238,239,115,129,  3,133, 72,240,+    227,237, 98,128,  3, 68,237,239,238,100,129, 38,102, 72,255,243,+    245,233,244,247,232,233,244,101,128, 38, 98,229,242,229,243,233,+    115,133,  0,168, 73, 30, 73, 38, 73, 49, 73, 55, 73, 63,225,227,+    245,244,101,128,246,215,226,229,236,239,247,227,237, 98,128,  3,+     36,227,237, 98,128,  3,  8,231,242,225,246,101,128,246,216,244,+    239,238,239,115,128,  3,133,232,233,242,225,231,225,238, 97,128,+     48, 98,235,225,244,225,235,225,238, 97,128, 48,194,244,244,239,+    237,225,242,107,128, 48,  3,246,105,  2, 73,110, 73,121,228,101,+    129,  0,247, 73,117,115,128, 34, 35,243,233,239,238,243,236,225,+    243,104,128, 34, 21,234,229,227,249,242,233,236,236,233, 99,128,+      4, 82,235,243,232,225,228,101,128, 37,147,108,  2, 73,161, 73,+    172,233,238,229,226,229,236,239,119,128, 30, 15,243,241,245,225,+    242,101,128, 51,151,109,  2, 73,187, 73,195,225,227,242,239,110,+    128,  1, 17,239,238,239,243,240,225,227,101,128,255, 68,238,226,+    236,239,227,107,128, 37,132,111, 10, 73,237, 73,249, 74,  3, 74,+     14, 74, 25, 74, 97, 74,102, 74,113, 74,228, 74,254,227,232,225,+    228,225,244,232,225,105,128, 14, 14,228,229,235,244,232,225,105,+    128, 14, 20,232,233,242,225,231,225,238, 97,128, 48,105,235,225,+    244,225,235,225,238, 97,128, 48,201,236,236,225,114,132,  0, 36,+     74, 40, 74, 51, 74, 63, 74, 74,233,238,230,229,242,233,239,114,+    128,246,227,237,239,238,239,243,240,225,227,101,128,255,  4,239,+    236,228,243,244,249,236,101,128,247, 36,115,  2, 74, 80, 74, 87,+    237,225,236,108,128,254,105,245,240,229,242,233,239,114,128,246,+    228,238,103,128, 32,171,242,245,243,241,245,225,242,101,128, 51,+     38,116,  6, 74,127, 74,144, 74,166, 74,177, 74,209, 74,216,225,+    227,227,229,238,116,129,  2,217, 74,138,227,237, 98,128,  3,  7,+    226,229,236,239,247, 99,  2, 74,155, 74,160,237, 98,128,  3, 35,+    239,237, 98,128,  3, 35,235,225,244,225,235,225,238, 97,128, 48,+    251,236,229,243,115,  2, 74,186, 74,190,105,128,  1, 49,106,129,+    246,190, 74,196,243,244,242,239,235,229,232,239,239,107,128,  2,+    132,237,225,244,104,128, 34,197,244,229,228,227,233,242,227,236,+    101,128, 37,204,245,226,236,229,249,239,228,240,225,244,225,104,+    129,251, 31, 74,245,232,229,226,242,229,119,128,251, 31,247,238,+    244,225,227,107,  2, 75,  9, 75, 20,226,229,236,239,247,227,237,+     98,128,  3, 30,237,239,100,128,  2,213,240,225,242,229,110,128,+     36,159,243,245,240,229,242,233,239,114,128,246,235,116,  2, 75,+     51, 75, 57,225,233,108,128,  2, 86,239,240,226,225,114,128,  1,+    140,117,  2, 75, 71, 75, 82,232,233,242,225,231,225,238, 97,128,+     48,101,235,225,244,225,235,225,238, 97,128, 48,197,122,132,  1,+    243, 75,105, 75,114, 75,133, 75,170,225,236,244,239,238,101,128,+      2,163, 99,  2, 75,120, 75,127,225,242,239,110,128,  1,198,245,+    242,108,128,  2,165,101,  2, 75,139, 75,159,225,226,235,232,225,+    243,233,225,238,227,249,242,233,236,236,233, 99,128,  4,225,227,+    249,242,233,236,236,233, 99,128,  4, 85,232,229,227,249,242,233,+    236,236,233, 99,128,  4, 95,101,151,  0,101, 75,233, 75,252, 76,+     30, 77,  4, 77, 66, 77, 99, 77,111, 77,134, 77,187, 79, 43, 79,+    101, 79,203, 80, 63, 80,198, 81, 17, 81, 48, 81,110, 81,163, 82,+     98, 82,231, 82,251, 83, 39, 83,130, 97,  2, 75,239, 75,246,227,+    245,244,101,128,  0,233,242,244,104,128, 38, 65, 98,  3, 76,  4,+     76, 13, 76, 23,229,238,231,225,236,105,128,  9,143,239,240,239,+    237,239,230,111,128, 49, 28,242,229,246,101,128,  1, 21, 99,  5,+     76, 42, 76,115, 76,129, 76,161, 76,250, 97,  2, 76, 48, 76,109,+    238,228,242, 97,  3, 76, 59, 76, 66, 76, 77,228,229,246, 97,128,+      9, 13,231,245,234,225,242,225,244,105,128, 10,141,246,239,247,+    229,236,243,233,231,110,  2, 76, 91, 76, 98,228,229,246, 97,128,+      9, 69,231,245,234,225,242,225,244,105,128, 10,197,242,239,110,+    128,  1, 27,229,228,233,236,236,225,226,242,229,246,101,128, 30,+     29,104,  2, 76,135, 76,146,225,242,237,229,238,233,225,110,128,+      5,101,249,233,247,238,225,242,237,229,238,233,225,110,128,  5,+    135,233,242, 99,  2, 76,169, 76,174,236,101,128, 36,212,245,237,+    230,236,229,120,134,  0,234, 76,195, 76,203, 76,211, 76,222, 76,+    230, 76,242,225,227,245,244,101,128, 30,191,226,229,236,239,119,+    128, 30, 25,228,239,244,226,229,236,239,119,128, 30,199,231,242,+    225,246,101,128, 30,193,232,239,239,235,225,226,239,246,101,128,+     30,195,244,233,236,228,101,128, 30,197,249,242,233,236,236,233,+     99,128,  4, 84,100,  4, 77, 14, 77, 24, 77, 30, 77, 40,226,236,+    231,242,225,246,101,128,  2,  5,229,246, 97,128,  9, 15,233,229,+    242,229,243,233,115,128,  0,235,239,116,130,  1, 23, 77, 49, 77,+     58,225,227,227,229,238,116,128,  1, 23,226,229,236,239,119,128,+     30,185,101,  2, 77, 72, 77, 83,231,245,242,237,245,235,232,105,+    128, 10, 15,237,225,244,242,225,231,245,242,237,245,235,232,105,+    128, 10, 71,230,227,249,242,233,236,236,233, 99,128,  4, 68,103,+      2, 77,117, 77,124,242,225,246,101,128,  0,232,245,234,225,242,+    225,244,105,128, 10,143,104,  4, 77,144, 77,155, 77,166, 77,176,+    225,242,237,229,238,233,225,110,128,  5,103,226,239,240,239,237,+    239,230,111,128, 49, 29,233,242,225,231,225,238, 97,128, 48, 72,+    239,239,235,225,226,239,246,101,128, 30,187,105,  4, 77,197, 77,+    208, 79, 10, 79, 25,226,239,240,239,237,239,230,111,128, 49, 31,+    231,232,116,142,  0, 56, 77,242, 77,251, 78,  5, 78, 35, 78, 42,+     78, 80, 78,105, 78,150, 78,184, 78,196, 78,207, 78,240, 78,248,+     79,  3,225,242,225,226,233, 99,128,  6,104,226,229,238,231,225,+    236,105,128,  9,238,227,233,242,227,236,101,129, 36,103, 78, 16,+    233,238,246,229,242,243,229,243,225,238,243,243,229,242,233,102,+    128, 39,145,228,229,246, 97,128,  9,110,229,229,110,  2, 78, 50,+     78, 59,227,233,242,227,236,101,128, 36,113,112,  2, 78, 65, 78,+     72,225,242,229,110,128, 36,133,229,242,233,239,100,128, 36,153,+    231,117,  2, 78, 87, 78, 96,234,225,242,225,244,105,128, 10,238,+    242,237,245,235,232,105,128, 10,110,104,  2, 78,111, 78,137, 97,+      2, 78,117, 78,128,227,235,225,242,225,226,233, 99,128,  6,104,+    238,231,250,232,239,117,128, 48, 40,238,239,244,229,226,229,225,+    237,229,100,128, 38,107,105,  2, 78,156, 78,174,228,229,239,231,+    242,225,240,232,233,227,240,225,242,229,110,128, 50, 39,238,230,+    229,242,233,239,114,128, 32,136,237,239,238,239,243,240,225,227,+    101,128,255, 24,239,236,228,243,244,249,236,101,128,247, 56,112,+      2, 78,213, 78,220,225,242,229,110,128, 36,123,229,114,  2, 78,+    227, 78,233,233,239,100,128, 36,143,243,233,225,110,128,  6,248,+    242,239,237,225,110,128, 33,119,243,245,240,229,242,233,239,114,+    128, 32,120,244,232,225,105,128, 14, 88,238,246,229,242,244,229,+    228,226,242,229,246,101,128,  2,  7,239,244,233,230,233,229,228,+    227,249,242,233,236,236,233, 99,128,  4,101,107,  2, 79, 49, 79,+     73,225,244,225,235,225,238, 97,129, 48,168, 79, 61,232,225,236,+    230,247,233,228,244,104,128,255,116,111,  2, 79, 79, 79, 94,238,+    235,225,242,231,245,242,237,245,235,232,105,128, 10,116,242,229,+    225,110,128, 49, 84,108,  3, 79,109, 79,120, 79,181,227,249,242,+    233,236,236,233, 99,128,  4, 59,101,  2, 79,126, 79,133,237,229,+    238,116,128, 34,  8,246,229,110,  3, 79,143, 79,152, 79,173,227,+    233,242,227,236,101,128, 36,106,112,  2, 79,158, 79,165,225,242,+    229,110,128, 36,126,229,242,233,239,100,128, 36,146,242,239,237,+    225,110,128, 33,122,236,233,240,243,233,115,129, 32, 38, 79,192,+    246,229,242,244,233,227,225,108,128, 34,238,109,  5, 79,215, 79,+    243, 79,254, 80, 18, 80, 29,225,227,242,239,110,130,  1, 19, 79,+    227, 79,235,225,227,245,244,101,128, 30, 23,231,242,225,246,101,+    128, 30, 21,227,249,242,233,236,236,233, 99,128,  4, 60,228,225,+    243,104,129, 32, 20, 80,  7,246,229,242,244,233,227,225,108,128,+    254, 49,239,238,239,243,240,225,227,101,128,255, 69,112,  2, 80,+     35, 80, 55,232,225,243,233,243,237,225,242,235,225,242,237,229,+    238,233,225,110,128,  5, 91,244,249,243,229,116,128, 34,  5,110,+      6, 80, 77, 80, 88, 80, 99, 80,143, 80,175, 80,190,226,239,240,+    239,237,239,230,111,128, 49, 35,227,249,242,233,236,236,233, 99,+    128,  4, 61,100,  2, 80,105, 80,124,225,243,104,129, 32, 19, 80,+    113,246,229,242,244,233,227,225,108,128,254, 50,229,243,227,229,+    238,228,229,242,227,249,242,233,236,236,233, 99,128,  4,163,103,+    130,  1, 75, 80,151, 80,162,226,239,240,239,237,239,230,111,128,+     49, 37,232,229,227,249,242,233,236,236,233, 99,128,  4,165,232,+    239,239,235,227,249,242,233,236,236,233, 99,128,  4,200,243,240,+    225,227,101,128, 32,  2,111,  3, 80,206, 80,214, 80,223,231,239,+    238,229,107,128,  1, 25,235,239,242,229,225,110,128, 49, 83,240,+    229,110,130,  2, 91, 80,233, 80,242,227,236,239,243,229,100,128,+      2,154,242,229,246,229,242,243,229,100,130,  2, 92, 81,  1, 81,+     10,227,236,239,243,229,100,128,  2, 94,232,239,239,107,128,  2,+     93,112,  2, 81, 23, 81, 30,225,242,229,110,128, 36,160,243,233,+    236,239,110,129,  3,181, 81, 40,244,239,238,239,115,128,  3,173,+    241,117,  2, 81, 55, 81, 99,225,108,130,  0, 61, 81, 64, 81, 76,+    237,239,238,239,243,240,225,227,101,128,255, 29,115,  2, 81, 82,+     81, 89,237,225,236,108,128,254,102,245,240,229,242,233,239,114,+    128, 32,124,233,246,225,236,229,238,227,101,128, 34, 97,114,  3,+     81,118, 81,129, 81,140,226,239,240,239,237,239,230,111,128, 49,+     38,227,249,242,233,236,236,233, 99,128,  4, 64,229,246,229,242,+    243,229,100,129,  2, 88, 81,152,227,249,242,233,236,236,233, 99,+    128,  4, 77,115,  6, 81,177, 81,188, 81,208, 82, 33, 82, 78, 82,+     88,227,249,242,233,236,236,233, 99,128,  4, 65,228,229,243,227,+    229,238,228,229,242,227,249,242,233,236,236,233, 99,128,  4,171,+    104,132,  2,131, 81,220, 81,227, 82,  2, 82, 17,227,245,242,108,+    128,  2,134,239,242,116,  2, 81,235, 81,242,228,229,246, 97,128,+      9, 14,246,239,247,229,236,243,233,231,238,228,229,246, 97,128,+      9, 70,242,229,246,229,242,243,229,228,236,239,239,112,128,  1,+    170,243,241,245,225,244,242,229,246,229,242,243,229,100,128,  2,+    133,237,225,236,108,  2, 82, 42, 82, 53,232,233,242,225,231,225,+    238, 97,128, 48, 71,235,225,244,225,235,225,238, 97,129, 48,167,+     82, 66,232,225,236,230,247,233,228,244,104,128,255,106,244,233,+    237,225,244,229,100,128, 33, 46,245,240,229,242,233,239,114,128,+    246,236,116,  5, 82,110, 82,136, 82,140, 82,157, 82,223, 97,130,+      3,183, 82,118, 82,128,242,237,229,238,233,225,110,128,  5,104,+    244,239,238,239,115,128,  3,174,104,128,  0,240,233,236,228,101,+    129, 30,189, 82,149,226,229,236,239,119,128, 30, 27,238,225,232,+    244, 97,  3, 82,169, 82,201, 82,210,230,239,245,235,104,  2, 82,+    179, 82,188,232,229,226,242,229,119,128,  5,145,236,229,230,244,+    232,229,226,242,229,119,128,  5,145,232,229,226,242,229,119,128,+      5,145,236,229,230,244,232,229,226,242,229,119,128,  5,145,245,+    242,238,229,100,128,  1,221,117,  2, 82,237, 82,246,235,239,242,+    229,225,110,128, 49, 97,242,111,128, 32,172,246,239,247,229,236,+    243,233,231,110,  3, 83, 11, 83, 21, 83, 28,226,229,238,231,225,+    236,105,128,  9,199,228,229,246, 97,128,  9, 71,231,245,234,225,+    242,225,244,105,128, 10,199,120,  2, 83, 45, 83,118,227,236,225,+    109,132,  0, 33, 83, 60, 83, 71, 83, 98, 83,110,225,242,237,229,+    238,233,225,110,128,  5, 92,100,  2, 83, 77, 83, 82,226,108,128,+     32, 60,239,247,110,129,  0,161, 83, 90,243,237,225,236,108,128,+    247,161,237,239,238,239,243,240,225,227,101,128,255,  1,243,237,+    225,236,108,128,247, 33,233,243,244,229,238,244,233,225,108,128,+     34,  3,250,104,131,  2,146, 83,141, 83,160, 83,171, 99,  2, 83,+    147, 83,154,225,242,239,110,128,  1,239,245,242,108,128,  2,147,+    242,229,246,229,242,243,229,100,128,  1,185,244,225,233,108,128,+      1,186,102,140,  0,102, 83,206, 84, 32, 84, 43, 84, 52, 84, 64,+     84,167, 84,183, 86,191, 86,204, 86,230, 88,107, 88,115, 97,  4,+     83,216, 83,223, 83,234, 83,245,228,229,246, 97,128,  9, 94,231,+    245,242,237,245,235,232,105,128, 10, 94,232,242,229,238,232,229,+    233,116,128, 33,  9,244,232, 97,  3, 83,255, 84,  8, 84, 20,225,+    242,225,226,233, 99,128,  6, 78,236,239,247,225,242,225,226,233,+     99,128,  6, 78,244,225,238,225,242,225,226,233, 99,128,  6, 75,+    226,239,240,239,237,239,230,111,128, 49,  8,227,233,242,227,236,+    101,128, 36,213,228,239,244,225,227,227,229,238,116,128, 30, 31,+    101,  3, 84, 72, 84,150, 84,160,104,  4, 84, 82, 84,105, 84,119,+     84,135,225,114,  2, 84, 89, 84, 96,225,226,233, 99,128,  6, 65,+    237,229,238,233,225,110,128,  5,134,230,233,238,225,236,225,242,+    225,226,233, 99,128,254,210,233,238,233,244,233,225,236,225,242,+    225,226,233, 99,128,254,211,237,229,228,233,225,236,225,242,225,+    226,233, 99,128,254,212,233,227,239,240,244,233, 99,128,  3,229,+    237,225,236,101,128, 38, 64,102,130,251,  0, 84,175, 84,179,105,+    128,251,  3,108,128,251,  4,105,136,251,  1, 84,203, 84,243, 84,+    254, 85, 20, 85,142, 85,159, 85,167, 85,180,230,244,229,229,110,+      2, 84,213, 84,222,227,233,242,227,236,101,128, 36,110,112,  2,+     84,228, 84,235,225,242,229,110,128, 36,130,229,242,233,239,100,+    128, 36,150,231,245,242,229,228,225,243,104,128, 32, 18,236,236,+    229,100,  2, 85,  7, 85, 13,226,239,120,128, 37,160,242,229,227,+    116,128, 37,172,238,225,108,  5, 85, 34, 85, 73, 85, 90, 85,107,+     85,123,235,225,102,130,  5,218, 85, 44, 85, 64,228,225,231,229,+    243,104,129,251, 58, 85, 55,232,229,226,242,229,119,128,251, 58,+    232,229,226,242,229,119,128,  5,218,237,229,109,129,  5,221, 85,+     81,232,229,226,242,229,119,128,  5,221,238,245,110,129,  5,223,+     85, 98,232,229,226,242,229,119,128,  5,223,240,101,129,  5,227,+     85,114,232,229,226,242,229,119,128,  5,227,244,243,225,228,105,+    129,  5,229, 85,133,232,229,226,242,229,119,128,  5,229,242,243,+    244,244,239,238,229,227,232,233,238,229,243,101,128,  2,201,243,+    232,229,249,101,128, 37,201,244,225,227,249,242,233,236,236,233,+     99,128,  4,115,246,101,142,  0, 53, 85,213, 85,222, 85,232, 86,+      6, 86, 13, 86, 23, 86, 48, 86, 75, 86,109, 86,121, 86,132, 86,+    165, 86,173, 86,184,225,242,225,226,233, 99,128,  6,101,226,229,+    238,231,225,236,105,128,  9,235,227,233,242,227,236,101,129, 36,+    100, 85,243,233,238,246,229,242,243,229,243,225,238,243,243,229,+    242,233,102,128, 39,142,228,229,246, 97,128,  9,107,229,233,231,+    232,244,232,115,128, 33, 93,231,117,  2, 86, 30, 86, 39,234,225,+    242,225,244,105,128, 10,235,242,237,245,235,232,105,128, 10,107,+    232, 97,  2, 86, 55, 86, 66,227,235,225,242,225,226,233, 99,128,+      6,101,238,231,250,232,239,117,128, 48, 37,105,  2, 86, 81, 86,+     99,228,229,239,231,242,225,240,232,233,227,240,225,242,229,110,+    128, 50, 36,238,230,229,242,233,239,114,128, 32,133,237,239,238,+    239,243,240,225,227,101,128,255, 21,239,236,228,243,244,249,236,+    101,128,247, 53,112,  2, 86,138, 86,145,225,242,229,110,128, 36,+    120,229,114,  2, 86,152, 86,158,233,239,100,128, 36,140,243,233,+    225,110,128,  6,245,242,239,237,225,110,128, 33,116,243,245,240,+    229,242,233,239,114,128, 32,117,244,232,225,105,128, 14, 85,108,+    129,251,  2, 86,197,239,242,233,110,128,  1,146,109,  2, 86,210,+     86,221,239,238,239,243,240,225,227,101,128,255, 70,243,241,245,+    225,242,101,128, 51,153,111,  4, 86,240, 87,  6, 87, 18, 87, 25,+    230, 97,  2, 86,247, 86,255,238,244,232,225,105,128, 14, 31,244,+    232,225,105,128, 14, 29,238,231,237,225,238,244,232,225,105,128,+     14, 79,242,225,236,108,128, 34,  0,245,114,142,  0, 52, 87, 58,+     87, 67, 87, 77, 87,107, 87,114, 87,139, 87,166, 87,200, 87,212,+     87,231, 87,242, 88, 19, 88, 27, 88, 38,225,242,225,226,233, 99,+    128,  6,100,226,229,238,231,225,236,105,128,  9,234,227,233,242,+    227,236,101,129, 36, 99, 87, 88,233,238,246,229,242,243,229,243,+    225,238,243,243,229,242,233,102,128, 39,141,228,229,246, 97,128,+      9,106,231,117,  2, 87,121, 87,130,234,225,242,225,244,105,128,+     10,234,242,237,245,235,232,105,128, 10,106,232, 97,  2, 87,146,+     87,157,227,235,225,242,225,226,233, 99,128,  6,100,238,231,250,+    232,239,117,128, 48, 36,105,  2, 87,172, 87,190,228,229,239,231,+    242,225,240,232,233,227,240,225,242,229,110,128, 50, 35,238,230,+    229,242,233,239,114,128, 32,132,237,239,238,239,243,240,225,227,+    101,128,255, 20,238,245,237,229,242,225,244,239,242,226,229,238,+    231,225,236,105,128,  9,247,239,236,228,243,244,249,236,101,128,+    247, 52,112,  2, 87,248, 87,255,225,242,229,110,128, 36,119,229,+    114,  2, 88,  6, 88, 12,233,239,100,128, 36,139,243,233,225,110,+    128,  6,244,242,239,237,225,110,128, 33,115,243,245,240,229,242,+    233,239,114,128, 32,116,116,  2, 88, 44, 88, 82,229,229,110,  2,+     88, 52, 88, 61,227,233,242,227,236,101,128, 36,109,112,  2, 88,+     67, 88, 74,225,242,229,110,128, 36,129,229,242,233,239,100,128,+     36,149,104,  2, 88, 88, 88, 93,225,105,128, 14, 84,244,239,238,+    229,227,232,233,238,229,243,101,128,  2,203,240,225,242,229,110,+    128, 36,161,242, 97,  2, 88,122, 88,130,227,244,233,239,110,128,+     32, 68,238, 99,128, 32,163,103,144,  0,103, 88,171, 89,117, 89,+    140, 89,201, 89,218, 90,139, 91,132, 91,217, 91,230, 92, 88, 92,+    113, 92,141, 92,163, 93,108, 93,130, 93,232, 97,  9, 88,191, 88,+    201, 88,208, 88,215, 89, 23, 89, 48, 89, 59, 89, 70, 89,104,226,+    229,238,231,225,236,105,128,  9,151,227,245,244,101,128,  1,245,+    228,229,246, 97,128,  9, 23,102,  4, 88,225, 88,234, 88,248, 89,+      8,225,242,225,226,233, 99,128,  6,175,230,233,238,225,236,225,+    242,225,226,233, 99,128,251,147,233,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,251,148,237,229,228,233,225,236,225,242,+    225,226,233, 99,128,251,149,231,117,  2, 89, 30, 89, 39,234,225,+    242,225,244,105,128, 10,151,242,237,245,235,232,105,128, 10, 23,+    232,233,242,225,231,225,238, 97,128, 48, 76,235,225,244,225,235,+    225,238, 97,128, 48,172,237,237, 97,130,  3,179, 89, 80, 89, 93,+    236,225,244,233,238,243,237,225,236,108,128,  2, 99,243,245,240,+    229,242,233,239,114,128,  2,224,238,231,233,225,227,239,240,244,+    233, 99,128,  3,235, 98,  2, 89,123, 89,133,239,240,239,237,239,+    230,111,128, 49, 13,242,229,246,101,128,  1, 31, 99,  4, 89,150,+     89,157, 89,166, 89,188,225,242,239,110,128,  1,231,229,228,233,+    236,236, 97,128,  1, 35,233,242, 99,  2, 89,174, 89,179,236,101,+    128, 36,214,245,237,230,236,229,120,128,  1, 29,239,237,237,225,+    225,227,227,229,238,116,128,  1, 35,228,239,116,129,  1, 33, 89,+    209,225,227,227,229,238,116,128,  1, 33,101,  6, 89,232, 89,243,+     89,254, 90,  9, 90, 28, 90,130,227,249,242,233,236,236,233, 99,+    128,  4, 51,232,233,242,225,231,225,238, 97,128, 48, 82,235,225,+    244,225,235,225,238, 97,128, 48,178,239,237,229,244,242,233,227,+    225,236,236,249,229,241,245,225,108,128, 34, 81,114,  3, 90, 36,+     90, 85, 90, 95,229,243,104,  3, 90, 46, 90, 61, 90, 70,225,227,+    227,229,238,244,232,229,226,242,229,119,128,  5,156,232,229,226,+    242,229,119,128,  5,243,237,245,241,228,225,237,232,229,226,242,+    229,119,128,  5,157,237,225,238,228,226,236,115,128,  0,223,243,+    232,225,249,233,109,  2, 90,106, 90,121,225,227,227,229,238,244,+    232,229,226,242,229,119,128,  5,158,232,229,226,242,229,119,128,+      5,244,244,225,237,225,242,107,128, 48, 19,104,  5, 90,151, 91,+     28, 91, 91, 91,116, 91,122, 97,  4, 90,161, 90,171, 90,194, 90,+    219,226,229,238,231,225,236,105,128,  9,152,100,  2, 90,177, 90,+    188,225,242,237,229,238,233,225,110,128,  5,114,229,246, 97,128,+      9, 24,231,117,  2, 90,201, 90,210,234,225,242,225,244,105,128,+     10,152,242,237,245,235,232,105,128, 10, 24,233,110,  4, 90,230,+     90,239, 90,253, 91, 13,225,242,225,226,233, 99,128,  6, 58,230,+    233,238,225,236,225,242,225,226,233, 99,128,254,206,233,238,233,+    244,233,225,236,225,242,225,226,233, 99,128,254,207,237,229,228,+    233,225,236,225,242,225,226,233, 99,128,254,208,101,  3, 91, 36,+     91, 57, 91, 74,237,233,228,228,236,229,232,239,239,235,227,249,+    242,233,236,236,233, 99,128,  4,149,243,244,242,239,235,229,227,+    249,242,233,236,236,233, 99,128,  4,147,245,240,244,245,242,238,+    227,249,242,233,236,236,233, 99,128,  4,145,232, 97,  2, 91, 98,+     91,105,228,229,246, 97,128,  9, 90,231,245,242,237,245,235,232,+    105,128, 10, 90,239,239,107,128,  2, 96,250,243,241,245,225,242,+    101,128, 51,147,105,  3, 91,140, 91,151, 91,162,232,233,242,225,+    231,225,238, 97,128, 48, 78,235,225,244,225,235,225,238, 97,128,+     48,174,109,  2, 91,168, 91,179,225,242,237,229,238,233,225,110,+    128,  5, 99,229,108,130,  5,210, 91,188, 91,208,228,225,231,229,+    243,104,129,251, 50, 91,199,232,229,226,242,229,119,128,251, 50,+    232,229,226,242,229,119,128,  5,210,234,229,227,249,242,233,236,+    236,233, 99,128,  4, 83,236,239,244,244,225,108,  2, 91,241, 92,+      2,233,238,246,229,242,244,229,228,243,244,242,239,235,101,128,+      1,190,243,244,239,112,132,  2,148, 92, 17, 92, 28, 92, 34, 92,+     66,233,238,246,229,242,244,229,100,128,  2,150,237,239,100,128,+      2,192,242,229,246,229,242,243,229,100,130,  2,149, 92, 49, 92,+     55,237,239,100,128,  2,193,243,245,240,229,242,233,239,114,128,+      2,228,243,244,242,239,235,101,129,  2,161, 92, 77,242,229,246,+    229,242,243,229,100,128,  2,162,109,  2, 92, 94, 92,102,225,227,+    242,239,110,128, 30, 33,239,238,239,243,240,225,227,101,128,255,+     71,111,  2, 92,119, 92,130,232,233,242,225,231,225,238, 97,128,+     48, 84,235,225,244,225,235,225,238, 97,128, 48,180,240, 97,  2,+     92,148, 92,154,242,229,110,128, 36,162,243,241,245,225,242,101,+    128, 51,172,114,  2, 92,169, 93, 10, 97,  2, 92,175, 92,183,228,+    233,229,238,116,128, 34,  7,246,101,134,  0, 96, 92,200, 92,211,+     92,228, 92,235, 92,244, 93,  0,226,229,236,239,247,227,237, 98,+    128,  3, 22, 99,  2, 92,217, 92,222,237, 98,128,  3,  0,239,237,+     98,128,  3,  0,228,229,246, 97,128,  9, 83,236,239,247,237,239,+    100,128,  2,206,237,239,238,239,243,240,225,227,101,128,255, 64,+    244,239,238,229,227,237, 98,128,  3, 64,229,225,244,229,114,132,+      0, 62, 93, 26, 93, 45, 93, 57, 93,100,229,241,245,225,108,129,+     34,101, 93, 36,239,242,236,229,243,115,128, 34,219,237,239,238,+    239,243,240,225,227,101,128,255, 30,111,  2, 93, 63, 93, 89,114,+      2, 93, 69, 93, 82,229,241,245,233,246,225,236,229,238,116,128,+     34,115,236,229,243,115,128, 34,119,246,229,242,229,241,245,225,+    108,128, 34,103,243,237,225,236,108,128,254,101,115,  2, 93,114,+     93,122,227,242,233,240,116,128,  2, 97,244,242,239,235,101,128,+      1,229,117,  4, 93,140, 93,151, 93,208, 93,219,232,233,242,225,+    231,225,238, 97,128, 48, 80,233,108,  2, 93,158, 93,183,236,229,+    237,239,116,  2, 93,168, 93,175,236,229,230,116,128,  0,171,242,+    233,231,232,116,128,  0,187,243,233,238,231,108,  2, 93,193, 93,+    200,236,229,230,116,128, 32, 57,242,233,231,232,116,128, 32, 58,+    235,225,244,225,235,225,238, 97,128, 48,176,242,225,237,245,243,+    241,245,225,242,101,128, 51, 24,249,243,241,245,225,242,101,128,+     51,201,104,144,  0,104, 94, 22, 96,164, 96,199, 96,236, 97, 20,+     98,164, 98,184, 99,149, 99,161, 99,173,100,241,100,249,101,  4,+    101, 13,101, 93,101, 97, 97, 13, 94, 50, 94, 89, 94, 99, 94,129,+     94,154, 94,232, 94,244, 95, 13, 95, 28, 95, 57, 95, 70, 95,128,+     95,137, 97,  2, 94, 56, 94, 75,226,235,232,225,243,233,225,238,+    227,249,242,233,236,236,233, 99,128,  4,169,236,244,239,238,229,+    225,242,225,226,233, 99,128,  6,193,226,229,238,231,225,236,105,+    128,  9,185,228,101,  2, 94,106, 94,124,243,227,229,238,228,229,+    242,227,249,242,233,236,236,233, 99,128,  4,179,246, 97,128,  9,+     57,231,117,  2, 94,136, 94,145,234,225,242,225,244,105,128, 10,+    185,242,237,245,235,232,105,128, 10, 57,104,  4, 94,164, 94,173,+     94,187, 94,217,225,242,225,226,233, 99,128,  6, 45,230,233,238,+    225,236,225,242,225,226,233, 99,128,254,162,105,  2, 94,193, 94,+    208,238,233,244,233,225,236,225,242,225,226,233, 99,128,254,163,+    242,225,231,225,238, 97,128, 48,111,237,229,228,233,225,236,225,+    242,225,226,233, 99,128,254,164,233,244,245,243,241,245,225,242,+    101,128, 51, 42,235,225,244,225,235,225,238, 97,129, 48,207, 95,+      1,232,225,236,230,247,233,228,244,104,128,255,138,236,225,238,+    244,231,245,242,237,245,235,232,105,128, 10, 77,237,250, 97,  2,+     95, 36, 95, 45,225,242,225,226,233, 99,128,  6, 33,236,239,247,+    225,242,225,226,233, 99,128,  6, 33,238,231,245,236,230,233,236,+    236,229,114,128, 49,100,114,  2, 95, 76, 95, 92,228,243,233,231,+    238,227,249,242,233,236,236,233, 99,128,  4, 74,240,239,239,110,+      2, 95,101, 95,114,236,229,230,244,226,225,242,226,245,112,128,+     33,188,242,233,231,232,244,226,225,242,226,245,112,128, 33,192,+    243,241,245,225,242,101,128, 51,202,244,225,102,  3, 95,147, 95,+    239, 96, 74,240,225,244,225,104,134,  5,178, 95,167, 95,172, 95,+    186, 95,195, 95,210, 95,226,177, 54,128,  5,178, 50,  2, 95,178,+     95,182, 51,128,  5,178,102,128,  5,178,232,229,226,242,229,119,+    128,  5,178,238,225,242,242,239,247,232,229,226,242,229,119,128,+      5,178,241,245,225,242,244,229,242,232,229,226,242,229,119,128,+      5,178,247,233,228,229,232,229,226,242,229,119,128,  5,178,241,+    225,237,225,244,115,135,  5,179, 96,  6, 96, 11, 96, 16, 96, 21,+     96, 30, 96, 45, 96, 61,177, 98,128,  5,179,178, 56,128,  5,179,+    179, 52,128,  5,179,232,229,226,242,229,119,128,  5,179,238,225,+    242,242,239,247,232,229,226,242,229,119,128,  5,179,241,245,225,+    242,244,229,242,232,229,226,242,229,119,128,  5,179,247,233,228,+    229,232,229,226,242,229,119,128,  5,179,243,229,231,239,108,135,+      5,177, 96, 96, 96,101, 96,106, 96,111, 96,120, 96,135, 96,151,+    177, 55,128,  5,177,178, 52,128,  5,177,179, 48,128,  5,177,232,+    229,226,242,229,119,128,  5,177,238,225,242,242,239,247,232,229,+    226,242,229,119,128,  5,177,241,245,225,242,244,229,242,232,229,+    226,242,229,119,128,  5,177,247,233,228,229,232,229,226,242,229,+    119,128,  5,177, 98,  3, 96,172, 96,177, 96,187,225,114,128,  1,+     39,239,240,239,237,239,230,111,128, 49, 15,242,229,246,229,226,+    229,236,239,119,128, 30, 43, 99,  2, 96,205, 96,214,229,228,233,+    236,236, 97,128, 30, 41,233,242, 99,  2, 96,222, 96,227,236,101,+    128, 36,215,245,237,230,236,229,120,128,  1, 37,100,  2, 96,242,+     96,252,233,229,242,229,243,233,115,128, 30, 39,239,116,  2, 97,+      3, 97, 12,225,227,227,229,238,116,128, 30, 35,226,229,236,239,+    119,128, 30, 37,101,136,  5,212, 97, 40, 97, 73, 97, 93, 98, 66,+     98, 82, 98,127, 98,136, 98,149,225,242,116,129, 38,101, 97, 48,+    243,245,233,116,  2, 97, 57, 97, 65,226,236,225,227,107,128, 38,+    101,247,232,233,244,101,128, 38, 97,228,225,231,229,243,104,129,+    251, 52, 97, 84,232,229,226,242,229,119,128,251, 52,104,  6, 97,+    107, 97,135, 97,143, 97,193, 97,239, 98, 32, 97,  2, 97,113, 97,+    127,236,244,239,238,229,225,242,225,226,233, 99,128,  6,193,242,+    225,226,233, 99,128,  6, 71,229,226,242,229,119,128,  5,212,230,+    233,238,225,236, 97,  2, 97,154, 97,185,236,116,  2, 97,161, 97,+    173,239,238,229,225,242,225,226,233, 99,128,251,167,244,247,239,+    225,242,225,226,233, 99,128,254,234,242,225,226,233, 99,128,254,+    234,232,225,237,250,225,225,226,239,246,101,  2, 97,208, 97,222,+    230,233,238,225,236,225,242,225,226,233, 99,128,251,165,233,243,+    239,236,225,244,229,228,225,242,225,226,233, 99,128,251,164,105,+      2, 97,245, 98, 23,238,233,244,233,225,236, 97,  2, 98,  1, 98,+     15,236,244,239,238,229,225,242,225,226,233, 99,128,251,168,242,+    225,226,233, 99,128,254,235,242,225,231,225,238, 97,128, 48,120,+    237,229,228,233,225,236, 97,  2, 98, 44, 98, 58,236,244,239,238,+    229,225,242,225,226,233, 99,128,251,169,242,225,226,233, 99,128,+    254,236,233,243,229,233,229,242,225,243,241,245,225,242,101,128,+     51,123,107,  2, 98, 88, 98,112,225,244,225,235,225,238, 97,129,+     48,216, 98,100,232,225,236,230,247,233,228,244,104,128,255,141,+    245,244,225,225,242,245,243,241,245,225,242,101,128, 51, 54,238,+    231,232,239,239,107,128,  2,103,242,245,244,245,243,241,245,225,+    242,101,128, 51, 57,116,129,  5,215, 98,155,232,229,226,242,229,+    119,128,  5,215,232,239,239,107,129,  2,102, 98,173,243,245,240,+    229,242,233,239,114,128,  2,177,105,  4, 98,194, 99, 23, 99, 34,+     99, 59,229,245,104,  4, 98,206, 98,241, 99,  0, 99,  9, 97,  2,+     98,212, 98,227,227,233,242,227,236,229,235,239,242,229,225,110,+    128, 50,123,240,225,242,229,238,235,239,242,229,225,110,128, 50,+     27,227,233,242,227,236,229,235,239,242,229,225,110,128, 50,109,+    235,239,242,229,225,110,128, 49, 78,240,225,242,229,238,235,239,+    242,229,225,110,128, 50, 13,232,233,242,225,231,225,238, 97,128,+     48,114,235,225,244,225,235,225,238, 97,129, 48,210, 99, 47,232,+    225,236,230,247,233,228,244,104,128,255,139,242,233,113,134,  5,+    180, 99, 77, 99, 82, 99, 96, 99,105, 99,120, 99,136,177, 52,128,+      5,180, 50,  2, 99, 88, 99, 92, 49,128,  5,180,100,128,  5,180,+    232,229,226,242,229,119,128,  5,180,238,225,242,242,239,247,232,+    229,226,242,229,119,128,  5,180,241,245,225,242,244,229,242,232,+    229,226,242,229,119,128,  5,180,247,233,228,229,232,229,226,242,+    229,119,128,  5,180,236,233,238,229,226,229,236,239,119,128, 30,+    150,237,239,238,239,243,240,225,227,101,128,255, 72,111,  9, 99,+    193, 99,204, 99,228, 99,253,100, 85,100, 98,100,184,100,224,100,+    235,225,242,237,229,238,233,225,110,128,  5,112,232,105,  2, 99,+    211, 99,219,240,244,232,225,105,128, 14, 43,242,225,231,225,238,+     97,128, 48,123,235,225,244,225,235,225,238, 97,129, 48,219, 99,+    241,232,225,236,230,247,233,228,244,104,128,255,142,236,225,109,+    135,  5,185,100, 17,100, 22,100, 27,100, 32,100, 41,100, 56,100,+     72,177, 57,128,  5,185,178, 54,128,  5,185,179, 50,128,  5,185,+    232,229,226,242,229,119,128,  5,185,238,225,242,242,239,247,232,+    229,226,242,229,119,128,  5,185,241,245,225,242,244,229,242,232,+    229,226,242,229,119,128,  5,185,247,233,228,229,232,229,226,242,+    229,119,128,  5,185,238,239,235,232,245,235,244,232,225,105,128,+     14, 46,111,  2,100,104,100,174,107,  4,100,114,100,126,100,132,+    100,154,225,226,239,246,229,227,239,237, 98,128,  3,  9,227,237,+     98,128,  3,  9,240,225,236,225,244,225,236,233,250,229,228,226,+    229,236,239,247,227,237, 98,128,  3, 33,242,229,244,242,239,230,+    236,229,248,226,229,236,239,247,227,237, 98,128,  3, 34,238,243,+    241,245,225,242,101,128, 51, 66,114,  2,100,190,100,217,105,  2,+    100,196,100,205,227,239,240,244,233, 99,128,  3,233,250,239,238,+    244,225,236,226,225,114,128, 32, 21,238,227,237, 98,128,  3, 27,+    244,243,240,242,233,238,231,115,128, 38,104,245,243,101,128, 35,+      2,240,225,242,229,110,128, 36,163,243,245,240,229,242,233,239,+    114,128,  2,176,244,245,242,238,229,100,128,  2,101,117,  4,101,+     23,101, 34,101, 47,101, 72,232,233,242,225,231,225,238, 97,128,+     48,117,233,233,244,239,243,241,245,225,242,101,128, 51, 51,235,+    225,244,225,235,225,238, 97,129, 48,213,101, 60,232,225,236,230,+    247,233,228,244,104,128,255,140,238,231,225,242,245,237,236,225,+    245,116,129,  2,221,101, 87,227,237, 98,128,  3, 11,118,128,  1,+    149,249,240,232,229,110,132,  0, 45,101,113,101,124,101,136,101,+    159,233,238,230,229,242,233,239,114,128,246,229,237,239,238,239,+    243,240,225,227,101,128,255, 13,115,  2,101,142,101,149,237,225,+    236,108,128,254, 99,245,240,229,242,233,239,114,128,246,230,244,+    247,111,128, 32, 16,105,149,  0,105,101,211,101,234,102, 12,102,+     59,105,197,106, 61,106, 98,106,125,107, 31,107, 35,107, 73,107,+     95,107,179,108, 88,108,163,108,171,108,184,109, 15,109, 72,109,+    100,109,144,225, 99,  2,101,218,101,224,245,244,101,128,  0,237,+    249,242,233,236,236,233, 99,128,  4, 79, 98,  3,101,242,101,251,+    102,  5,229,238,231,225,236,105,128,  9,135,239,240,239,237,239,+    230,111,128, 49, 39,242,229,246,101,128,  1, 45, 99,  3,102, 20,+    102, 27,102, 49,225,242,239,110,128,  1,208,233,242, 99,  2,102,+     35,102, 40,236,101,128, 36,216,245,237,230,236,229,120,128,  0,+    238,249,242,233,236,236,233, 99,128,  4, 86,100,  4,102, 69,102,+     79,105,154,105,187,226,236,231,242,225,246,101,128,  2,  9,101,+      2,102, 85,105,149,239,231,242,225,240,104,  7,102,106,102,120,+    102,133,105, 62,105, 93,105,106,105,118,229,225,242,244,232,227,+    233,242,227,236,101,128, 50,143,230,233,242,229,227,233,242,227,+    236,101,128, 50,139,233, 99, 14,102,164,102,180,103, 23,103, 77,+    103,143,103,172,103,188,103,245,104, 38,104, 50,104, 77,104,144,+    105, 26,105, 55,225,236,236,233,225,238,227,229,240,225,242,229,+    110,128, 50, 63, 99,  4,102,190,102,201,102,215,102,222,225,236,+    236,240,225,242,229,110,128, 50, 58,229,238,244,242,229,227,233,+    242,227,236,101,128, 50,165,236,239,243,101,128, 48,  6,111,  3,+    102,230,102,245,103,  9,237,237, 97,129, 48,  1,102,238,236,229,+    230,116,128,255,100,238,231,242,225,244,245,236,225,244,233,239,+    238,240,225,242,229,110,128, 50, 55,242,242,229,227,244,227,233,+    242,227,236,101,128, 50,163,101,  3,103, 31,103, 43,103, 60,225,+    242,244,232,240,225,242,229,110,128, 50, 47,238,244,229,242,240,+    242,233,243,229,240,225,242,229,110,128, 50, 61,248,227,229,236,+    236,229,238,244,227,233,242,227,236,101,128, 50,157,102,  2,103,+     83,103, 98,229,243,244,233,246,225,236,240,225,242,229,110,128,+     50, 64,105,  2,103,104,103,133,238,225,238,227,233,225,108,  2,+    103,116,103,125,227,233,242,227,236,101,128, 50,150,240,225,242,+    229,110,128, 50, 54,242,229,240,225,242,229,110,128, 50, 43,104,+      2,103,149,103,160,225,246,229,240,225,242,229,110,128, 50, 50,+    233,231,232,227,233,242,227,236,101,128, 50,164,233,244,229,242,+    225,244,233,239,238,237,225,242,107,128, 48,  5,108,  3,103,196,+    103,222,103,234,225,226,239,114,  2,103,205,103,214,227,233,242,+    227,236,101,128, 50,152,240,225,242,229,110,128, 50, 56,229,230,+    244,227,233,242,227,236,101,128, 50,167,239,247,227,233,242,227,+    236,101,128, 50,166,109,  2,103,251,104, 27,101,  2,104,  1,104,+     16,228,233,227,233,238,229,227,233,242,227,236,101,128, 50,169,+    244,225,236,240,225,242,229,110,128, 50, 46,239,239,238,240,225,+    242,229,110,128, 50, 42,238,225,237,229,240,225,242,229,110,128,+     50, 52,112,  2,104, 56,104, 64,229,242,233,239,100,128, 48,  2,+    242,233,238,244,227,233,242,227,236,101,128, 50,158,114,  2,104,+     83,104,131,101,  3,104, 91,104,102,104,117,225,227,232,240,225,+    242,229,110,128, 50, 67,240,242,229,243,229,238,244,240,225,242,+    229,110,128, 50, 57,243,239,245,242,227,229,240,225,242,229,110,+    128, 50, 62,233,231,232,244,227,233,242,227,236,101,128, 50,168,+    115,  5,104,156,104,185,104,199,104,224,104,252,101,  2,104,162,+    104,175,227,242,229,244,227,233,242,227,236,101,128, 50,153,236,+    230,240,225,242,229,110,128, 50, 66,239,227,233,229,244,249,240,+    225,242,229,110,128, 50, 51,112,  2,104,205,104,211,225,227,101,+    128, 48,  0,229,227,233,225,236,240,225,242,229,110,128, 50, 53,+    116,  2,104,230,104,241,239,227,235,240,225,242,229,110,128, 50,+     49,245,228,249,240,225,242,229,110,128, 50, 59,117,  2,105,  2,+    105, 11,238,240,225,242,229,110,128, 50, 48,240,229,242,246,233,+    243,229,240,225,242,229,110,128, 50, 60,119,  2,105, 32,105, 44,+    225,244,229,242,240,225,242,229,110,128, 50, 44,239,239,228,240,+    225,242,229,110,128, 50, 45,250,229,242,111,128, 48,  7,109,  2,+    105, 68,105, 81,229,244,225,236,227,233,242,227,236,101,128, 50,+    142,239,239,238,227,233,242,227,236,101,128, 50,138,238,225,237,+    229,227,233,242,227,236,101,128, 50,148,243,245,238,227,233,242,+    227,236,101,128, 50,144,119,  2,105,124,105,137,225,244,229,242,+    227,233,242,227,236,101,128, 50,140,239,239,228,227,233,242,227,+    236,101,128, 50,141,246, 97,128,  9,  7,233,229,242,229,243,233,+    115,130,  0,239,105,168,105,176,225,227,245,244,101,128, 30, 47,+    227,249,242,233,236,236,233, 99,128,  4,229,239,244,226,229,236,+    239,119,128, 30,203,101,  3,105,205,105,221,105,232,226,242,229,+    246,229,227,249,242,233,236,236,233, 99,128,  4,215,227,249,242,+    233,236,236,233, 99,128,  4, 53,245,238,103,  4,105,244,106, 23,+    106, 38,106, 47, 97,  2,105,250,106,  9,227,233,242,227,236,229,+    235,239,242,229,225,110,128, 50,117,240,225,242,229,238,235,239,+    242,229,225,110,128, 50, 21,227,233,242,227,236,229,235,239,242,+    229,225,110,128, 50,103,235,239,242,229,225,110,128, 49, 71,240,+    225,242,229,238,235,239,242,229,225,110,128, 50,  7,103,  2,106,+     67,106, 74,242,225,246,101,128,  0,236,117,  2,106, 80,106, 89,+    234,225,242,225,244,105,128, 10,135,242,237,245,235,232,105,128,+     10,  7,104,  2,106,104,106,114,233,242,225,231,225,238, 97,128,+     48, 68,239,239,235,225,226,239,246,101,128, 30,201,105,  8,106,+    143,106,153,106,164,106,171,106,196,106,212,106,227,106,243,226,+    229,238,231,225,236,105,128,  9,136,227,249,242,233,236,236,233,+     99,128,  4, 56,228,229,246, 97,128,  9,  8,231,117,  2,106,178,+    106,187,234,225,242,225,244,105,128, 10,136,242,237,245,235,232,+    105,128, 10,  8,237,225,244,242,225,231,245,242,237,245,235,232,+    105,128, 10, 64,238,246,229,242,244,229,228,226,242,229,246,101,+    128,  2, 11,243,232,239,242,244,227,249,242,233,236,236,233, 99,+    128,  4, 57,246,239,247,229,236,243,233,231,110,  3,107,  3,107,+     13,107, 20,226,229,238,231,225,236,105,128,  9,192,228,229,246,+     97,128,  9, 64,231,245,234,225,242,225,244,105,128, 10,192,106,+    128,  1, 51,107,  2,107, 41,107, 65,225,244,225,235,225,238, 97,+    129, 48,164,107, 53,232,225,236,230,247,233,228,244,104,128,255,+    114,239,242,229,225,110,128, 49, 99,108,  2,107, 79,107, 84,228,+    101,128,  2,220,245,249,232,229,226,242,229,119,128,  5,172,109,+      2,107,101,107,168, 97,  3,107,109,107,129,107,154,227,242,239,+    110,129,  1, 43,107,118,227,249,242,233,236,236,233, 99,128,  4,+    227,231,229,239,242,225,240,240,242,239,248,233,237,225,244,229,+    236,249,229,241,245,225,108,128, 34, 83,244,242,225,231,245,242,+    237,245,235,232,105,128, 10, 63,239,238,239,243,240,225,227,101,+    128,255, 73,110,  5,107,191,107,201,107,210,107,222,108, 50,227,+    242,229,237,229,238,116,128, 34,  6,230,233,238,233,244,121,128,+     34, 30,233,225,242,237,229,238,233,225,110,128,  5,107,116,  2,+    107,228,108, 40,101,  2,107,234,108, 29,231,242,225,108,131, 34,+     43,107,247,108,  9,108, 14, 98,  2,107,253,108,  5,239,244,244,+    239,109,128, 35, 33,116,128, 35, 33,229,120,128,248,245,116,  2,+    108, 20,108, 25,239,112,128, 35, 32,112,128, 35, 32,242,243,229,+    227,244,233,239,110,128, 34, 41,233,243,241,245,225,242,101,128,+     51,  5,118,  3,108, 58,108, 67,108, 76,226,245,236,236,229,116,+    128, 37,216,227,233,242,227,236,101,128, 37,217,243,237,233,236,+    229,230,225,227,101,128, 38, 59,111,  3,108, 96,108,107,108,115,+    227,249,242,233,236,236,233, 99,128,  4, 81,231,239,238,229,107,+    128,  1, 47,244, 97,131,  3,185,108,126,108,147,108,155,228,233,+    229,242,229,243,233,115,129,  3,202,108,139,244,239,238,239,115,+    128,  3,144,236,225,244,233,110,128,  2,105,244,239,238,239,115,+    128,  3,175,240,225,242,229,110,128, 36,164,242,233,231,245,242,+    237,245,235,232,105,128, 10,114,115,  4,108,194,108,239,108,253,+    109,  5,237,225,236,108,  2,108,203,108,214,232,233,242,225,231,+    225,238, 97,128, 48, 67,235,225,244,225,235,225,238, 97,129, 48,+    163,108,227,232,225,236,230,247,233,228,244,104,128,255,104,243,+    232,225,242,226,229,238,231,225,236,105,128,  9,250,244,242,239,+    235,101,128,  2,104,245,240,229,242,233,239,114,128,246,237,116,+      2,109, 21,109, 55,229,242,225,244,233,239,110,  2,109, 33,109,+     44,232,233,242,225,231,225,238, 97,128, 48,157,235,225,244,225,+    235,225,238, 97,128, 48,253,233,236,228,101,129,  1, 41,109, 64,+    226,229,236,239,119,128, 30, 45,117,  2,109, 78,109, 89,226,239,+    240,239,237,239,230,111,128, 49, 41,227,249,242,233,236,236,233,+     99,128,  4, 78,246,239,247,229,236,243,233,231,110,  3,109,116,+    109,126,109,133,226,229,238,231,225,236,105,128,  9,191,228,229,+    246, 97,128,  9, 63,231,245,234,225,242,225,244,105,128, 10,191,+    250,232,233,244,243, 97,  2,109,155,109,166,227,249,242,233,236,+    236,233, 99,128,  4,117,228,226,236,231,242,225,246,229,227,249,+    242,233,236,236,233, 99,128,  4,119,106,138,  0,106,109,209,110,+     16,110, 27,110, 77,110, 93,110,206,111, 19,111, 24,111, 36,111,+     44, 97,  4,109,219,109,230,109,240,109,247,225,242,237,229,238,+    233,225,110,128,  5,113,226,229,238,231,225,236,105,128,  9,156,+    228,229,246, 97,128,  9, 28,231,117,  2,109,254,110,  7,234,225,+    242,225,244,105,128, 10,156,242,237,245,235,232,105,128, 10, 28,+    226,239,240,239,237,239,230,111,128, 49, 16, 99,  3,110, 35,110,+     42,110, 64,225,242,239,110,128,  1,240,233,242, 99,  2,110, 50,+    110, 55,236,101,128, 36,217,245,237,230,236,229,120,128,  1, 53,+    242,239,243,243,229,228,244,225,233,108,128,  2,157,228,239,244,+    236,229,243,243,243,244,242,239,235,101,128,  2, 95,101,  3,110,+    101,110,112,110,177,227,249,242,233,236,236,233, 99,128,  4, 88,+    229,109,  4,110,123,110,132,110,146,110,162,225,242,225,226,233,+     99,128,  6, 44,230,233,238,225,236,225,242,225,226,233, 99,128,+    254,158,233,238,233,244,233,225,236,225,242,225,226,233, 99,128,+    254,159,237,229,228,233,225,236,225,242,225,226,233, 99,128,254,+    160,104,  2,110,183,110,192,225,242,225,226,233, 99,128,  6,152,+    230,233,238,225,236,225,242,225,226,233, 99,128,251,139,104,  2,+    110,212,111,  6, 97,  3,110,220,110,230,110,237,226,229,238,231,+    225,236,105,128,  9,157,228,229,246, 97,128,  9, 29,231,117,  2,+    110,244,110,253,234,225,242,225,244,105,128, 10,157,242,237,245,+    235,232,105,128, 10, 29,229,232,225,242,237,229,238,233,225,110,+    128,  5,123,233,115,128, 48,  4,237,239,238,239,243,240,225,227,+    101,128,255, 74,240,225,242,229,110,128, 36,165,243,245,240,229,+    242,233,239,114,128,  2,178,107,146,  0,107,111, 95,113,184,113,+    195,114,  1,114, 12,114,102,114,116,115,224,116,164,116,177,116,+    203,116,252,117,134,117,156,117,169,117,192,117,234,117,244, 97,+     12,111,121,111,153,111,175,111,205,112, 63,112, 88,112,118,112,+    143,112,249,113,  7,113,130,113,159, 98,  2,111,127,111,144,225,+    243,232,235,233,242,227,249,242,233,236,236,233, 99,128,  4,161,+    229,238,231,225,236,105,128,  9,149, 99,  2,111,159,111,165,245,+    244,101,128, 30, 49,249,242,233,236,236,233, 99,128,  4, 58,228,+    101,  2,111,182,111,200,243,227,229,238,228,229,242,227,249,242,+    233,236,236,233, 99,128,  4,155,246, 97,128,  9, 21,102,135,  5,+    219,111,223,111,232,111,252,112, 10,112, 19,112, 35,112, 50,225,+    242,225,226,233, 99,128,  6, 67,228,225,231,229,243,104,129,251,+     59,111,243,232,229,226,242,229,119,128,251, 59,230,233,238,225,+    236,225,242,225,226,233, 99,128,254,218,232,229,226,242,229,119,+    128,  5,219,233,238,233,244,233,225,236,225,242,225,226,233, 99,+    128,254,219,237,229,228,233,225,236,225,242,225,226,233, 99,128,+    254,220,242,225,230,229,232,229,226,242,229,119,128,251, 77,231,+    117,  2,112, 70,112, 79,234,225,242,225,244,105,128, 10,149,242,+    237,245,235,232,105,128, 10, 21,104,  2,112, 94,112,104,233,242,+    225,231,225,238, 97,128, 48, 75,239,239,235,227,249,242,233,236,+    236,233, 99,128,  4,196,235,225,244,225,235,225,238, 97,129, 48,+    171,112,131,232,225,236,230,247,233,228,244,104,128,255,118,112,+      2,112,149,112,170,240, 97,129,  3,186,112,156,243,249,237,226,+    239,236,231,242,229,229,107,128,  3,240,249,229,239,245,110,  3,+    112,182,112,196,112,230,237,233,229,245,237,235,239,242,229,225,+    110,128, 49,113,112,  2,112,202,112,217,232,233,229,245,240,232,+    235,239,242,229,225,110,128, 49,132,233,229,245,240,235,239,242,+    229,225,110,128, 49,120,243,243,225,238,231,240,233,229,245,240,+    235,239,242,229,225,110,128, 49,121,242,239,242,233,233,243,241,+    245,225,242,101,128, 51, 13,115,  5,113, 19,113, 63,113, 78,113,+     86,113,114,232,233,228,225,225,245,244,111,  2,113, 32,113, 41,+    225,242,225,226,233, 99,128,  6, 64,238,239,243,233,228,229,226,+    229,225,242,233,238,231,225,242,225,226,233, 99,128,  6, 64,237,+    225,236,236,235,225,244,225,235,225,238, 97,128, 48,245,241,245,+    225,242,101,128, 51,132,242, 97,  2,113, 93,113,102,225,242,225,+    226,233, 99,128,  6, 80,244,225,238,225,242,225,226,233, 99,128,+      6, 77,244,242,239,235,229,227,249,242,233,236,236,233, 99,128,+      4,159,244,225,232,233,242,225,240,242,239,236,239,238,231,237,+    225,242,235,232,225,236,230,247,233,228,244,104,128,255,112,246,+    229,242,244,233,227,225,236,243,244,242,239,235,229,227,249,242,+    233,236,236,233, 99,128,  4,157,226,239,240,239,237,239,230,111,+    128, 49, 14, 99,  4,113,205,113,227,113,236,113,244, 97,  2,113,+    211,113,221,236,243,241,245,225,242,101,128, 51,137,242,239,110,+    128,  1,233,229,228,233,236,236, 97,128,  1, 55,233,242,227,236,+    101,128, 36,218,239,237,237,225,225,227,227,229,238,116,128,  1,+     55,228,239,244,226,229,236,239,119,128, 30, 51,101,  4,114, 22,+    114, 49,114, 74,114, 86,104,  2,114, 28,114, 39,225,242,237,229,+    238,233,225,110,128,  5,132,233,242,225,231,225,238, 97,128, 48,+     81,235,225,244,225,235,225,238, 97,129, 48,177,114, 62,232,225,+    236,230,247,233,228,244,104,128,255,121,238,225,242,237,229,238,+    233,225,110,128,  5,111,243,237,225,236,236,235,225,244,225,235,+    225,238, 97,128, 48,246,231,242,229,229,238,236,225,238,228,233,+     99,128,  1, 56,104,  6,114,130,115,  3,115, 14,115, 39,115,126,+    115,214, 97,  5,114,142,114,152,114,163,114,170,114,195,226,229,+    238,231,225,236,105,128,  9,150,227,249,242,233,236,236,233, 99,+    128,  4, 69,228,229,246, 97,128,  9, 22,231,117,  2,114,177,114,+    186,234,225,242,225,244,105,128, 10,150,242,237,245,235,232,105,+    128, 10, 22,104,  4,114,205,114,214,114,228,114,244,225,242,225,+    226,233, 99,128,  6, 46,230,233,238,225,236,225,242,225,226,233,+     99,128,254,166,233,238,233,244,233,225,236,225,242,225,226,233,+     99,128,254,167,237,229,228,233,225,236,225,242,225,226,233, 99,+    128,254,168,229,233,227,239,240,244,233, 99,128,  3,231,232, 97,+      2,115, 21,115, 28,228,229,246, 97,128,  9, 89,231,245,242,237,+    245,235,232,105,128, 10, 89,233,229,245,235,104,  4,115, 53,115,+     88,115,103,115,112, 97,  2,115, 59,115, 74,227,233,242,227,236,+    229,235,239,242,229,225,110,128, 50,120,240,225,242,229,238,235,+    239,242,229,225,110,128, 50, 24,227,233,242,227,236,229,235,239,+    242,229,225,110,128, 50,106,235,239,242,229,225,110,128, 49, 75,+    240,225,242,229,238,235,239,242,229,225,110,128, 50, 10,111,  4,+    115,136,115,185,115,195,115,200,235,104,  4,115,147,115,156,115,+    165,115,175,225,233,244,232,225,105,128, 14,  2,239,238,244,232,+    225,105,128, 14,  5,245,225,244,244,232,225,105,128, 14,  3,247,+    225,233,244,232,225,105,128, 14,  4,237,245,244,244,232,225,105,+    128, 14, 91,239,107,128,  1,153,242,225,235,232,225,238,231,244,+    232,225,105,128, 14,  6,250,243,241,245,225,242,101,128, 51,145,+    105,  4,115,234,115,245,116, 14,116, 63,232,233,242,225,231,225,+    238, 97,128, 48, 77,235,225,244,225,235,225,238, 97,129, 48,173,+    116,  2,232,225,236,230,247,233,228,244,104,128,255,119,242,111,+      3,116, 23,116, 38,116, 54,231,245,242,225,237,245,243,241,245,+    225,242,101,128, 51, 21,237,229,229,244,239,242,245,243,241,245,+    225,242,101,128, 51, 22,243,241,245,225,242,101,128, 51, 20,249,+    229,239,107,  5,116, 78,116,113,116,128,116,137,116,151, 97,  2,+    116, 84,116, 99,227,233,242,227,236,229,235,239,242,229,225,110,+    128, 50,110,240,225,242,229,238,235,239,242,229,225,110,128, 50,+     14,227,233,242,227,236,229,235,239,242,229,225,110,128, 50, 96,+    235,239,242,229,225,110,128, 49, 49,240,225,242,229,238,235,239,+    242,229,225,110,128, 50,  0,243,233,239,243,235,239,242,229,225,+    110,128, 49, 51,234,229,227,249,242,233,236,236,233, 99,128,  4,+     92,108,  2,116,183,116,194,233,238,229,226,229,236,239,119,128,+     30, 53,243,241,245,225,242,101,128, 51,152,109,  3,116,211,116,+    225,116,236,227,245,226,229,228,243,241,245,225,242,101,128, 51,+    166,239,238,239,243,240,225,227,101,128,255, 75,243,241,245,225,+    242,229,228,243,241,245,225,242,101,128, 51,162,111,  5,117,  8,+    117, 34,117, 72,117, 84,117, 98,104,  2,117, 14,117, 24,233,242,+    225,231,225,238, 97,128, 48, 83,237,243,241,245,225,242,101,128,+     51,192,235, 97,  2,117, 41,117, 49,233,244,232,225,105,128, 14,+      1,244,225,235,225,238, 97,129, 48,179,117, 60,232,225,236,230,+    247,233,228,244,104,128,255,122,239,240,239,243,241,245,225,242,+    101,128, 51, 30,240,240,225,227,249,242,233,236,236,233, 99,128,+      4,129,114,  2,117,104,117,124,229,225,238,243,244,225,238,228,+    225,242,228,243,249,237,226,239,108,128, 50,127,239,238,233,243,+    227,237, 98,128,  3, 67,240, 97,  2,117,141,117,147,242,229,110,+    128, 36,166,243,241,245,225,242,101,128, 51,170,243,233,227,249,+    242,233,236,236,233, 99,128,  4,111,116,  2,117,175,117,184,243,+    241,245,225,242,101,128, 51,207,245,242,238,229,100,128,  2,158,+    117,  2,117,198,117,209,232,233,242,225,231,225,238, 97,128, 48,+     79,235,225,244,225,235,225,238, 97,129, 48,175,117,222,232,225,+    236,230,247,233,228,244,104,128,255,120,246,243,241,245,225,242,+    101,128, 51,184,247,243,241,245,225,242,101,128, 51,190,108,146,+      0,108,118, 38,120, 65,120, 94,120,160,120,198,121, 94,121,103,+    121,119,121,143,121,161,122, 23,122, 64,122,199,122,207,122,240,+    122,249,123,  1,123, 63, 97,  7,118, 54,118, 64,118, 71,118, 78,+    118,103,118,119,120, 53,226,229,238,231,225,236,105,128,  9,178,+    227,245,244,101,128,  1, 58,228,229,246, 97,128,  9, 50,231,117,+      2,118, 85,118, 94,234,225,242,225,244,105,128, 10,178,242,237,+    245,235,232,105,128, 10, 50,235,235,232,225,238,231,249,225,239,+    244,232,225,105,128, 14, 69,109, 10,118,141,119, 80,119, 97,119,+    135,119,149,119,168,119,184,119,204,119,224,119,247, 97,  2,118,+    147,119, 72,236,229,102,  4,118,159,118,173,119,  9,119, 26,230,+    233,238,225,236,225,242,225,226,233, 99,128,254,252,232,225,237,+    250, 97,  2,118,183,118,224,225,226,239,246,101,  2,118,193,118,+    207,230,233,238,225,236,225,242,225,226,233, 99,128,254,248,233,+    243,239,236,225,244,229,228,225,242,225,226,233, 99,128,254,247,+    226,229,236,239,119,  2,118,234,118,248,230,233,238,225,236,225,+    242,225,226,233, 99,128,254,250,233,243,239,236,225,244,229,228,+    225,242,225,226,233, 99,128,254,249,233,243,239,236,225,244,229,+    228,225,242,225,226,233, 99,128,254,251,237,225,228,228,225,225,+    226,239,246,101,  2,119, 41,119, 55,230,233,238,225,236,225,242,+    225,226,233, 99,128,254,246,233,243,239,236,225,244,229,228,225,+    242,225,226,233, 99,128,254,245,242,225,226,233, 99,128,  6, 68,+    226,228, 97,129,  3,187,119, 88,243,244,242,239,235,101,128,  1,+    155,229,100,130,  5,220,119,106,119,126,228,225,231,229,243,104,+    129,251, 60,119,117,232,229,226,242,229,119,128,251, 60,232,229,+    226,242,229,119,128,  5,220,230,233,238,225,236,225,242,225,226,+    233, 99,128,254,222,232,225,232,233,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,252,202,233,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,254,223,234,229,229,237,233,238,233,244,+    233,225,236,225,242,225,226,233, 99,128,252,201,235,232,225,232,+    233,238,233,244,233,225,236,225,242,225,226,233, 99,128,252,203,+    236,225,237,232,229,232,233,243,239,236,225,244,229,228,225,242,+    225,226,233, 99,128,253,242,237,101,  2,119,254,120, 11,228,233,+    225,236,225,242,225,226,233, 99,128,254,224,229,109,  2,120, 18,+    120, 37,232,225,232,233,238,233,244,233,225,236,225,242,225,226,+    233, 99,128,253,136,233,238,233,244,233,225,236,225,242,225,226,+    233, 99,128,252,204,242,231,229,227,233,242,227,236,101,128, 37,+    239, 98,  3,120, 73,120, 78,120, 84,225,114,128,  1,154,229,236,+    116,128,  2,108,239,240,239,237,239,230,111,128, 49, 12, 99,  4,+    120,104,120,111,120,120,120,147,225,242,239,110,128,  1, 62,229,+    228,233,236,236, 97,128,  1, 60,233,242, 99,  2,120,128,120,133,+    236,101,128, 36,219,245,237,230,236,229,248,226,229,236,239,119,+    128, 30, 61,239,237,237,225,225,227,227,229,238,116,128,  1, 60,+    228,239,116,130,  1, 64,120,170,120,179,225,227,227,229,238,116,+    128,  1, 64,226,229,236,239,119,129, 30, 55,120,189,237,225,227,+    242,239,110,128, 30, 57,101,  3,120,206,120,244,121, 89,230,116,+      2,120,213,120,229,225,238,231,236,229,225,226,239,246,229,227,+    237, 98,128,  3, 26,244,225,227,235,226,229,236,239,247,227,237,+     98,128,  3, 24,243,115,132,  0, 60,121,  1,121, 23,121, 35,121,+     81,229,241,245,225,108,129, 34,100,121, 11,239,242,231,242,229,+    225,244,229,114,128, 34,218,237,239,238,239,243,240,225,227,101,+    128,255, 28,111,  2,121, 41,121, 70,114,  2,121, 47,121, 60,229,+    241,245,233,246,225,236,229,238,116,128, 34,114,231,242,229,225,+    244,229,114,128, 34,118,246,229,242,229,241,245,225,108,128, 34,+    102,243,237,225,236,108,128,254,100,250,104,128,  2,110,230,226,+    236,239,227,107,128, 37,140,232,239,239,235,242,229,244,242,239,+    230,236,229,120,128,  2,109,105,  2,121,125,121,130,242, 97,128,+     32,164,247,238,225,242,237,229,238,233,225,110,128,  5,108,106,+    129,  1,201,121,149,229,227,249,242,233,236,236,233, 99,128,  4,+     89,108,132,246,192,121,173,121,197,121,208,121,217, 97,  2,121,+    179,121,186,228,229,246, 97,128,  9, 51,231,245,234,225,242,225,+    244,105,128, 10,179,233,238,229,226,229,236,239,119,128, 30, 59,+    236,225,228,229,246, 97,128,  9, 52,246,239,227,225,236,233, 99,+      3,121,231,121,241,121,248,226,229,238,231,225,236,105,128,  9,+    225,228,229,246, 97,128,  9, 97,246,239,247,229,236,243,233,231,+    110,  2,122,  6,122, 16,226,229,238,231,225,236,105,128,  9,227,+    228,229,246, 97,128,  9, 99,109,  3,122, 31,122, 44,122, 55,233,+    228,228,236,229,244,233,236,228,101,128,  2,107,239,238,239,243,+    240,225,227,101,128,255, 76,243,241,245,225,242,101,128, 51,208,+    111,  6,122, 78,122, 90,122,132,122,143,122,149,122,191,227,232,+    245,236,225,244,232,225,105,128, 14, 44,231,233,227,225,108,  3,+    122,102,122,108,122,127,225,238,100,128, 34, 39,238,239,116,129,+      0,172,122,116,242,229,246,229,242,243,229,100,128, 35, 16,239,+    114,128, 34, 40,236,233,238,231,244,232,225,105,128, 14, 37,238,+    231,115,128,  1,127,247,236,233,238,101,  2,122,159,122,182, 99,+      2,122,165,122,177,229,238,244,229,242,236,233,238,101,128,254,+     78,237, 98,128,  3, 50,228,225,243,232,229,100,128,254, 77,250,+    229,238,231,101,128, 37,202,240,225,242,229,110,128, 36,167,115,+      3,122,215,122,222,122,230,236,225,243,104,128,  1, 66,241,245,+    225,242,101,128, 33, 19,245,240,229,242,233,239,114,128,246,238,+    244,243,232,225,228,101,128, 37,145,245,244,232,225,105,128, 14,+     38,246,239,227,225,236,233, 99,  3,123, 15,123, 25,123, 32,226,+    229,238,231,225,236,105,128,  9,140,228,229,246, 97,128,  9, 12,+    246,239,247,229,236,243,233,231,110,  2,123, 46,123, 56,226,229,+    238,231,225,236,105,128,  9,226,228,229,246, 97,128,  9, 98,248,+    243,241,245,225,242,101,128, 51,211,109,144,  0,109,123,109,125,+    218,125,243,126, 14,126, 39,127, 92,127,114,128,169,128,199,128,+    248,129, 99,129,121,129,146,129,155,130,182,130,210, 97, 12,123,+    135,123,145,123,209,123,216,123,241,124, 33,125,125,125,150,125,+    155,125,169,125,181,125,186,226,229,238,231,225,236,105,128,  9,+    174, 99,  2,123,151,123,203,242,239,110,132,  0,175,123,165,123,+    176,123,182,123,191,226,229,236,239,247,227,237, 98,128,  3, 49,+    227,237, 98,128,  3,  4,236,239,247,237,239,100,128,  2,205,237,+    239,238,239,243,240,225,227,101,128,255,227,245,244,101,128, 30,+     63,228,229,246, 97,128,  9, 46,231,117,  2,123,223,123,232,234,+    225,242,225,244,105,128, 10,174,242,237,245,235,232,105,128, 10,+     46,104,  2,123,247,124, 23,225,240,225,235,104,  2,124,  1,124,+     10,232,229,226,242,229,119,128,  5,164,236,229,230,244,232,229,+    226,242,229,119,128,  5,164,233,242,225,231,225,238, 97,128, 48,+    126,105,  5,124, 45,124,114,124,177,124,207,125,113,227,232,225,+    244,244,225,247, 97,  3,124, 60,124, 91,124, 98,236,239,119,  2,+    124, 68,124, 79,236,229,230,244,244,232,225,105,128,248,149,242,+    233,231,232,244,244,232,225,105,128,248,148,244,232,225,105,128,+     14, 75,245,240,240,229,242,236,229,230,244,244,232,225,105,128,+    248,147,229,107,  3,124,123,124,154,124,161,236,239,119,  2,124,+    131,124,142,236,229,230,244,244,232,225,105,128,248,140,242,233,+    231,232,244,244,232,225,105,128,248,139,244,232,225,105,128, 14,+     72,245,240,240,229,242,236,229,230,244,244,232,225,105,128,248,+    138,232,225,238,225,235,225,116,  2,124,189,124,200,236,229,230,+    244,244,232,225,105,128,248,132,244,232,225,105,128, 14, 49,116,+      3,124,215,124,243,125, 50,225,233,235,232,117,  2,124,225,124,+    236,236,229,230,244,244,232,225,105,128,248,137,244,232,225,105,+    128, 14, 71,232,111,  3,124,252,125, 27,125, 34,236,239,119,  2,+    125,  4,125, 15,236,229,230,244,244,232,225,105,128,248,143,242,+    233,231,232,244,244,232,225,105,128,248,142,244,232,225,105,128,+     14, 73,245,240,240,229,242,236,229,230,244,244,232,225,105,128,+    248,141,242,105,  3,125, 59,125, 90,125, 97,236,239,119,  2,125,+     67,125, 78,236,229,230,244,244,232,225,105,128,248,146,242,233,+    231,232,244,244,232,225,105,128,248,145,244,232,225,105,128, 14,+     74,245,240,240,229,242,236,229,230,244,244,232,225,105,128,248,+    144,249,225,237,239,235,244,232,225,105,128, 14, 70,235,225,244,+    225,235,225,238, 97,129, 48,222,125,138,232,225,236,230,247,233,+    228,244,104,128,255,143,236,101,128, 38, 66,238,243,249,239,238,+    243,241,245,225,242,101,128, 51, 71,241,225,230,232,229,226,242,+    229,119,128,  5,190,242,115,128, 38, 66,115,  2,125,192,125,210,+    239,242,225,227,233,242,227,236,229,232,229,226,242,229,119,128,+      5,175,241,245,225,242,101,128, 51,131, 98,  2,125,224,125,234,+    239,240,239,237,239,230,111,128, 49,  7,243,241,245,225,242,101,+    128, 51,212, 99,  2,125,249,126,  1,233,242,227,236,101,128, 36,+    220,245,226,229,228,243,241,245,225,242,101,128, 51,165,228,239,+    116,  2,126, 22,126, 31,225,227,227,229,238,116,128, 30, 65,226,+    229,236,239,119,128, 30, 67,101,  7,126, 55,126,182,126,193,126,+    208,126,233,127, 14,127, 26,101,  2,126, 61,126,169,109,  4,126,+     71,126, 80,126, 94,126,110,225,242,225,226,233, 99,128,  6, 69,+    230,233,238,225,236,225,242,225,226,233, 99,128,254,226,233,238,+    233,244,233,225,236,225,242,225,226,233, 99,128,254,227,237,101,+      2,126,117,126,130,228,233,225,236,225,242,225,226,233, 99,128,+    254,228,229,237,105,  2,126,138,126,153,238,233,244,233,225,236,+    225,242,225,226,233, 99,128,252,209,243,239,236,225,244,229,228,+    225,242,225,226,233, 99,128,252, 72,244,239,242,245,243,241,245,+    225,242,101,128, 51, 77,232,233,242,225,231,225,238, 97,128, 48,+    129,233,250,233,229,242,225,243,241,245,225,242,101,128, 51,126,+    235,225,244,225,235,225,238, 97,129, 48,225,126,221,232,225,236,+    230,247,233,228,244,104,128,255,146,109,130,  5,222,126,241,127,+      5,228,225,231,229,243,104,129,251, 62,126,252,232,229,226,242,+    229,119,128,251, 62,232,229,226,242,229,119,128,  5,222,238,225,+    242,237,229,238,233,225,110,128,  5,116,242,235,232, 97,  3,127,+     37,127, 46,127, 79,232,229,226,242,229,119,128,  5,165,235,229,+    230,245,236, 97,  2,127, 57,127, 66,232,229,226,242,229,119,128,+      5,166,236,229,230,244,232,229,226,242,229,119,128,  5,166,236,+    229,230,244,232,229,226,242,229,119,128,  5,165,104,  2,127, 98,+    127,104,239,239,107,128,  2,113,250,243,241,245,225,242,101,128,+     51,146,105,  6,127,128,127,165,128, 46,128, 57,128, 82,128,139,+    228,100,  2,127,135,127,160,236,229,228,239,244,235,225,244,225,+    235,225,238,225,232,225,236,230,247,233,228,244,104,128,255,101,+    239,116,128,  0,183,229,245,109,  5,127,179,127,214,127,229,127,+    238,128, 33, 97,  2,127,185,127,200,227,233,242,227,236,229,235,+    239,242,229,225,110,128, 50,114,240,225,242,229,238,235,239,242,+    229,225,110,128, 50, 18,227,233,242,227,236,229,235,239,242,229,+    225,110,128, 50,100,235,239,242,229,225,110,128, 49, 65,112,  2,+    127,244,128, 20, 97,  2,127,250,128,  8,238,243,233,239,243,235,+    239,242,229,225,110,128, 49,112,242,229,238,235,239,242,229,225,+    110,128, 50,  4,233,229,245,240,235,239,242,229,225,110,128, 49,+    110,243,233,239,243,235,239,242,229,225,110,128, 49,111,232,233,+    242,225,231,225,238, 97,128, 48,127,235,225,244,225,235,225,238,+     97,129, 48,223,128, 70,232,225,236,230,247,233,228,244,104,128,+    255,144,238,117,  2,128, 89,128,134,115,132, 34, 18,128,101,128,+    112,128,121,128,127,226,229,236,239,247,227,237, 98,128,  3, 32,+    227,233,242,227,236,101,128, 34,150,237,239,100,128,  2,215,240,+    236,245,115,128, 34, 19,244,101,128, 32, 50,242,105,  2,128,146,+    128,160,226,225,225,242,245,243,241,245,225,242,101,128, 51, 74,+    243,241,245,225,242,101,128, 51, 73,108,  2,128,175,128,190,239,+    238,231,236,229,231,244,245,242,238,229,100,128,  2,112,243,241,+    245,225,242,101,128, 51,150,109,  3,128,207,128,221,128,232,227,+    245,226,229,228,243,241,245,225,242,101,128, 51,163,239,238,239,+    243,240,225,227,101,128,255, 77,243,241,245,225,242,229,228,243,+    241,245,225,242,101,128, 51,159,111,  5,129,  4,129, 30,129, 55,+    129, 65,129, 74,104,  2,129, 10,129, 20,233,242,225,231,225,238,+     97,128, 48,130,237,243,241,245,225,242,101,128, 51,193,235,225,+    244,225,235,225,238, 97,129, 48,226,129, 43,232,225,236,230,247,+    233,228,244,104,128,255,147,236,243,241,245,225,242,101,128, 51,+    214,237,225,244,232,225,105,128, 14, 33,246,229,242,243,243,241,+    245,225,242,101,129, 51,167,129, 89,228,243,241,245,225,242,101,+    128, 51,168,240, 97,  2,129,106,129,112,242,229,110,128, 36,168,+    243,241,245,225,242,101,128, 51,171,115,  2,129,127,129,136,243,+    241,245,225,242,101,128, 51,179,245,240,229,242,233,239,114,128,+    246,239,244,245,242,238,229,100,128,  2,111,117,141,  0,181,129,+    185,129,189,129,199,129,223,129,233,129,255,130, 10,130, 35,130,+     58,130, 68,130, 98,130,162,130,172, 49,128,  0,181,225,243,241,+    245,225,242,101,128, 51,130,227,104,  2,129,206,129,216,231,242,+    229,225,244,229,114,128, 34,107,236,229,243,115,128, 34,106,230,+    243,241,245,225,242,101,128, 51,140,103,  2,129,239,129,246,242,+    229,229,107,128,  3,188,243,241,245,225,242,101,128, 51,141,232,+    233,242,225,231,225,238, 97,128, 48,128,235,225,244,225,235,225,+    238, 97,129, 48,224,130, 23,232,225,236,230,247,233,228,244,104,+    128,255,145,108,  2,130, 41,130, 50,243,241,245,225,242,101,128,+     51,149,244,233,240,236,121,128,  0,215,237,243,241,245,225,242,+    101,128, 51,155,238,225,104,  2,130, 76,130, 85,232,229,226,242,+    229,119,128,  5,163,236,229,230,244,232,229,226,242,229,119,128,+      5,163,115,  2,130,104,130,153,233, 99,  3,130,113,130,130,130,+    141,225,236,238,239,244,101,129, 38,106,130,124,228,226,108,128,+     38,107,230,236,225,244,243,233,231,110,128, 38,109,243,232,225,+    242,240,243,233,231,110,128, 38,111,243,241,245,225,242,101,128,+     51,178,246,243,241,245,225,242,101,128, 51,182,247,243,241,245,+    225,242,101,128, 51,188,118,  2,130,188,130,201,237,229,231,225,+    243,241,245,225,242,101,128, 51,185,243,241,245,225,242,101,128,+     51,183,119,  2,130,216,130,229,237,229,231,225,243,241,245,225,+    242,101,128, 51,191,243,241,245,225,242,101,128, 51,189,110,150,+      0,110,131, 30,131,164,131,188,131,254,132, 23,132, 81,132, 91,+    132,158,132,201,134,235,134,253,135, 22,135, 53,135, 79,135,144,+    137,126,137,134,137,159,137,167,138,135,138,145,138,155, 97,  8,+    131, 48,131, 68,131, 75,131, 82,131,107,131,118,131,143,131,155,+     98,  2,131, 54,131, 63,229,238,231,225,236,105,128,  9,168,236,+     97,128, 34,  7,227,245,244,101,128,  1, 68,228,229,246, 97,128,+      9, 40,231,117,  2,131, 89,131, 98,234,225,242,225,244,105,128,+     10,168,242,237,245,235,232,105,128, 10, 40,232,233,242,225,231,+    225,238, 97,128, 48,106,235,225,244,225,235,225,238, 97,129, 48,+    202,131,131,232,225,236,230,247,233,228,244,104,128,255,133,240,+    239,243,244,242,239,240,232,101,128,  1, 73,243,241,245,225,242,+    101,128, 51,129, 98,  2,131,170,131,180,239,240,239,237,239,230,+    111,128, 49, 11,243,240,225,227,101,128,  0,160, 99,  4,131,198,+    131,205,131,214,131,241,225,242,239,110,128,  1, 72,229,228,233,+    236,236, 97,128,  1, 70,233,242, 99,  2,131,222,131,227,236,101,+    128, 36,221,245,237,230,236,229,248,226,229,236,239,119,128, 30,+     75,239,237,237,225,225,227,227,229,238,116,128,  1, 70,228,239,+    116,  2,132,  6,132, 15,225,227,227,229,238,116,128, 30, 69,226,+    229,236,239,119,128, 30, 71,101,  3,132, 31,132, 42,132, 67,232,+    233,242,225,231,225,238, 97,128, 48,109,235,225,244,225,235,225,+    238, 97,129, 48,205,132, 55,232,225,236,230,247,233,228,244,104,+    128,255,136,247,243,232,229,241,229,236,243,233,231,110,128, 32,+    170,230,243,241,245,225,242,101,128, 51,139,103,  2,132, 97,132,+    147, 97,  3,132,105,132,115,132,122,226,229,238,231,225,236,105,+    128,  9,153,228,229,246, 97,128,  9, 25,231,117,  2,132,129,132,+    138,234,225,242,225,244,105,128, 10,153,242,237,245,235,232,105,+    128, 10, 25,239,238,231,245,244,232,225,105,128, 14,  7,104,  2,+    132,164,132,174,233,242,225,231,225,238, 97,128, 48,147,239,239,+    107,  2,132,182,132,189,236,229,230,116,128,  2,114,242,229,244,+    242,239,230,236,229,120,128,  2,115,105,  4,132,211,133,124,133,+    135,133,193,229,245,110,  7,132,229,133,  8,133, 40,133, 54,133,+     63,133, 96,133,109, 97,  2,132,235,132,250,227,233,242,227,236,+    229,235,239,242,229,225,110,128, 50,111,240,225,242,229,238,235,+    239,242,229,225,110,128, 50, 15,227,105,  2,133, 15,133, 27,229,+    245,227,235,239,242,229,225,110,128, 49, 53,242,227,236,229,235,+    239,242,229,225,110,128, 50, 97,232,233,229,245,232,235,239,242,+    229,225,110,128, 49, 54,235,239,242,229,225,110,128, 49, 52,240,+     97,  2,133, 70,133, 84,238,243,233,239,243,235,239,242,229,225,+    110,128, 49,104,242,229,238,235,239,242,229,225,110,128, 50,  1,+    243,233,239,243,235,239,242,229,225,110,128, 49,103,244,233,235,+    229,245,244,235,239,242,229,225,110,128, 49,102,232,233,242,225,+    231,225,238, 97,128, 48,107,107,  2,133,141,133,165,225,244,225,+    235,225,238, 97,129, 48,203,133,153,232,225,236,230,247,233,228,+    244,104,128,255,134,232,225,232,233,116,  2,133,175,133,186,236,+    229,230,244,244,232,225,105,128,248,153,244,232,225,105,128, 14,+     77,238,101,141,  0, 57,133,224,133,233,133,243,134, 17,134, 24,+    134, 49,134, 76,134,110,134,122,134,133,134,166,134,174,134,185,+    225,242,225,226,233, 99,128,  6,105,226,229,238,231,225,236,105,+    128,  9,239,227,233,242,227,236,101,129, 36,104,133,254,233,238,+    246,229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39,+    146,228,229,246, 97,128,  9,111,231,117,  2,134, 31,134, 40,234,+    225,242,225,244,105,128, 10,239,242,237,245,235,232,105,128, 10,+    111,232, 97,  2,134, 56,134, 67,227,235,225,242,225,226,233, 99,+    128,  6,105,238,231,250,232,239,117,128, 48, 41,105,  2,134, 82,+    134,100,228,229,239,231,242,225,240,232,233,227,240,225,242,229,+    110,128, 50, 40,238,230,229,242,233,239,114,128, 32,137,237,239,+    238,239,243,240,225,227,101,128,255, 25,239,236,228,243,244,249,+    236,101,128,247, 57,112,  2,134,139,134,146,225,242,229,110,128,+     36,124,229,114,  2,134,153,134,159,233,239,100,128, 36,144,243,+    233,225,110,128,  6,249,242,239,237,225,110,128, 33,120,243,245,+    240,229,242,233,239,114,128, 32,121,116,  2,134,191,134,229,229,+    229,110,  2,134,199,134,208,227,233,242,227,236,101,128, 36,114,+    112,  2,134,214,134,221,225,242,229,110,128, 36,134,229,242,233,+    239,100,128, 36,154,232,225,105,128, 14, 89,106,129,  1,204,134,+    241,229,227,249,242,233,236,236,233, 99,128,  4, 90,235,225,244,+    225,235,225,238, 97,129, 48,243,135, 10,232,225,236,230,247,233,+    228,244,104,128,255,157,108,  2,135, 28,135, 42,229,231,242,233,+    231,232,244,236,239,238,103,128,  1,158,233,238,229,226,229,236,+    239,119,128, 30, 73,109,  2,135, 59,135, 70,239,238,239,243,240,+    225,227,101,128,255, 78,243,241,245,225,242,101,128, 51,154,110,+      2,135, 85,135,135, 97,  3,135, 93,135,103,135,110,226,229,238,+    231,225,236,105,128,  9,163,228,229,246, 97,128,  9, 35,231,117,+      2,135,117,135,126,234,225,242,225,244,105,128, 10,163,242,237,+    245,235,232,105,128, 10, 35,238,225,228,229,246, 97,128,  9, 41,+    111,  6,135,158,135,169,135,194,135,235,136,187,137,114,232,233,+    242,225,231,225,238, 97,128, 48,110,235,225,244,225,235,225,238,+     97,129, 48,206,135,182,232,225,236,230,247,233,228,244,104,128,+    255,137,110,  3,135,202,135,218,135,227,226,242,229,225,235,233,+    238,231,243,240,225,227,101,128,  0,160,229,238,244,232,225,105,+    128, 14, 19,245,244,232,225,105,128, 14, 25,239,110,  7,135,252,+    136,  5,136, 19,136, 53,136, 69,136,110,136,169,225,242,225,226,+    233, 99,128,  6, 70,230,233,238,225,236,225,242,225,226,233, 99,+    128,254,230,231,232,245,238,238, 97,  2,136, 30,136, 39,225,242,+    225,226,233, 99,128,  6,186,230,233,238,225,236,225,242,225,226,+    233, 99,128,251,159,233,238,233,244,233,225,236,225,242,225,226,+    233, 99,128,254,231,234,229,229,237,105,  2,136, 79,136, 94,238,+    233,244,233,225,236,225,242,225,226,233, 99,128,252,210,243,239,+    236,225,244,229,228,225,242,225,226,233, 99,128,252, 75,237,101,+      2,136,117,136,130,228,233,225,236,225,242,225,226,233, 99,128,+    254,232,229,237,105,  2,136,138,136,153,238,233,244,233,225,236,+    225,242,225,226,233, 99,128,252,213,243,239,236,225,244,229,228,+    225,242,225,226,233, 99,128,252, 78,238,239,239,238,230,233,238,+    225,236,225,242,225,226,233, 99,128,252,141,116,  7,136,203,136,+    214,136,243,137, 22,137, 34,137, 54,137, 80,227,239,238,244,225,+    233,238,115,128, 34, 12,101,  2,136,220,136,236,236,229,237,229,+    238,116,129, 34,  9,136,231,239,102,128, 34,  9,241,245,225,108,+    128, 34, 96,231,242,229,225,244,229,114,129, 34,111,136,255,238,+    239,114,  2,137,  7,137, 15,229,241,245,225,108,128, 34,113,236,+    229,243,115,128, 34,121,233,228,229,238,244,233,227,225,108,128,+     34, 98,236,229,243,115,129, 34,110,137, 43,238,239,242,229,241,+    245,225,108,128, 34,112,112,  2,137, 60,137, 70,225,242,225,236,+    236,229,108,128, 34, 38,242,229,227,229,228,229,115,128, 34,128,+    243,117,  3,137, 89,137, 96,137,105,226,243,229,116,128, 34,132,+    227,227,229,229,228,115,128, 34,129,240,229,242,243,229,116,128,+     34,133,247,225,242,237,229,238,233,225,110,128,  5,118,240,225,+    242,229,110,128, 36,169,115,  2,137,140,137,149,243,241,245,225,+    242,101,128, 51,177,245,240,229,242,233,239,114,128, 32,127,244,+    233,236,228,101,128,  0,241,117,132,  3,189,137,179,137,190,138,+     15,138, 98,232,233,242,225,231,225,238, 97,128, 48,108,107,  2,+    137,196,137,220,225,244,225,235,225,238, 97,129, 48,204,137,208,+    232,225,236,230,247,233,228,244,104,128,255,135,244, 97,  3,137,+    229,137,239,137,246,226,229,238,231,225,236,105,128,  9,188,228,+    229,246, 97,128,  9, 60,231,117,  2,137,253,138,  6,234,225,242,+    225,244,105,128, 10,188,242,237,245,235,232,105,128, 10, 60,109,+      2,138, 21,138, 55,226,229,242,243,233,231,110,130,  0, 35,138,+     35,138, 47,237,239,238,239,243,240,225,227,101,128,255,  3,243,+    237,225,236,108,128,254, 95,229,114,  2,138, 62,138, 94,225,236,+    243,233,231,110,  2,138, 73,138, 81,231,242,229,229,107,128,  3,+    116,236,239,247,229,242,231,242,229,229,107,128,  3,117,111,128,+     33, 22,110,130,  5,224,138,106,138,126,228,225,231,229,243,104,+    129,251, 64,138,117,232,229,226,242,229,119,128,251, 64,232,229,+    226,242,229,119,128,  5,224,246,243,241,245,225,242,101,128, 51,+    181,247,243,241,245,225,242,101,128, 51,187,249, 97,  3,138,164,+    138,174,138,181,226,229,238,231,225,236,105,128,  9,158,228,229,+    246, 97,128,  9, 30,231,117,  2,138,188,138,197,234,225,242,225,+    244,105,128, 10,158,242,237,245,235,232,105,128, 10, 30,111,147,+      0,111,138,248,139, 14,139, 92,140,  6,140, 78,140, 93,140,133,+    141,  0,141, 21,141, 59,141, 70,141,248,143, 82,143,146,143,179,+    143,225,144, 98,144,145,144,157, 97,  2,138,254,139,  5,227,245,+    244,101,128,  0,243,238,231,244,232,225,105,128, 14, 45, 98,  4,+    139, 24,139, 66,139, 75,139, 85,225,242,242,229,100,130,  2,117,+    139, 36,139, 47,227,249,242,233,236,236,233, 99,128,  4,233,228,+    233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128,+      4,235,229,238,231,225,236,105,128,  9,147,239,240,239,237,239,+    230,111,128, 49, 27,242,229,246,101,128,  1, 79, 99,  3,139,100,+    139,173,139,252, 97,  2,139,106,139,167,238,228,242, 97,  3,139,+    117,139,124,139,135,228,229,246, 97,128,  9, 17,231,245,234,225,+    242,225,244,105,128, 10,145,246,239,247,229,236,243,233,231,110,+      2,139,149,139,156,228,229,246, 97,128,  9, 73,231,245,234,225,+    242,225,244,105,128, 10,201,242,239,110,128,  1,210,233,242, 99,+      2,139,181,139,186,236,101,128, 36,222,245,237,230,236,229,120,+    133,  0,244,139,205,139,213,139,224,139,232,139,244,225,227,245,+    244,101,128, 30,209,228,239,244,226,229,236,239,119,128, 30,217,+    231,242,225,246,101,128, 30,211,232,239,239,235,225,226,239,246,+    101,128, 30,213,244,233,236,228,101,128, 30,215,249,242,233,236,+    236,233, 99,128,  4, 62,100,  4,140, 16,140, 39,140, 45,140, 68,+    226,108,  2,140, 23,140, 31,225,227,245,244,101,128,  1, 81,231,+    242,225,246,101,128,  2, 13,229,246, 97,128,  9, 19,233,229,242,+    229,243,233,115,129,  0,246,140, 57,227,249,242,233,236,236,233,+     99,128,  4,231,239,244,226,229,236,239,119,128, 30,205,101,129,+      1, 83,140, 84,235,239,242,229,225,110,128, 49, 90,103,  3,140,+    101,140,116,140,123,239,238,229,107,129,  2,219,140,110,227,237,+     98,128,  3, 40,242,225,246,101,128,  0,242,245,234,225,242,225,+    244,105,128, 10,147,104,  4,140,143,140,154,140,164,140,242,225,+    242,237,229,238,233,225,110,128,  5,133,233,242,225,231,225,238,+     97,128, 48, 74,111,  2,140,170,140,180,239,235,225,226,239,246,+    101,128, 30,207,242,110,133,  1,161,140,195,140,203,140,214,140,+    222,140,234,225,227,245,244,101,128, 30,219,228,239,244,226,229,+    236,239,119,128, 30,227,231,242,225,246,101,128, 30,221,232,239,+    239,235,225,226,239,246,101,128, 30,223,244,233,236,228,101,128,+     30,225,245,238,231,225,242,245,237,236,225,245,116,128,  1, 81,+    105,129,  1,163,141,  6,238,246,229,242,244,229,228,226,242,229,+    246,101,128,  2, 15,107,  2,141, 27,141, 51,225,244,225,235,225,+    238, 97,129, 48,170,141, 39,232,225,236,230,247,233,228,244,104,+    128,255,117,239,242,229,225,110,128, 49, 87,236,229,232,229,226,+    242,229,119,128,  5,171,109,  6,141, 84,141,112,141,119,141,208,+    141,219,141,237,225,227,242,239,110,130,  1, 77,141, 96,141,104,+    225,227,245,244,101,128, 30, 83,231,242,225,246,101,128, 30, 81,+    228,229,246, 97,128,  9, 80,229,231, 97,133,  3,201,141,135,141,+    139,141,150,141,164,141,180, 49,128,  3,214,227,249,242,233,236,+    236,233, 99,128,  4, 97,236,225,244,233,238,227,236,239,243,229,+    100,128,  2,119,242,239,245,238,228,227,249,242,233,236,236,233,+     99,128,  4,123,116,  2,141,186,141,201,233,244,236,239,227,249,+    242,233,236,236,233, 99,128,  4,125,239,238,239,115,128,  3,206,+    231,245,234,225,242,225,244,105,128, 10,208,233,227,242,239,110,+    129,  3,191,141,229,244,239,238,239,115,128,  3,204,239,238,239,+    243,240,225,227,101,128,255, 79,238,101,145,  0, 49,142, 31,142,+     40,142, 50,142, 80,142,105,142,114,142,123,142,148,142,182,142,+    216,142,228,142,247,143,  2,143, 35,143, 45,143, 53,143, 64,225,+    242,225,226,233, 99,128,  6, 97,226,229,238,231,225,236,105,128,+      9,231,227,233,242,227,236,101,129, 36, 96,142, 61,233,238,246,+    229,242,243,229,243,225,238,243,243,229,242,233,102,128, 39,138,+    100,  2,142, 86,142, 92,229,246, 97,128,  9,103,239,244,229,238,+    236,229,225,228,229,114,128, 32, 36,229,233,231,232,244,104,128,+     33, 91,230,233,244,244,229,100,128,246,220,231,117,  2,142,130,+    142,139,234,225,242,225,244,105,128, 10,231,242,237,245,235,232,+    105,128, 10,103,232, 97,  3,142,157,142,168,142,173,227,235,225,+    242,225,226,233, 99,128,  6, 97,236,102,128,  0,189,238,231,250,+    232,239,117,128, 48, 33,105,  2,142,188,142,206,228,229,239,231,+    242,225,240,232,233,227,240,225,242,229,110,128, 50, 32,238,230,+    229,242,233,239,114,128, 32,129,237,239,238,239,243,240,225,227,+    101,128,255, 17,238,245,237,229,242,225,244,239,242,226,229,238,+    231,225,236,105,128,  9,244,239,236,228,243,244,249,236,101,128,+    247, 49,112,  2,143,  8,143, 15,225,242,229,110,128, 36,116,229,+    114,  2,143, 22,143, 28,233,239,100,128, 36,136,243,233,225,110,+    128,  6,241,241,245,225,242,244,229,114,128,  0,188,242,239,237,+    225,110,128, 33,112,243,245,240,229,242,233,239,114,128,  0,185,+    244,104,  2,143, 71,143, 76,225,105,128, 14, 81,233,242,100,128,+     33, 83,111,  3,143, 90,143,124,143,140,103,  2,143, 96,143,114,+    239,238,229,107,129,  1,235,143,105,237,225,227,242,239,110,128,+      1,237,245,242,237,245,235,232,105,128, 10, 19,237,225,244,242,+    225,231,245,242,237,245,235,232,105,128, 10, 75,240,229,110,128,+      2, 84,112,  3,143,154,143,161,143,172,225,242,229,110,128, 36,+    170,229,238,226,245,236,236,229,116,128, 37,230,244,233,239,110,+    128, 35, 37,114,  2,143,185,143,214,100,  2,143,191,143,202,230,+    229,237,233,238,233,238,101,128,  0,170,237,225,243,227,245,236,+    233,238,101,128,  0,186,244,232,239,231,239,238,225,108,128, 34,+     31,115,  5,143,237,144, 13,144, 30,144, 75,144, 88,232,239,242,+    116,  2,143,246,143,253,228,229,246, 97,128,  9, 18,246,239,247,+    229,236,243,233,231,238,228,229,246, 97,128,  9, 74,236,225,243,+    104,129,  0,248,144, 22,225,227,245,244,101,128,  1,255,237,225,+    236,108,  2,144, 39,144, 50,232,233,242,225,231,225,238, 97,128,+     48, 73,235,225,244,225,235,225,238, 97,129, 48,169,144, 63,232,+    225,236,230,247,233,228,244,104,128,255,107,244,242,239,235,229,+    225,227,245,244,101,128,  1,255,245,240,229,242,233,239,114,128,+    246,240,116,  2,144,104,144,115,227,249,242,233,236,236,233, 99,+    128,  4,127,233,236,228,101,130,  0,245,144,126,144,134,225,227,+    245,244,101,128, 30, 77,228,233,229,242,229,243,233,115,128, 30,+     79,245,226,239,240,239,237,239,230,111,128, 49, 33,118,  2,144,+    163,144,244,229,114,  2,144,170,144,236,236,233,238,101,131, 32,+     62,144,183,144,206,144,229, 99,  2,144,189,144,201,229,238,244,+    229,242,236,233,238,101,128,254, 74,237, 98,128,  3,  5,100,  2,+    144,212,144,220,225,243,232,229,100,128,254, 73,226,236,247,225,+    246,121,128,254, 76,247,225,246,121,128,254, 75,243,227,239,242,+    101,128,  0,175,239,247,229,236,243,233,231,110,  3,145,  3,145,+     13,145, 20,226,229,238,231,225,236,105,128,  9,203,228,229,246,+     97,128,  9, 75,231,245,234,225,242,225,244,105,128, 10,203,112,+    145,  0,112,145, 69,147,197,147,208,147,217,147,229,149,154,149,+    164,150,156,151,175,152,  9,152, 35,152,166,152,174,153, 76,153,+    134,153,162,153,172, 97, 14,145, 99,145,131,145,141,145,148,145,+    155,145,203,145,214,145,228,145,239,146, 30,146, 44,147, 56,147,+     95,147,185, 97,  2,145,105,145,117,237,240,243,243,241,245,225,+    242,101,128, 51,128,243,229,238,244,239,243,241,245,225,242,101,+    128, 51, 43,226,229,238,231,225,236,105,128,  9,170,227,245,244,+    101,128, 30, 85,228,229,246, 97,128,  9, 42,103,  2,145,161,145,+    179,101,  2,145,167,145,174,228,239,247,110,128, 33,223,245,112,+    128, 33,222,117,  2,145,185,145,194,234,225,242,225,244,105,128,+     10,170,242,237,245,235,232,105,128, 10, 42,232,233,242,225,231,+    225,238, 97,128, 48,113,233,249,225,238,238,239,233,244,232,225,+    105,128, 14, 47,235,225,244,225,235,225,238, 97,128, 48,209,108,+      2,145,245,146, 14,225,244,225,236,233,250,225,244,233,239,238,+    227,249,242,233,236,236,233,227,227,237, 98,128,  4,132,239,227,+    232,235,225,227,249,242,233,236,236,233, 99,128,  4,192,238,243,+    233,239,243,235,239,242,229,225,110,128, 49,127,114,  3,146, 52,+    146, 73,147, 45, 97,  2,146, 58,146, 66,231,242,225,240,104,128,+      0,182,236,236,229,108,128, 34, 37,229,110,  2,146, 80,146,190,+    236,229,230,116,136,  0, 40,146,103,146,118,146,123,146,128,146,+    139,146,151,146,174,146,179,225,236,244,239,238,229,225,242,225,+    226,233, 99,128,253, 62,226,116,128,248,237,229,120,128,248,236,+    233,238,230,229,242,233,239,114,128, 32,141,237,239,238,239,243,+    240,225,227,101,128,255,  8,115,  2,146,157,146,164,237,225,236,+    108,128,254, 89,245,240,229,242,233,239,114,128, 32,125,244,112,+    128,248,235,246,229,242,244,233,227,225,108,128,254, 53,242,233,+    231,232,116,136,  0, 41,146,214,146,229,146,234,146,239,146,250,+    147,  6,147, 29,147, 34,225,236,244,239,238,229,225,242,225,226,+    233, 99,128,253, 63,226,116,128,248,248,229,120,128,248,247,233,+    238,230,229,242,233,239,114,128, 32,142,237,239,238,239,243,240,+    225,227,101,128,255,  9,115,  2,147, 12,147, 19,237,225,236,108,+    128,254, 90,245,240,229,242,233,239,114,128, 32,126,244,112,128,+    248,246,246,229,242,244,233,227,225,108,128,254, 54,244,233,225,+    236,228,233,230,102,128, 34,  2,115,  3,147, 64,147, 75,147, 87,+    229,241,232,229,226,242,229,119,128,  5,192,232,244,225,232,229,+    226,242,229,119,128,  5,153,241,245,225,242,101,128, 51,169,244,+    225,104,134,  5,183,147,113,147,127,147,132,147,141,147,156,147,+    172, 49,  2,147,119,147,123, 49,128,  5,183,100,128,  5,183,178,+     97,128,  5,183,232,229,226,242,229,119,128,  5,183,238,225,242,+    242,239,247,232,229,226,242,229,119,128,  5,183,241,245,225,242,+    244,229,242,232,229,226,242,229,119,128,  5,183,247,233,228,229,+    232,229,226,242,229,119,128,  5,183,250,229,242,232,229,226,242,+    229,119,128,  5,161,226,239,240,239,237,239,230,111,128, 49,  6,+    227,233,242,227,236,101,128, 36,223,228,239,244,225,227,227,229,+    238,116,128, 30, 87,101,137,  5,228,147,251,148,  6,148, 26,148,+     38,148, 58,148,160,148,171,148,192,149,147,227,249,242,233,236,+    236,233, 99,128,  4, 63,228,225,231,229,243,104,129,251, 68,148,+     17,232,229,226,242,229,119,128,251, 68,229,250,233,243,241,245,+    225,242,101,128, 51, 59,230,233,238,225,236,228,225,231,229,243,+    232,232,229,226,242,229,119,128,251, 67,104,  5,148, 70,148, 93,+    148,101,148,115,148,145,225,114,  2,148, 77,148, 84,225,226,233,+     99,128,  6,126,237,229,238,233,225,110,128,  5,122,229,226,242,+    229,119,128,  5,228,230,233,238,225,236,225,242,225,226,233, 99,+    128,251, 87,105,  2,148,121,148,136,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,251, 88,242,225,231,225,238, 97,128, 48,+    122,237,229,228,233,225,236,225,242,225,226,233, 99,128,251, 89,+    235,225,244,225,235,225,238, 97,128, 48,218,237,233,228,228,236,+    229,232,239,239,235,227,249,242,233,236,236,233, 99,128,  4,167,+    114,  5,148,204,148,216,149,  2,149,123,149,136,225,230,229,232,+    229,226,242,229,119,128,251, 78,227,229,238,116,131,  0, 37,148,+    229,148,238,148,250,225,242,225,226,233, 99,128,  6,106,237,239,+    238,239,243,240,225,227,101,128,255,  5,243,237,225,236,108,128,+    254,106,105,  2,149,  8,149,105,239,100,134,  0, 46,149, 25,149,+     36,149, 47,149, 59,149, 70,149, 82,225,242,237,229,238,233,225,+    110,128,  5,137,227,229,238,244,229,242,229,100,128,  0,183,232,+    225,236,230,247,233,228,244,104,128,255, 97,233,238,230,229,242,+    233,239,114,128,246,231,237,239,238,239,243,240,225,227,101,128,+    255, 14,115,  2,149, 88,149, 95,237,225,236,108,128,254, 82,245,+    240,229,242,233,239,114,128,246,232,243,240,239,237,229,238,233,+    231,242,229,229,235,227,237, 98,128,  3, 66,240,229,238,228,233,+    227,245,236,225,114,128, 34,165,244,232,239,245,243,225,238,100,+    128, 32, 48,243,229,244, 97,128, 32,167,230,243,241,245,225,242,+    101,128, 51,138,104,  3,149,172,149,222,150,103, 97,  3,149,180,+    149,190,149,197,226,229,238,231,225,236,105,128,  9,171,228,229,+    246, 97,128,  9, 43,231,117,  2,149,204,149,213,234,225,242,225,+    244,105,128, 10,171,242,237,245,235,232,105,128, 10, 43,105,133,+      3,198,149,236,149,240,150, 70,150, 78,150, 89, 49,128,  3,213,+    229,245,240,104,  4,149,253,150, 32,150, 47,150, 56, 97,  2,150,+      3,150, 18,227,233,242,227,236,229,235,239,242,229,225,110,128,+     50,122,240,225,242,229,238,235,239,242,229,225,110,128, 50, 26,+    227,233,242,227,236,229,235,239,242,229,225,110,128, 50,108,235,+    239,242,229,225,110,128, 49, 77,240,225,242,229,238,235,239,242,+    229,225,110,128, 50, 12,236,225,244,233,110,128,  2,120,238,244,+    232,245,244,232,225,105,128, 14, 58,243,249,237,226,239,236,231,+    242,229,229,107,128,  3,213,111,  3,150,111,150,116,150,142,239,+    107,128,  1,165,240,104,  2,150,123,150,132,225,238,244,232,225,+    105,128, 14, 30,245,238,231,244,232,225,105,128, 14, 28,243,225,+    237,240,232,225,239,244,232,225,105,128, 14, 32,105,133,  3,192,+    150,170,151,126,151,137,151,148,151,162,229,245,112,  6,150,186,+    150,221,150,253,151, 25,151, 39,151, 91, 97,  2,150,192,150,207,+    227,233,242,227,236,229,235,239,242,229,225,110,128, 50,115,240,+    225,242,229,238,235,239,242,229,225,110,128, 50, 19,227,105,  2,+    150,228,150,240,229,245,227,235,239,242,229,225,110,128, 49,118,+    242,227,236,229,235,239,242,229,225,110,128, 50,101,107,  2,151,+      3,151, 17,233,249,229,239,235,235,239,242,229,225,110,128, 49,+    114,239,242,229,225,110,128, 49, 66,240,225,242,229,238,235,239,+    242,229,225,110,128, 50,  5,243,233,239,115,  2,151, 48,151, 76,+    107,  2,151, 54,151, 68,233,249,229,239,235,235,239,242,229,225,+    110,128, 49,116,239,242,229,225,110,128, 49, 68,244,233,235,229,+    245,244,235,239,242,229,225,110,128, 49,117,116,  2,151, 97,151,+    112,232,233,229,245,244,232,235,239,242,229,225,110,128, 49,119,+    233,235,229,245,244,235,239,242,229,225,110,128, 49,115,232,233,+    242,225,231,225,238, 97,128, 48,116,235,225,244,225,235,225,238,+     97,128, 48,212,243,249,237,226,239,236,231,242,229,229,107,128,+      3,214,247,242,225,242,237,229,238,233,225,110,128,  5,131,236,+    245,115,132,  0, 43,151,189,151,200,151,209,151,242,226,229,236,+    239,247,227,237, 98,128,  3, 31,227,233,242,227,236,101,128, 34,+    149,109,  2,151,215,151,222,233,238,245,115,128,  0,177,111,  2,+    151,228,151,232,100,128,  2,214,238,239,243,240,225,227,101,128,+    255, 11,115,  2,151,248,151,255,237,225,236,108,128,254, 98,245,+    240,229,242,233,239,114,128, 32,122,109,  2,152, 15,152, 26,239,+    238,239,243,240,225,227,101,128,255, 80,243,241,245,225,242,101,+    128, 51,216,111,  5,152, 47,152, 58,152,125,152,136,152,146,232,+    233,242,225,231,225,238, 97,128, 48,125,233,238,244,233,238,231,+    233,238,228,229,120,  4,152, 78,152, 90,152,102,152,115,228,239,+    247,238,247,232,233,244,101,128, 38, 31,236,229,230,244,247,232,+    233,244,101,128, 38, 28,242,233,231,232,244,247,232,233,244,101,+    128, 38, 30,245,240,247,232,233,244,101,128, 38, 29,235,225,244,+    225,235,225,238, 97,128, 48,221,240,236,225,244,232,225,105,128,+     14, 27,243,244,225,236,237,225,242,107,129, 48, 18,152,159,230,+    225,227,101,128, 48, 32,240,225,242,229,110,128, 36,171,114,  3,+    152,182,152,208,152,233,101,  2,152,188,152,196,227,229,228,229,+    115,128, 34,122,243,227,242,233,240,244,233,239,110,128, 33, 30,+    233,237,101,  2,152,216,152,222,237,239,100,128,  2,185,242,229,+    246,229,242,243,229,100,128, 32, 53,111,  4,152,243,152,250,153,+      4,153, 17,228,245,227,116,128, 34, 15,234,229,227,244,233,246,+    101,128, 35,  5,236,239,238,231,229,228,235,225,238, 97,128, 48,+    252,112,  2,153, 23,153, 60,101,  2,153, 29,153, 36,236,236,239,+    114,128, 35, 24,242,243,117,  2,153, 44,153, 51,226,243,229,116,+    128, 34,130,240,229,242,243,229,116,128, 34,131,239,242,244,233,+    239,110,129, 34, 55,153, 71,225,108,128, 34, 29,115,  2,153, 82,+    153,125,105,130,  3,200,153, 90,153,101,227,249,242,233,236,236,+    233, 99,128,  4,113,236,233,240,238,229,245,237,225,244,225,227,+    249,242,233,236,236,233,227,227,237, 98,128,  4,134,243,241,245,+    225,242,101,128, 51,176,117,  2,153,140,153,151,232,233,242,225,+    231,225,238, 97,128, 48,119,235,225,244,225,235,225,238, 97,128,+     48,215,246,243,241,245,225,242,101,128, 51,180,247,243,241,245,+    225,242,101,128, 51,186,113,136,  0,113,153,202,154,251,155,  6,+    155, 15,155, 22,155, 34,155, 72,155, 80, 97,  4,153,212,153,235,+    154, 43,154,234,100,  2,153,218,153,224,229,246, 97,128,  9, 88,+    237,225,232,229,226,242,229,119,128,  5,168,102,  4,153,245,153,+    254,154, 12,154, 28,225,242,225,226,233, 99,128,  6, 66,230,233,+    238,225,236,225,242,225,226,233, 99,128,254,214,233,238,233,244,+    233,225,236,225,242,225,226,233, 99,128,254,215,237,229,228,233,+    225,236,225,242,225,226,233, 99,128,254,216,237,225,244,115,136,+      5,184,154, 66,154, 86,154,100,154,105,154,110,154,119,154,134,+    154,221, 49,  3,154, 74,154, 78,154, 82, 48,128,  5,184, 97,128,+      5,184, 99,128,  5,184, 50,  2,154, 92,154, 96, 55,128,  5,184,+     57,128,  5,184,179, 51,128,  5,184,228,101,128,  5,184,232,229,+    226,242,229,119,128,  5,184,238,225,242,242,239,247,232,229,226,+    242,229,119,128,  5,184,113,  2,154,140,154,206,225,244,225,110,+      4,154,153,154,162,154,177,154,193,232,229,226,242,229,119,128,+      5,184,238,225,242,242,239,247,232,229,226,242,229,119,128,  5,+    184,241,245,225,242,244,229,242,232,229,226,242,229,119,128,  5,+    184,247,233,228,229,232,229,226,242,229,119,128,  5,184,245,225,+    242,244,229,242,232,229,226,242,229,119,128,  5,184,247,233,228,+    229,232,229,226,242,229,119,128,  5,184,242,238,229,249,240,225,+    242,225,232,229,226,242,229,119,128,  5,159,226,239,240,239,237,+    239,230,111,128, 49, 17,227,233,242,227,236,101,128, 36,224,232,+    239,239,107,128,  2,160,237,239,238,239,243,240,225,227,101,128,+    255, 81,239,102,130,  5,231,155, 43,155, 63,228,225,231,229,243,+    104,129,251, 71,155, 54,232,229,226,242,229,119,128,251, 71,232,+    229,226,242,229,119,128,  5,231,240,225,242,229,110,128, 36,172,+    117,  4,155, 90,155,102,155,191,156, 22,225,242,244,229,242,238,+    239,244,101,128, 38,105,226,245,244,115,135,  5,187,155,123,155,+    128,155,133,155,138,155,147,155,162,155,178,177, 56,128,  5,187,+    178, 53,128,  5,187,179, 49,128,  5,187,232,229,226,242,229,119,+    128,  5,187,238,225,242,242,239,247,232,229,226,242,229,119,128,+      5,187,241,245,225,242,244,229,242,232,229,226,242,229,119,128,+      5,187,247,233,228,229,232,229,226,242,229,119,128,  5,187,229,+    243,244,233,239,110,133,  0, 63,155,210,155,233,155,250,156,  2,+    156, 14,225,114,  2,155,217,155,224,225,226,233, 99,128,  6, 31,+    237,229,238,233,225,110,128,  5, 94,228,239,247,110,129,  0,191,+    155,242,243,237,225,236,108,128,247,191,231,242,229,229,107,128,+      3,126,237,239,238,239,243,240,225,227,101,128,255, 31,243,237,+    225,236,108,128,247, 63,239,244,101,  4,156, 34,156,105,156,125,+    156,154,228,226,108,133,  0, 34,156, 50,156, 57,156, 64,156, 76,+    156, 97,226,225,243,101,128, 32, 30,236,229,230,116,128, 32, 28,+    237,239,238,239,243,240,225,227,101,128,255,  2,240,242,233,237,+    101,129, 48, 30,156, 86,242,229,246,229,242,243,229,100,128, 48,+     29,242,233,231,232,116,128, 32, 29,236,229,230,116,129, 32, 24,+    156,114,242,229,246,229,242,243,229,100,128, 32, 27,114,  2,156,+    131,156,141,229,246,229,242,243,229,100,128, 32, 27,233,231,232,+    116,129, 32, 25,156,150,110,128,  1, 73,243,233,238,231,108,  2,+    156,164,156,171,226,225,243,101,128, 32, 26,101,129,  0, 39,156,+    177,237,239,238,239,243,240,225,227,101,128,255,  7,114,145,  0,+    114,156,227,157,231,157,242,158, 33,158, 84,159,101,159,125,159,+    220,161,254,162, 35,162, 47,162,101,162,109,163, 15,163, 26,163,+     61,163,161, 97, 11,156,251,157,  6,157, 16,157, 23,157, 88,157,+    104,157,129,157,140,157,165,157,188,157,225,225,242,237,229,238,+    233,225,110,128,  5,124,226,229,238,231,225,236,105,128,  9,176,+    227,245,244,101,128,  1, 85,100,  4,157, 33,157, 39,157, 53,157,+     79,229,246, 97,128,  9, 48,233,227,225,108,129, 34, 26,157, 48,+    229,120,128,248,229,239,246,229,242,243,243,241,245,225,242,101,+    129, 51,174,157, 69,228,243,241,245,225,242,101,128, 51,175,243,+    241,245,225,242,101,128, 51,173,230,101,129,  5,191,157, 95,232,+    229,226,242,229,119,128,  5,191,231,117,  2,157,111,157,120,234,+    225,242,225,244,105,128, 10,176,242,237,245,235,232,105,128, 10,+     48,232,233,242,225,231,225,238, 97,128, 48,137,235,225,244,225,+    235,225,238, 97,129, 48,233,157,153,232,225,236,230,247,233,228,+    244,104,128,255,151,236,239,247,229,242,228,233,225,231,239,238,+    225,236,226,229,238,231,225,236,105,128,  9,241,109,  2,157,194,+    157,217,233,228,228,236,229,228,233,225,231,239,238,225,236,226,+    229,238,231,225,236,105,128,  9,240,243,232,239,242,110,128,  2,+    100,244,233,111,128, 34, 54,226,239,240,239,237,239,230,111,128,+     49, 22, 99,  4,157,252,158,  3,158, 12,158, 20,225,242,239,110,+    128,  1, 89,229,228,233,236,236, 97,128,  1, 87,233,242,227,236,+    101,128, 36,225,239,237,237,225,225,227,227,229,238,116,128,  1,+     87,100,  2,158, 39,158, 49,226,236,231,242,225,246,101,128,  2,+     17,239,116,  2,158, 56,158, 65,225,227,227,229,238,116,128, 30,+     89,226,229,236,239,119,129, 30, 91,158, 75,237,225,227,242,239,+    110,128, 30, 93,101,  6,158, 98,158,143,158,178,158,233,159,  2,+    159, 35,102,  2,158,104,158,117,229,242,229,238,227,229,237,225,+    242,107,128, 32, 59,236,229,248,243,117,  2,158,127,158,134,226,+    243,229,116,128, 34,134,240,229,242,243,229,116,128, 34,135,231,+    233,243,244,229,114,  2,158,154,158,159,229,100,128,  0,174,115,+      2,158,165,158,171,225,238,115,128,248,232,229,242,233,102,128,+    246,218,104,  3,158,186,158,209,158,223,225,114,  2,158,193,158,+    200,225,226,233, 99,128,  6, 49,237,229,238,233,225,110,128,  5,+    128,230,233,238,225,236,225,242,225,226,233, 99,128,254,174,233,+    242,225,231,225,238, 97,128, 48,140,235,225,244,225,235,225,238,+     97,129, 48,236,158,246,232,225,236,230,247,233,228,244,104,128,+    255,154,243,104,130,  5,232,159, 11,159, 26,228,225,231,229,243,+    232,232,229,226,242,229,119,128,251, 72,232,229,226,242,229,119,+    128,  5,232,118,  3,159, 43,159, 56,159, 88,229,242,243,229,228,+    244,233,236,228,101,128, 34, 61,233, 97,  2,159, 63,159, 72,232,+    229,226,242,229,119,128,  5,151,237,245,231,242,225,243,232,232,+    229,226,242,229,119,128,  5,151,236,239,231,233,227,225,236,238,+    239,116,128, 35, 16,230,233,243,232,232,239,239,107,129,  2,126,+    159,114,242,229,246,229,242,243,229,100,128,  2,127,104,  2,159,+    131,159,154, 97,  2,159,137,159,147,226,229,238,231,225,236,105,+    128,  9,221,228,229,246, 97,128,  9, 93,111,131,  3,193,159,164,+    159,193,159,207,239,107,129,  2,125,159,171,244,245,242,238,229,+    100,129,  2,123,159,182,243,245,240,229,242,233,239,114,128,  2,+    181,243,249,237,226,239,236,231,242,229,229,107,128,  3,241,244,+    233,227,232,239,239,235,237,239,100,128,  2,222,105,  6,159,234,+    161, 22,161, 68,161, 79,161,104,161,240,229,245,108,  9,160,  0,+    160, 35,160, 50,160, 64,160,110,160,124,160,210,160,223,161,  2,+     97,  2,160,  6,160, 21,227,233,242,227,236,229,235,239,242,229,+    225,110,128, 50,113,240,225,242,229,238,235,239,242,229,225,110,+    128, 50, 17,227,233,242,227,236,229,235,239,242,229,225,110,128,+     50, 99,232,233,229,245,232,235,239,242,229,225,110,128, 49, 64,+    107,  2,160, 70,160,102,233,249,229,239,107,  2,160, 80,160, 89,+    235,239,242,229,225,110,128, 49, 58,243,233,239,243,235,239,242,+    229,225,110,128, 49,105,239,242,229,225,110,128, 49, 57,237,233,+    229,245,237,235,239,242,229,225,110,128, 49, 59,112,  3,160,132,+    160,164,160,179, 97,  2,160,138,160,152,238,243,233,239,243,235,+    239,242,229,225,110,128, 49,108,242,229,238,235,239,242,229,225,+    110,128, 50,  3,232,233,229,245,240,232,235,239,242,229,225,110,+    128, 49, 63,233,229,245,112,  2,160,188,160,197,235,239,242,229,+    225,110,128, 49, 60,243,233,239,243,235,239,242,229,225,110,128,+     49,107,243,233,239,243,235,239,242,229,225,110,128, 49, 61,116,+      2,160,229,160,244,232,233,229,245,244,232,235,239,242,229,225,+    110,128, 49, 62,233,235,229,245,244,235,239,242,229,225,110,128,+     49,106,249,229,239,242,233,238,232,233,229,245,232,235,239,242,+    229,225,110,128, 49,109,231,232,116,  2,161, 30,161, 38,225,238,+    231,236,101,128, 34, 31,116,  2,161, 44,161, 58,225,227,235,226,+    229,236,239,247,227,237, 98,128,  3, 25,242,233,225,238,231,236,+    101,128, 34,191,232,233,242,225,231,225,238, 97,128, 48,138,235,+    225,244,225,235,225,238, 97,129, 48,234,161, 92,232,225,236,230,+    247,233,228,244,104,128,255,152,110,  2,161,110,161,226,103,131,+      2,218,161,120,161,131,161,137,226,229,236,239,247,227,237, 98,+    128,  3, 37,227,237, 98,128,  3, 10,232,225,236,102,  2,161,146,+    161,192,236,229,230,116,131,  2,191,161,159,161,170,161,181,225,+    242,237,229,238,233,225,110,128,  5, 89,226,229,236,239,247,227,+    237, 98,128,  3, 28,227,229,238,244,229,242,229,100,128,  2,211,+    242,233,231,232,116,130,  2,190,161,204,161,215,226,229,236,239,+    247,227,237, 98,128,  3, 57,227,229,238,244,229,242,229,100,128,+      2,210,246,229,242,244,229,228,226,242,229,246,101,128,  2, 19,+    244,244,239,242,245,243,241,245,225,242,101,128, 51, 81,108,  2,+    162,  4,162, 15,233,238,229,226,229,236,239,119,128, 30, 95,239,+    238,231,236,229,103,129,  2,124,162, 26,244,245,242,238,229,100,+    128,  2,122,237,239,238,239,243,240,225,227,101,128,255, 82,111,+      3,162, 55,162, 66,162, 91,232,233,242,225,231,225,238, 97,128,+     48,141,235,225,244,225,235,225,238, 97,129, 48,237,162, 79,232,+    225,236,230,247,233,228,244,104,128,255,155,242,245,225,244,232,+    225,105,128, 14, 35,240,225,242,229,110,128, 36,173,114,  3,162,+    117,162,153,162,183, 97,  3,162,125,162,135,162,142,226,229,238,+    231,225,236,105,128,  9,220,228,229,246, 97,128,  9, 49,231,245,+    242,237,245,235,232,105,128, 10, 92,229,104,  2,162,160,162,169,+    225,242,225,226,233, 99,128,  6,145,230,233,238,225,236,225,242,+    225,226,233, 99,128,251,141,246,239,227,225,236,233, 99,  4,162,+    199,162,209,162,216,162,227,226,229,238,231,225,236,105,128,  9,+    224,228,229,246, 97,128,  9, 96,231,245,234,225,242,225,244,105,+    128, 10,224,246,239,247,229,236,243,233,231,110,  3,162,243,162,+    253,163,  4,226,229,238,231,225,236,105,128,  9,196,228,229,246,+     97,128,  9, 68,231,245,234,225,242,225,244,105,128, 10,196,243,+    245,240,229,242,233,239,114,128,246,241,116,  2,163, 32,163, 40,+    226,236,239,227,107,128, 37,144,245,242,238,229,100,129,  2,121,+    163, 50,243,245,240,229,242,233,239,114,128,  2,180,117,  4,163,+     71,163, 82,163,107,163,154,232,233,242,225,231,225,238, 97,128,+     48,139,235,225,244,225,235,225,238, 97,129, 48,235,163, 95,232,+    225,236,230,247,233,228,244,104,128,255,153,112,  2,163,113,163,+    148,229,101,  2,163,120,163,134,237,225,242,235,226,229,238,231,+    225,236,105,128,  9,242,243,233,231,238,226,229,238,231,225,236,+    105,128,  9,243,233,225,104,128,246,221,244,232,225,105,128, 14,+     36,246,239,227,225,236,233, 99,  4,163,177,163,187,163,194,163,+    205,226,229,238,231,225,236,105,128,  9,139,228,229,246, 97,128,+      9, 11,231,245,234,225,242,225,244,105,128, 10,139,246,239,247,+    229,236,243,233,231,110,  3,163,221,163,231,163,238,226,229,238,+    231,225,236,105,128,  9,195,228,229,246, 97,128,  9, 67,231,245,+    234,225,242,225,244,105,128, 10,195,115,147,  0,115,164, 35,166,+      5,166, 16,166,142,166,181,169,123,169,134,172, 21,174,159,174,+    205,174,232,175,167,175,234,177, 11,177, 21,177,207,178, 24,178,+    194,178,204, 97,  9,164, 55,164, 65,164, 86,164,158,164,183,164,+    194,164,219,164,251,165, 35,226,229,238,231,225,236,105,128,  9,+    184,227,245,244,101,129,  1, 91,164, 74,228,239,244,225,227,227,+    229,238,116,128, 30,101,100,  5,164, 98,164,107,164,113,164,127,+    164,143,225,242,225,226,233, 99,128,  6, 53,229,246, 97,128,  9,+     56,230,233,238,225,236,225,242,225,226,233, 99,128,254,186,233,+    238,233,244,233,225,236,225,242,225,226,233, 99,128,254,187,237,+    229,228,233,225,236,225,242,225,226,233, 99,128,254,188,231,117,+      2,164,165,164,174,234,225,242,225,244,105,128, 10,184,242,237,+    245,235,232,105,128, 10, 56,232,233,242,225,231,225,238, 97,128,+     48, 85,235,225,244,225,235,225,238, 97,129, 48,181,164,207,232,+    225,236,230,247,233,228,244,104,128,255,123,236,236,225,236,236,+    225,232,239,245,225,236,225,249,232,229,247,225,243,225,236,236,+    225,237,225,242,225,226,233, 99,128,253,250,237,229,235,104,130,+      5,225,165,  6,165, 26,228,225,231,229,243,104,129,251, 65,165,+     17,232,229,226,242,229,119,128,251, 65,232,229,226,242,229,119,+    128,  5,225,242, 97,  5,165, 48,165,122,165,130,165,180,165,188,+     97,  5,165, 60,165, 68,165, 76,165,107,165,115,225,244,232,225,+    105,128, 14, 50,229,244,232,225,105,128, 14, 65,233,237,225,233,+    109,  2,165, 86,165, 97,225,236,225,233,244,232,225,105,128, 14,+     68,245,225,238,244,232,225,105,128, 14, 67,237,244,232,225,105,+    128, 14, 51,244,232,225,105,128, 14, 48,229,244,232,225,105,128,+     14, 64,105,  3,165,138,165,162,165,173,105,  2,165,144,165,155,+    236,229,230,244,244,232,225,105,128,248,134,244,232,225,105,128,+     14, 53,236,229,230,244,244,232,225,105,128,248,133,244,232,225,+    105,128, 14, 52,239,244,232,225,105,128, 14, 66,117,  3,165,196,+    165,246,165,253,101,  3,165,204,165,228,165,239,101,  2,165,210,+    165,221,236,229,230,244,244,232,225,105,128,248,136,244,232,225,+    105,128, 14, 55,236,229,230,244,244,232,225,105,128,248,135,244,+    232,225,105,128, 14, 54,244,232,225,105,128, 14, 56,245,244,232,+    225,105,128, 14, 57,226,239,240,239,237,239,230,111,128, 49, 25,+     99,  5,166, 28,166, 49,166, 58,166,107,166,129,225,242,239,110,+    129,  1, 97,166, 37,228,239,244,225,227,227,229,238,116,128, 30,+    103,229,228,233,236,236, 97,128,  1, 95,232,247, 97,131,  2, 89,+    166, 70,166, 81,166,100,227,249,242,233,236,236,233, 99,128,  4,+    217,228,233,229,242,229,243,233,243,227,249,242,233,236,236,233,+     99,128,  4,219,232,239,239,107,128,  2, 90,233,242, 99,  2,166,+    115,166,120,236,101,128, 36,226,245,237,230,236,229,120,128,  1,+     93,239,237,237,225,225,227,227,229,238,116,128,  2, 25,228,239,+    116,  2,166,150,166,159,225,227,227,229,238,116,128, 30, 97,226,+    229,236,239,119,129, 30, 99,166,169,228,239,244,225,227,227,229,+    238,116,128, 30,105,101,  9,166,201,166,217,166,252,167, 61,167,+    164,167,191,167,216,168, 41,168, 68,225,231,245,236,236,226,229,+    236,239,247,227,237, 98,128,  3, 60, 99,  2,166,223,166,245,239,+    238,100,129, 32, 51,166,231,244,239,238,229,227,232,233,238,229,+    243,101,128,  2,202,244,233,239,110,128,  0,167,229,110,  4,167,+      7,167, 16,167, 30,167, 46,225,242,225,226,233, 99,128,  6, 51,+    230,233,238,225,236,225,242,225,226,233, 99,128,254,178,233,238,+    233,244,233,225,236,225,242,225,226,233, 99,128,254,179,237,229,+    228,233,225,236,225,242,225,226,233, 99,128,254,180,231,239,108,+    135,  5,182,167, 81,167, 95,167,100,167,109,167,124,167,140,167,+    151, 49,  2,167, 87,167, 91, 51,128,  5,182,102,128,  5,182,178,+     99,128,  5,182,232,229,226,242,229,119,128,  5,182,238,225,242,+    242,239,247,232,229,226,242,229,119,128,  5,182,241,245,225,242,+    244,229,242,232,229,226,242,229,119,128,  5,182,244,225,232,229,+    226,242,229,119,128,  5,146,247,233,228,229,232,229,226,242,229,+    119,128,  5,182,104,  2,167,170,167,181,225,242,237,229,238,233,+    225,110,128,  5,125,233,242,225,231,225,238, 97,128, 48, 91,235,+    225,244,225,235,225,238, 97,129, 48,187,167,204,232,225,236,230,+    247,233,228,244,104,128,255,126,237,105,  2,167,223,168, 10,227,+    239,236,239,110,131,  0, 59,167,237,167,246,168,  2,225,242,225,+    226,233, 99,128,  6, 27,237,239,238,239,243,240,225,227,101,128,+    255, 27,243,237,225,236,108,128,254, 84,246,239,233,227,229,228,+    237,225,242,235,235,225,238, 97,129, 48,156,168, 29,232,225,236,+    230,247,233,228,244,104,128,255,159,238,116,  2,168, 48,168, 58,+    233,243,241,245,225,242,101,128, 51, 34,239,243,241,245,225,242,+    101,128, 51, 35,246,229,110,142,  0, 55,168,102,168,111,168,121,+    168,151,168,158,168,168,168,193,168,220,168,254,169, 10,169, 21,+    169, 54,169, 62,169, 73,225,242,225,226,233, 99,128,  6,103,226,+    229,238,231,225,236,105,128,  9,237,227,233,242,227,236,101,129,+     36,102,168,132,233,238,246,229,242,243,229,243,225,238,243,243,+    229,242,233,102,128, 39,144,228,229,246, 97,128,  9,109,229,233,+    231,232,244,232,115,128, 33, 94,231,117,  2,168,175,168,184,234,+    225,242,225,244,105,128, 10,237,242,237,245,235,232,105,128, 10,+    109,232, 97,  2,168,200,168,211,227,235,225,242,225,226,233, 99,+    128,  6,103,238,231,250,232,239,117,128, 48, 39,105,  2,168,226,+    168,244,228,229,239,231,242,225,240,232,233,227,240,225,242,229,+    110,128, 50, 38,238,230,229,242,233,239,114,128, 32,135,237,239,+    238,239,243,240,225,227,101,128,255, 23,239,236,228,243,244,249,+    236,101,128,247, 55,112,  2,169, 27,169, 34,225,242,229,110,128,+     36,122,229,114,  2,169, 41,169, 47,233,239,100,128, 36,142,243,+    233,225,110,128,  6,247,242,239,237,225,110,128, 33,118,243,245,+    240,229,242,233,239,114,128, 32,119,116,  2,169, 79,169,117,229,+    229,110,  2,169, 87,169, 96,227,233,242,227,236,101,128, 36,112,+    112,  2,169,102,169,109,225,242,229,110,128, 36,132,229,242,233,+    239,100,128, 36,152,232,225,105,128, 14, 87,230,244,232,249,240,+    232,229,110,128,  0,173,104,  7,169,150,170,124,170,135,170,149,+    171, 94,171,107,172, 15, 97,  6,169,164,169,175,169,185,169,196,+    170, 83,170,108,225,242,237,229,238,233,225,110,128,  5,119,226,+    229,238,231,225,236,105,128,  9,182,227,249,242,233,236,236,233,+     99,128,  4, 72,100,  2,169,202,170, 42,228, 97,  4,169,213,169,+    222,169,253,170, 11,225,242,225,226,233, 99,128,  6, 81,228,225,+    237,237, 97,  2,169,232,169,241,225,242,225,226,233, 99,128,252,+     97,244,225,238,225,242,225,226,233, 99,128,252, 94,230,225,244,+    232,225,225,242,225,226,233, 99,128,252, 96,235,225,243,242, 97,+      2,170, 21,170, 30,225,242,225,226,233, 99,128,252, 98,244,225,+    238,225,242,225,226,233, 99,128,252, 95,101,132, 37,146,170, 54,+    170, 61,170, 69,170, 78,228,225,242,107,128, 37,147,236,233,231,+    232,116,128, 37,145,237,229,228,233,245,109,128, 37,146,246, 97,+    128,  9, 54,231,117,  2,170, 90,170, 99,234,225,242,225,244,105,+    128, 10,182,242,237,245,235,232,105,128, 10, 54,236,243,232,229,+    236,229,244,232,229,226,242,229,119,128,  5,147,226,239,240,239,+    237,239,230,111,128, 49, 21,227,232,225,227,249,242,233,236,236,+    233, 99,128,  4, 73,101,  4,170,159,170,224,170,234,170,251,229,+    110,  4,170,170,170,179,170,193,170,209,225,242,225,226,233, 99,+    128,  6, 52,230,233,238,225,236,225,242,225,226,233, 99,128,254,+    182,233,238,233,244,233,225,236,225,242,225,226,233, 99,128,254,+    183,237,229,228,233,225,236,225,242,225,226,233, 99,128,254,184,+    233,227,239,240,244,233, 99,128,  3,227,241,229,108,129, 32,170,+    170,242,232,229,226,242,229,119,128, 32,170,246, 97,134,  5,176,+    171, 12,171, 27,171, 41,171, 50,171, 65,171, 81, 49,  2,171, 18,+    171, 23,177, 53,128,  5,176, 53,128,  5,176, 50,  2,171, 33,171,+     37, 50,128,  5,176,101,128,  5,176,232,229,226,242,229,119,128,+      5,176,238,225,242,242,239,247,232,229,226,242,229,119,128,  5,+    176,241,245,225,242,244,229,242,232,229,226,242,229,119,128,  5,+    176,247,233,228,229,232,229,226,242,229,119,128,  5,176,232,225,+    227,249,242,233,236,236,233, 99,128,  4,187,105,  2,171,113,171,+    124,237,225,227,239,240,244,233, 99,128,  3,237,110,131,  5,233,+    171,134,171,217,171,226,100,  2,171,140,171,206,225,231,229,243,+    104,130,251, 73,171,152,171,161,232,229,226,242,229,119,128,251,+     73,115,  2,171,167,171,187,232,233,238,228,239,116,129,251, 44,+    171,178,232,229,226,242,229,119,128,251, 44,233,238,228,239,116,+    129,251, 45,171,197,232,229,226,242,229,119,128,251, 45,239,244,+    232,229,226,242,229,119,128,  5,193,232,229,226,242,229,119,128,+      5,233,115,  2,171,232,171,252,232,233,238,228,239,116,129,251,+     42,171,243,232,229,226,242,229,119,128,251, 42,233,238,228,239,+    116,129,251, 43,172,  6,232,229,226,242,229,119,128,251, 43,239,+    239,107,128,  2,130,105,  8,172, 39,172, 83,172, 94,172,119,172,+    149,172,157,172,170,173, 85,231,237, 97,131,  3,195,172, 51,172,+     55,172, 63, 49,128,  3,194,230,233,238,225,108,128,  3,194,236,+    245,238,225,244,229,243,249,237,226,239,236,231,242,229,229,107,+    128,  3,242,232,233,242,225,231,225,238, 97,128, 48, 87,235,225,+    244,225,235,225,238, 97,129, 48,183,172,107,232,225,236,230,247,+    233,228,244,104,128,255,124,236,245,113,  2,172,127,172,136,232,+    229,226,242,229,119,128,  5,189,236,229,230,244,232,229,226,242,+    229,119,128,  5,189,237,233,236,225,114,128, 34, 60,238,228,239,+    244,232,229,226,242,229,119,128,  5,194,239,115,  6,172,185,172,+    220,172,252,173, 24,173, 38,173, 70, 97,  2,172,191,172,206,227,+    233,242,227,236,229,235,239,242,229,225,110,128, 50,116,240,225,+    242,229,238,235,239,242,229,225,110,128, 50, 20,227,105,  2,172,+    227,172,239,229,245,227,235,239,242,229,225,110,128, 49,126,242,+    227,236,229,235,239,242,229,225,110,128, 50,102,107,  2,173,  2,+    173, 16,233,249,229,239,235,235,239,242,229,225,110,128, 49,122,+    239,242,229,225,110,128, 49, 69,238,233,229,245,238,235,239,242,+    229,225,110,128, 49,123,112,  2,173, 44,173, 57,225,242,229,238,+    235,239,242,229,225,110,128, 50,  6,233,229,245,240,235,239,242,+    229,225,110,128, 49,125,244,233,235,229,245,244,235,239,242,229,+    225,110,128, 49,124,120,141,  0, 54,173,115,173,124,173,134,173,+    164,173,171,173,196,173,223,174,  1,174, 13,174, 24,174, 57,174,+     65,174, 76,225,242,225,226,233, 99,128,  6,102,226,229,238,231,+    225,236,105,128,  9,236,227,233,242,227,236,101,129, 36,101,173,+    145,233,238,246,229,242,243,229,243,225,238,243,243,229,242,233,+    102,128, 39,143,228,229,246, 97,128,  9,108,231,117,  2,173,178,+    173,187,234,225,242,225,244,105,128, 10,236,242,237,245,235,232,+    105,128, 10,108,232, 97,  2,173,203,173,214,227,235,225,242,225,+    226,233, 99,128,  6,102,238,231,250,232,239,117,128, 48, 38,105,+      2,173,229,173,247,228,229,239,231,242,225,240,232,233,227,240,+    225,242,229,110,128, 50, 37,238,230,229,242,233,239,114,128, 32,+    134,237,239,238,239,243,240,225,227,101,128,255, 22,239,236,228,+    243,244,249,236,101,128,247, 54,112,  2,174, 30,174, 37,225,242,+    229,110,128, 36,121,229,114,  2,174, 44,174, 50,233,239,100,128,+     36,141,243,233,225,110,128,  6,246,242,239,237,225,110,128, 33,+    117,243,245,240,229,242,233,239,114,128, 32,118,116,  2,174, 82,+    174,153,229,229,110,  2,174, 90,174,132, 99,  2,174, 96,174,104,+    233,242,227,236,101,128, 36,111,245,242,242,229,238,227,249,228,+    229,238,239,237,233,238,225,244,239,242,226,229,238,231,225,236,+    105,128,  9,249,112,  2,174,138,174,145,225,242,229,110,128, 36,+    131,229,242,233,239,100,128, 36,151,232,225,105,128, 14, 86,108,+      2,174,165,174,185,225,243,104,129,  0, 47,174,173,237,239,238,+    239,243,240,225,227,101,128,255, 15,239,238,103,129,  1,127,174,+    193,228,239,244,225,227,227,229,238,116,128, 30,155,109,  2,174,+    211,174,221,233,236,229,230,225,227,101,128, 38, 58,239,238,239,+    243,240,225,227,101,128,255, 83,111,  6,174,246,175, 40,175, 51,+    175, 76,175,121,175,132,102,  2,174,252,175, 10,240,225,243,245,+    241,232,229,226,242,229,119,128,  5,195,116,  2,175, 16,175, 25,+    232,249,240,232,229,110,128,  0,173,243,233,231,238,227,249,242,+    233,236,236,233, 99,128,  4, 76,232,233,242,225,231,225,238, 97,+    128, 48, 93,235,225,244,225,235,225,238, 97,129, 48,189,175, 64,+    232,225,236,230,247,233,228,244,104,128,255,127,236,233,228,245,+    115,  2,175, 86,175,103,236,239,238,231,239,246,229,242,236,225,+    249,227,237, 98,128,  3, 56,243,232,239,242,244,239,246,229,242,+    236,225,249,227,237, 98,128,  3, 55,242,245,243,233,244,232,225,+    105,128, 14, 41,115,  3,175,140,175,150,175,158,225,236,225,244,+    232,225,105,128, 14, 40,239,244,232,225,105,128, 14, 11,245,225,+    244,232,225,105,128, 14, 42,240, 97,  3,175,176,175,196,175,228,+    227,101,129,  0, 32,175,183,232,225,227,235,225,242,225,226,233,+     99,128,  0, 32,228,101,129, 38, 96,175,203,243,245,233,116,  2,+    175,212,175,220,226,236,225,227,107,128, 38, 96,247,232,233,244,+    101,128, 38,100,242,229,110,128, 36,174,241,245,225,242,101, 11,+    176,  6,176, 17,176, 31,176, 56,176, 73,176, 99,176,114,176,147,+    176,174,176,230,176,245,226,229,236,239,247,227,237, 98,128,  3,+     59, 99,  2,176, 23,176, 27, 99,128, 51,196,109,128, 51,157,228,+    233,225,231,239,238,225,236,227,242,239,243,243,232,225,244,227,+    232,230,233,236,108,128, 37,169,232,239,242,233,250,239,238,244,+    225,236,230,233,236,108,128, 37,164,107,  2,176, 79,176, 83,103,+    128, 51,143,109,129, 51,158,176, 89,227,225,240,233,244,225,108,+    128, 51,206,108,  2,176,105,176,109,110,128, 51,209,239,103,128,+     51,210,109,  4,176,124,176,128,176,133,176,137,103,128, 51,142,+    233,108,128, 51,213,109,128, 51,156,243,241,245,225,242,229,100,+    128, 51,161,239,242,244,232,239,231,239,238,225,236,227,242,239,+    243,243,232,225,244,227,232,230,233,236,108,128, 37,166,245,240,+    240,229,114,  2,176,184,176,207,236,229,230,244,244,239,236,239,+    247,229,242,242,233,231,232,244,230,233,236,108,128, 37,167,242,+    233,231,232,244,244,239,236,239,247,229,242,236,229,230,244,230,+    233,236,108,128, 37,168,246,229,242,244,233,227,225,236,230,233,+    236,108,128, 37,165,247,232,233,244,229,247,233,244,232,243,237,+    225,236,236,226,236,225,227,107,128, 37,163,242,243,241,245,225,+    242,101,128, 51,219,115,  2,177, 27,177,197, 97,  4,177, 37,177,+     47,177, 54,177, 65,226,229,238,231,225,236,105,128,  9,183,228,+    229,246, 97,128,  9, 55,231,245,234,225,242,225,244,105,128, 10,+    183,238,103,  8,177, 84,177, 98,177,112,177,126,177,141,177,155,+    177,169,177,182,227,233,229,245,227,235,239,242,229,225,110,128,+     49, 73,232,233,229,245,232,235,239,242,229,225,110,128, 49,133,+    233,229,245,238,231,235,239,242,229,225,110,128, 49,128,235,233,+    249,229,239,235,235,239,242,229,225,110,128, 49, 50,238,233,229,+    245,238,235,239,242,229,225,110,128, 49,101,240,233,229,245,240,+    235,239,242,229,225,110,128, 49, 67,243,233,239,243,235,239,242,+    229,225,110,128, 49, 70,244,233,235,229,245,244,235,239,242,229,+    225,110,128, 49, 56,245,240,229,242,233,239,114,128,246,242,116,+      2,177,213,177,236,229,242,236,233,238,103,129,  0,163,177,224,+    237,239,238,239,243,240,225,227,101,128,255,225,242,239,235,101,+      2,177,245,178,  6,236,239,238,231,239,246,229,242,236,225,249,+    227,237, 98,128,  3, 54,243,232,239,242,244,239,246,229,242,236,+    225,249,227,237, 98,128,  3, 53,117,  7,178, 40,178, 72,178, 94,+    178,105,178,146,178,156,178,160,226,243,229,116,130, 34,130,178,+     51,178, 62,238,239,244,229,241,245,225,108,128, 34,138,239,242,+    229,241,245,225,108,128, 34,134, 99,  2,178, 78,178, 86,227,229,+    229,228,115,128, 34,123,232,244,232,225,116,128, 34, 11,232,233,+    242,225,231,225,238, 97,128, 48, 89,107,  2,178,111,178,135,225,+    244,225,235,225,238, 97,129, 48,185,178,123,232,225,236,230,247,+    233,228,244,104,128,255,125,245,238,225,242,225,226,233, 99,128,+      6, 82,237,237,225,244,233,239,110,128, 34, 17,110,128, 38, 60,+    240,229,242,243,229,116,130, 34,131,178,173,178,184,238,239,244,+    229,241,245,225,108,128, 34,139,239,242,229,241,245,225,108,128,+     34,135,246,243,241,245,225,242,101,128, 51,220,249,239,245,247,+    225,229,242,225,243,241,245,225,242,101,128, 51,124,116,144,  0,+    116,179,  1,180, 10,180, 31,180,174,180,214,183,  6,186,144,187,+    219,187,231,187,243,189, 20,189, 45,189,131,190, 55,190,239,191,+     73, 97, 10,179, 23,179, 33,179, 54,179, 61,179, 86,179,164,179,+    181,179,206,179,220,179,224,226,229,238,231,225,236,105,128,  9,+    164,227,107,  2,179, 40,179, 47,228,239,247,110,128, 34,164,236,+    229,230,116,128, 34,163,228,229,246, 97,128,  9, 36,231,117,  2,+    179, 68,179, 77,234,225,242,225,244,105,128, 10,164,242,237,245,+    235,232,105,128, 10, 36,104,  4,179, 96,179,105,179,119,179,149,+    225,242,225,226,233, 99,128,  6, 55,230,233,238,225,236,225,242,+    225,226,233, 99,128,254,194,105,  2,179,125,179,140,238,233,244,+    233,225,236,225,242,225,226,233, 99,128,254,195,242,225,231,225,+    238, 97,128, 48, 95,237,229,228,233,225,236,225,242,225,226,233,+     99,128,254,196,233,243,249,239,245,229,242,225,243,241,245,225,+    242,101,128, 51,125,235,225,244,225,235,225,238, 97,129, 48,191,+    179,194,232,225,236,230,247,233,228,244,104,128,255,128,244,247,+    229,229,236,225,242,225,226,233, 99,128,  6, 64,117,128,  3,196,+    118,130,  5,234,179,232,180,  1,228,225,231,229,115,129,251, 74,+    179,242,104,129,251, 74,179,248,232,229,226,242,229,119,128,251,+     74,232,229,226,242,229,119,128,  5,234, 98,  2,180, 16,180, 21,+    225,114,128,  1,103,239,240,239,237,239,230,111,128, 49, 10, 99,+      6,180, 45,180, 52,180, 59,180, 68,180,134,180,161,225,242,239,+    110,128,  1,101,227,245,242,108,128,  2,168,229,228,233,236,236,+     97,128,  1, 99,232,229,104,  4,180, 80,180, 89,180,103,180,119,+    225,242,225,226,233, 99,128,  6,134,230,233,238,225,236,225,242,+    225,226,233, 99,128,251,123,233,238,233,244,233,225,236,225,242,+    225,226,233, 99,128,251,124,237,229,228,233,225,236,225,242,225,+    226,233, 99,128,251,125,233,242, 99,  2,180,142,180,147,236,101,+    128, 36,227,245,237,230,236,229,248,226,229,236,239,119,128, 30,+    113,239,237,237,225,225,227,227,229,238,116,128,  1, 99,100,  2,+    180,180,180,190,233,229,242,229,243,233,115,128, 30,151,239,116,+      2,180,197,180,206,225,227,227,229,238,116,128, 30,107,226,229,+    236,239,119,128, 30,109,101,  9,180,234,180,245,181,  9,182, 19,+    182, 44,182,108,182,175,182,180,182,232,227,249,242,233,236,236,+    233, 99,128,  4, 66,228,229,243,227,229,238,228,229,242,227,249,+    242,233,236,236,233, 99,128,  4,173,104,  7,181, 25,181, 34,181,+     48,181, 88,181,118,181,159,182,  1,225,242,225,226,233, 99,128,+      6, 42,230,233,238,225,236,225,242,225,226,233, 99,128,254,150,+    232,225,232,105,  2,181, 57,181, 72,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,252,162,243,239,236,225,244,229,228,225,+    242,225,226,233, 99,128,252, 12,105,  2,181, 94,181,109,238,233,+    244,233,225,236,225,242,225,226,233, 99,128,254,151,242,225,231,+    225,238, 97,128, 48,102,234,229,229,237,105,  2,181,128,181,143,+    238,233,244,233,225,236,225,242,225,226,233, 99,128,252,161,243,+    239,236,225,244,229,228,225,242,225,226,233, 99,128,252, 11,109,+      2,181,165,181,199,225,242,226,245,244, 97,  2,181,176,181,185,+    225,242,225,226,233, 99,128,  6, 41,230,233,238,225,236,225,242,+    225,226,233, 99,128,254,148,101,  2,181,205,181,218,228,233,225,+    236,225,242,225,226,233, 99,128,254,152,229,237,105,  2,181,226,+    181,241,238,233,244,233,225,236,225,242,225,226,233, 99,128,252,+    164,243,239,236,225,244,229,228,225,242,225,226,233, 99,128,252,+     14,238,239,239,238,230,233,238,225,236,225,242,225,226,233, 99,+    128,252,115,235,225,244,225,235,225,238, 97,129, 48,198,182, 32,+    232,225,236,230,247,233,228,244,104,128,255,131,108,  2,182, 50,+    182, 69,229,240,232,239,238,101,129, 33, 33,182, 61,226,236,225,+    227,107,128, 38, 14,233,243,232, 97,  2,182, 78,182, 93,231,229,+    228,239,236,225,232,229,226,242,229,119,128,  5,160,241,229,244,+    225,238,225,232,229,226,242,229,119,128,  5,169,110,  4,182,118,+    182,127,182,146,182,167,227,233,242,227,236,101,128, 36,105,233,+    228,229,239,231,242,225,240,232,233,227,240,225,242,229,110,128,+     50, 41,112,  2,182,152,182,159,225,242,229,110,128, 36,125,229,+    242,233,239,100,128, 36,145,242,239,237,225,110,128, 33,121,243,+    104,128,  2,167,116,131,  5,216,182,190,182,210,182,219,228,225,+    231,229,243,104,129,251, 56,182,201,232,229,226,242,229,119,128,+    251, 56,232,229,226,242,229,119,128,  5,216,243,229,227,249,242,+    233,236,236,233, 99,128,  4,181,246,233,114,  2,182,240,182,249,+    232,229,226,242,229,119,128,  5,155,236,229,230,244,232,229,226,+    242,229,119,128,  5,155,104,  6,183, 20,183,172,184, 38,184,170,+    185, 77,186,134, 97,  5,183, 32,183, 42,183, 49,183, 74,183,103,+    226,229,238,231,225,236,105,128,  9,165,228,229,246, 97,128,  9,+     37,231,117,  2,183, 56,183, 65,234,225,242,225,244,105,128, 10,+    165,242,237,245,235,232,105,128, 10, 37,108,  2,183, 80,183, 89,+    225,242,225,226,233, 99,128,  6, 48,230,233,238,225,236,225,242,+    225,226,233, 99,128,254,172,238,244,232,225,235,232,225,116,  3,+    183,118,183,149,183,156,236,239,119,  2,183,126,183,137,236,229,+    230,244,244,232,225,105,128,248,152,242,233,231,232,244,244,232,+    225,105,128,248,151,244,232,225,105,128, 14, 76,245,240,240,229,+    242,236,229,230,244,244,232,225,105,128,248,150,101,  3,183,180,+    183,244,184, 11,104,  4,183,190,183,199,183,213,183,229,225,242,+    225,226,233, 99,128,  6, 43,230,233,238,225,236,225,242,225,226,+    233, 99,128,254,154,233,238,233,244,233,225,236,225,242,225,226,+    233, 99,128,254,155,237,229,228,233,225,236,225,242,225,226,233,+     99,128,254,156,242,101,  2,183,251,184,  4,229,248,233,243,244,+    115,128, 34,  3,230,239,242,101,128, 34, 52,244, 97,130,  3,184,+    184, 20,184, 24, 49,128,  3,209,243,249,237,226,239,236,231,242,+    229,229,107,128,  3,209,105,  2,184, 44,184,130,229,245,244,104,+      4,184, 57,184, 92,184,107,184,116, 97,  2,184, 63,184, 78,227,+    233,242,227,236,229,235,239,242,229,225,110,128, 50,121,240,225,+    242,229,238,235,239,242,229,225,110,128, 50, 25,227,233,242,227,+    236,229,235,239,242,229,225,110,128, 50,107,235,239,242,229,225,+    110,128, 49, 76,240,225,242,229,238,235,239,242,229,225,110,128,+     50, 11,242,244,229,229,110,  2,184,140,184,149,227,233,242,227,+    236,101,128, 36,108,112,  2,184,155,184,162,225,242,229,110,128,+     36,128,229,242,233,239,100,128, 36,148,111,  6,184,184,184,201,+    184,206,184,220,184,225,185, 22,238,225,238,231,237,239,238,244,+    232,239,244,232,225,105,128, 14, 17,239,107,128,  1,173,240,232,+    245,244,232,225,239,244,232,225,105,128, 14, 18,242,110,128,  0,+    254,244,104,  3,184,234,185,  2,185, 12, 97,  2,184,240,184,250,+    232,225,238,244,232,225,105,128, 14, 23,238,244,232,225,105,128,+     14, 16,239,238,231,244,232,225,105,128, 14, 24,245,238,231,244,+    232,225,105,128, 14, 22,245,243,225,238,100,  2,185, 32,185, 43,+    227,249,242,233,236,236,233, 99,128,  4,130,243,243,229,240,225,+    242,225,244,239,114,  2,185, 58,185, 67,225,242,225,226,233, 99,+    128,  6,108,240,229,242,243,233,225,110,128,  6,108,242,229,101,+    144,  0, 51,185,115,185,124,185,134,185,164,185,171,185,181,185,+    206,185,233,186, 11,186, 23,186, 42,186, 53,186, 86,186,108,186,+    116,186,127,225,242,225,226,233, 99,128,  6, 99,226,229,238,231,+    225,236,105,128,  9,233,227,233,242,227,236,101,129, 36, 98,185,+    145,233,238,246,229,242,243,229,243,225,238,243,243,229,242,233,+    102,128, 39,140,228,229,246, 97,128,  9,105,229,233,231,232,244,+    232,115,128, 33, 92,231,117,  2,185,188,185,197,234,225,242,225,+    244,105,128, 10,233,242,237,245,235,232,105,128, 10,105,232, 97,+      2,185,213,185,224,227,235,225,242,225,226,233, 99,128,  6, 99,+    238,231,250,232,239,117,128, 48, 35,105,  2,185,239,186,  1,228,+    229,239,231,242,225,240,232,233,227,240,225,242,229,110,128, 50,+     34,238,230,229,242,233,239,114,128, 32,131,237,239,238,239,243,+    240,225,227,101,128,255, 19,238,245,237,229,242,225,244,239,242,+    226,229,238,231,225,236,105,128,  9,246,239,236,228,243,244,249,+    236,101,128,247, 51,112,  2,186, 59,186, 66,225,242,229,110,128,+     36,118,229,114,  2,186, 73,186, 79,233,239,100,128, 36,138,243,+    233,225,110,128,  6,243,241,245,225,242,244,229,242,115,129,  0,+    190,186, 99,229,237,228,225,243,104,128,246,222,242,239,237,225,+    110,128, 33,114,243,245,240,229,242,233,239,114,128,  0,179,244,+    232,225,105,128, 14, 83,250,243,241,245,225,242,101,128, 51,148,+    105,  7,186,160,186,171,187, 30,187,128,187,140,187,189,187,206,+    232,233,242,225,231,225,238, 97,128, 48, 97,107,  2,186,177,186,+    201,225,244,225,235,225,238, 97,129, 48,193,186,189,232,225,236,+    230,247,233,228,244,104,128,255,129,229,245,116,  4,186,213,186,+    248,187,  7,187, 16, 97,  2,186,219,186,234,227,233,242,227,236,+    229,235,239,242,229,225,110,128, 50,112,240,225,242,229,238,235,+    239,242,229,225,110,128, 50, 16,227,233,242,227,236,229,235,239,+    242,229,225,110,128, 50, 98,235,239,242,229,225,110,128, 49, 55,+    240,225,242,229,238,235,239,242,229,225,110,128, 50,  2,236,228,+    101,133,  2,220,187, 46,187, 57,187, 74,187, 86,187,114,226,229,+    236,239,247,227,237, 98,128,  3, 48, 99,  2,187, 63,187, 68,237,+     98,128,  3,  3,239,237, 98,128,  3,  3,228,239,245,226,236,229,+    227,237, 98,128,  3, 96,111,  2,187, 92,187,102,240,229,242,225,+    244,239,114,128, 34, 60,246,229,242,236,225,249,227,237, 98,128,+      3, 52,246,229,242,244,233,227,225,236,227,237, 98,128,  3, 62,+    237,229,243,227,233,242,227,236,101,128, 34,151,112,  2,187,146,+    187,176,229,232, 97,  2,187,154,187,163,232,229,226,242,229,119,+    128,  5,150,236,229,230,244,232,229,226,242,229,119,128,  5,150,+    240,233,231,245,242,237,245,235,232,105,128, 10,112,244,236,239,+    227,249,242,233,236,236,233,227,227,237, 98,128,  4,131,247,238,+    225,242,237,229,238,233,225,110,128,  5,127,236,233,238,229,226,+    229,236,239,119,128, 30,111,237,239,238,239,243,240,225,227,101,+    128,255, 84,111,  7,188,  3,188, 14,188, 25,188, 50,188,170,188,+    182,189, 10,225,242,237,229,238,233,225,110,128,  5,105,232,233,+    242,225,231,225,238, 97,128, 48,104,235,225,244,225,235,225,238,+     97,129, 48,200,188, 38,232,225,236,230,247,233,228,244,104,128,+    255,132,110,  3,188, 58,188,156,188,161,101,  4,188, 68,188,137,+    188,144,188,150,226,225,114,  4,188, 80,188,109,188,119,188,128,+    229,248,244,242, 97,  2,188, 90,188,100,232,233,231,232,237,239,+    100,128,  2,229,236,239,247,237,239,100,128,  2,233,232,233,231,+    232,237,239,100,128,  2,230,236,239,247,237,239,100,128,  2,232,+    237,233,228,237,239,100,128,  2,231,230,233,246,101,128,  1,189,+    243,233,120,128,  1,133,244,247,111,128,  1,168,239,115,128,  3,+    132,243,241,245,225,242,101,128, 51, 39,240,225,244,225,235,244,+    232,225,105,128, 14, 15,242,244,239,233,243,229,243,232,229,236,+    236,226,242,225,227,235,229,116,  2,188,205,188,235,236,229,230,+    116,130, 48, 20,188,216,188,224,243,237,225,236,108,128,254, 93,+    246,229,242,244,233,227,225,108,128,254, 57,242,233,231,232,116,+    130, 48, 21,188,247,188,255,243,237,225,236,108,128,254, 94,246,+    229,242,244,233,227,225,108,128,254, 58,244,225,239,244,232,225,+    105,128, 14, 21,240, 97,  2,189, 27,189, 39,236,225,244,225,236,+    232,239,239,107,128,  1,171,242,229,110,128, 36,175,114,  3,189,+     53,189, 84,189, 99,225,228,229,237,225,242,107,129, 33, 34,189,+     65,115,  2,189, 71,189, 77,225,238,115,128,248,234,229,242,233,+    102,128,246,219,229,244,242,239,230,236,229,248,232,239,239,107,+    128,  2,136,233,225,103,  4,189,111,189,116,189,121,189,126,228,+    110,128, 37,188,236,102,128, 37,196,242,116,128, 37,186,245,112,+    128, 37,178,115,132,  2,166,189,143,189,182,190, 32,190, 45,225,+    228,105,130,  5,230,189,153,189,173,228,225,231,229,243,104,129,+    251, 70,189,164,232,229,226,242,229,119,128,251, 70,232,229,226,+    242,229,119,128,  5,230,101,  2,189,188,189,199,227,249,242,233,+    236,236,233, 99,128,  4, 70,242,101,134,  5,181,189,216,189,230,+    189,235,189,244,190,  3,190, 19, 49,  2,189,222,189,226, 50,128,+      5,181,101,128,  5,181,178, 98,128,  5,181,232,229,226,242,229,+    119,128,  5,181,238,225,242,242,239,247,232,229,226,242,229,119,+    128,  5,181,241,245,225,242,244,229,242,232,229,226,242,229,119,+    128,  5,181,247,233,228,229,232,229,226,242,229,119,128,  5,181,+    232,229,227,249,242,233,236,236,233, 99,128,  4, 91,245,240,229,+    242,233,239,114,128,246,243,116,  4,190, 65,190,115,190,180,190,+    231, 97,  3,190, 73,190, 83,190, 90,226,229,238,231,225,236,105,+    128,  9,159,228,229,246, 97,128,  9, 31,231,117,  2,190, 97,190,+    106,234,225,242,225,244,105,128, 10,159,242,237,245,235,232,105,+    128, 10, 31,229,104,  4,190,126,190,135,190,149,190,165,225,242,+    225,226,233, 99,128,  6,121,230,233,238,225,236,225,242,225,226,+    233, 99,128,251,103,233,238,233,244,233,225,236,225,242,225,226,+    233, 99,128,251,104,237,229,228,233,225,236,225,242,225,226,233,+     99,128,251,105,232, 97,  3,190,189,190,199,190,206,226,229,238,+    231,225,236,105,128,  9,160,228,229,246, 97,128,  9, 32,231,117,+      2,190,213,190,222,234,225,242,225,244,105,128, 10,160,242,237,+    245,235,232,105,128, 10, 32,245,242,238,229,100,128,  2,135,117,+      3,190,247,191,  2,191, 27,232,233,242,225,231,225,238, 97,128,+     48,100,235,225,244,225,235,225,238, 97,129, 48,196,191, 15,232,+    225,236,230,247,233,228,244,104,128,255,130,243,237,225,236,108,+      2,191, 37,191, 48,232,233,242,225,231,225,238, 97,128, 48, 99,+    235,225,244,225,235,225,238, 97,129, 48,195,191, 61,232,225,236,+    230,247,233,228,244,104,128,255,111,119,  2,191, 79,191,184,101,+      2,191, 85,191,133,236,246,101,  3,191, 95,191,104,191,125,227,+    233,242,227,236,101,128, 36,107,112,  2,191,110,191,117,225,242,+    229,110,128, 36,127,229,242,233,239,100,128, 36,147,242,239,237,+    225,110,128, 33,123,238,244,121,  3,191,143,191,152,191,163,227,+    233,242,227,236,101,128, 36,115,232,225,238,231,250,232,239,117,+    128, 83, 68,112,  2,191,169,191,176,225,242,229,110,128, 36,135,+    229,242,233,239,100,128, 36,155,111,142,  0, 50,191,216,191,225,+    191,235,192,  9,192, 61,192, 86,192,113,192,147,192,159,192,178,+    192,189,192,222,192,230,192,254,225,242,225,226,233, 99,128,  6,+     98,226,229,238,231,225,236,105,128,  9,232,227,233,242,227,236,+    101,129, 36, 97,191,246,233,238,246,229,242,243,229,243,225,238,+    243,243,229,242,233,102,128, 39,139,100,  2,192, 15,192, 21,229,+    246, 97,128,  9,104,239,116,  2,192, 28,192, 39,229,238,236,229,+    225,228,229,114,128, 32, 37,236,229,225,228,229,114,129, 32, 37,+    192, 50,246,229,242,244,233,227,225,108,128,254, 48,231,117,  2,+    192, 68,192, 77,234,225,242,225,244,105,128, 10,232,242,237,245,+    235,232,105,128, 10,104,232, 97,  2,192, 93,192,104,227,235,225,+    242,225,226,233, 99,128,  6, 98,238,231,250,232,239,117,128, 48,+     34,105,  2,192,119,192,137,228,229,239,231,242,225,240,232,233,+    227,240,225,242,229,110,128, 50, 33,238,230,229,242,233,239,114,+    128, 32,130,237,239,238,239,243,240,225,227,101,128,255, 18,238,+    245,237,229,242,225,244,239,242,226,229,238,231,225,236,105,128,+      9,245,239,236,228,243,244,249,236,101,128,247, 50,112,  2,192,+    195,192,202,225,242,229,110,128, 36,117,229,114,  2,192,209,192,+    215,233,239,100,128, 36,137,243,233,225,110,128,  6,242,242,239,+    237,225,110,128, 33,113,115,  2,192,236,192,244,244,242,239,235,+    101,128,  1,187,245,240,229,242,233,239,114,128,  0,178,244,104,+      2,193,  5,193, 10,225,105,128, 14, 82,233,242,228,115,128, 33,+     84,117,145,  0,117,193, 55,193, 63,193,104,193,161,194, 43,194,+     80,194,203,194,219,195, 14,195, 84,195,165,195,174,196, 37,196,+     61,196,169,196,197,197, 55,225,227,245,244,101,128,  0,250, 98,+      4,193, 73,193, 78,193, 87,193, 97,225,114,128,  2,137,229,238,+    231,225,236,105,128,  9,137,239,240,239,237,239,230,111,128, 49,+     40,242,229,246,101,128,  1,109, 99,  3,193,112,193,119,193,151,+    225,242,239,110,128,  1,212,233,242, 99,  2,193,127,193,132,236,+    101,128, 36,228,245,237,230,236,229,120,129,  0,251,193,143,226,+    229,236,239,119,128, 30,119,249,242,233,236,236,233, 99,128,  4,+     67,100,  5,193,173,193,184,193,207,193,213,194, 33,225,244,244,+    225,228,229,246, 97,128,  9, 81,226,108,  2,193,191,193,199,225,+    227,245,244,101,128,  1,113,231,242,225,246,101,128,  2, 21,229,+    246, 97,128,  9,  9,233,229,242,229,243,233,115,133,  0,252,193,+    233,193,241,193,249,194, 16,194, 24,225,227,245,244,101,128,  1,+    216,226,229,236,239,119,128, 30,115, 99,  2,193,255,194,  6,225,+    242,239,110,128,  1,218,249,242,233,236,236,233, 99,128,  4,241,+    231,242,225,246,101,128,  1,220,237,225,227,242,239,110,128,  1,+    214,239,244,226,229,236,239,119,128, 30,229,103,  2,194, 49,194,+     56,242,225,246,101,128,  0,249,117,  2,194, 62,194, 71,234,225,+    242,225,244,105,128, 10,137,242,237,245,235,232,105,128, 10,  9,+    104,  3,194, 88,194, 98,194,176,233,242,225,231,225,238, 97,128,+     48, 70,111,  2,194,104,194,114,239,235,225,226,239,246,101,128,+     30,231,242,110,133,  1,176,194,129,194,137,194,148,194,156,194,+    168,225,227,245,244,101,128, 30,233,228,239,244,226,229,236,239,+    119,128, 30,241,231,242,225,246,101,128, 30,235,232,239,239,235,+    225,226,239,246,101,128, 30,237,244,233,236,228,101,128, 30,239,+    245,238,231,225,242,245,237,236,225,245,116,129,  1,113,194,192,+    227,249,242,233,236,236,233, 99,128,  4,243,233,238,246,229,242,+    244,229,228,226,242,229,246,101,128,  2, 23,107,  3,194,227,194,+    251,195,  6,225,244,225,235,225,238, 97,129, 48,166,194,239,232,+    225,236,230,247,233,228,244,104,128,255,115,227,249,242,233,236,+    236,233, 99,128,  4,121,239,242,229,225,110,128, 49, 92,109,  2,+    195, 20,195, 73, 97,  2,195, 26,195, 59,227,242,239,110,130,  1,+    107,195, 37,195, 48,227,249,242,233,236,236,233, 99,128,  4,239,+    228,233,229,242,229,243,233,115,128, 30,123,244,242,225,231,245,+    242,237,245,235,232,105,128, 10, 65,239,238,239,243,240,225,227,+    101,128,255, 85,110,  2,195, 90,195,145,228,229,242,243,227,239,+    242,101,132,  0, 95,195,109,195,115,195,127,195,138,228,226,108,+    128, 32, 23,237,239,238,239,243,240,225,227,101,128,255, 63,246,+    229,242,244,233,227,225,108,128,254, 51,247,225,246,121,128,254,+     79,105,  2,195,151,195,156,239,110,128, 34, 42,246,229,242,243,+    225,108,128, 34,  0,239,231,239,238,229,107,128,  1,115,112,  5,+    195,186,195,193,195,201,195,216,196, 11,225,242,229,110,128, 36,+    176,226,236,239,227,107,128, 37,128,240,229,242,228,239,244,232,+    229,226,242,229,119,128,  5,196,243,233,236,239,110,131,  3,197,+    195,230,195,251,196,  3,228,233,229,242,229,243,233,115,129,  3,+    203,195,243,244,239,238,239,115,128,  3,176,236,225,244,233,110,+    128,  2,138,244,239,238,239,115,128,  3,205,244,225,227,107,  2,+    196, 20,196, 31,226,229,236,239,247,227,237, 98,128,  3, 29,237,+    239,100,128,  2,212,114,  2,196, 43,196, 55,225,231,245,242,237,+    245,235,232,105,128, 10,115,233,238,103,128,  1,111,115,  3,196,+     69,196, 84,196,129,232,239,242,244,227,249,242,233,236,236,233,+     99,128,  4, 94,237,225,236,108,  2,196, 93,196,104,232,233,242,+    225,231,225,238, 97,128, 48, 69,235,225,244,225,235,225,238, 97,+    129, 48,165,196,117,232,225,236,230,247,233,228,244,104,128,255,+    105,244,242,225,233,231,232,116,  2,196,141,196,152,227,249,242,+    233,236,236,233, 99,128,  4,175,243,244,242,239,235,229,227,249,+    242,233,236,236,233, 99,128,  4,177,244,233,236,228,101,130,  1,+    105,196,181,196,189,225,227,245,244,101,128, 30,121,226,229,236,+    239,119,128, 30,117,117,  5,196,209,196,219,196,226,196,251,197,+     11,226,229,238,231,225,236,105,128,  9,138,228,229,246, 97,128,+      9, 10,231,117,  2,196,233,196,242,234,225,242,225,244,105,128,+     10,138,242,237,245,235,232,105,128, 10, 10,237,225,244,242,225,+    231,245,242,237,245,235,232,105,128, 10, 66,246,239,247,229,236,+    243,233,231,110,  3,197, 27,197, 37,197, 44,226,229,238,231,225,+    236,105,128,  9,194,228,229,246, 97,128,  9, 66,231,245,234,225,+    242,225,244,105,128, 10,194,246,239,247,229,236,243,233,231,110,+      3,197, 71,197, 81,197, 88,226,229,238,231,225,236,105,128,  9,+    193,228,229,246, 97,128,  9, 65,231,245,234,225,242,225,244,105,+    128, 10,193,118,139,  0,118,197,125,198, 17,198, 26,198, 37,198,+    222,198,229,199, 71,199, 83,199,183,199,191,199,212, 97,  4,197,+    135,197,142,197,167,197,178,228,229,246, 97,128,  9, 53,231,117,+      2,197,149,197,158,234,225,242,225,244,105,128, 10,181,242,237,+    245,235,232,105,128, 10, 53,235,225,244,225,235,225,238, 97,128,+     48,247,118,132,  5,213,197,190,197,217,197,249,198,  5,228,225,+    231,229,243,104,130,251, 53,197,203,197,208,182, 53,128,251, 53,+    232,229,226,242,229,119,128,251, 53,104,  2,197,223,197,231,229,+    226,242,229,119,128,  5,213,239,236,225,109,129,251, 75,197,240,+    232,229,226,242,229,119,128,251, 75,246,225,246,232,229,226,242,+    229,119,128,  5,240,249,239,228,232,229,226,242,229,119,128,  5,+    241,227,233,242,227,236,101,128, 36,229,228,239,244,226,229,236,+    239,119,128, 30,127,101,  6,198, 51,198, 62,198,126,198,137,198,+    143,198,210,227,249,242,233,236,236,233, 99,128,  4, 50,104,  4,+    198, 72,198, 81,198, 95,198,111,225,242,225,226,233, 99,128,  6,+    164,230,233,238,225,236,225,242,225,226,233, 99,128,251,107,233,+    238,233,244,233,225,236,225,242,225,226,233, 99,128,251,108,237,+    229,228,233,225,236,225,242,225,226,233, 99,128,251,109,235,225,+    244,225,235,225,238, 97,128, 48,249,238,245,115,128, 38, 64,242,+    244,233,227,225,108,  2,198,154,198,160,226,225,114,128,  0,124,+    236,233,238,101,  4,198,173,198,184,198,195,198,204,225,226,239,+    246,229,227,237, 98,128,  3, 13,226,229,236,239,247,227,237, 98,+    128,  3, 41,236,239,247,237,239,100,128,  2,204,237,239,100,128,+      2,200,247,225,242,237,229,238,233,225,110,128,  5,126,232,239,+    239,107,128,  2,139,105,  3,198,237,198,248,199, 31,235,225,244,+    225,235,225,238, 97,128, 48,248,242,225,237, 97,  3,199,  3,199,+     13,199, 20,226,229,238,231,225,236,105,128,  9,205,228,229,246,+     97,128,  9, 77,231,245,234,225,242,225,244,105,128, 10,205,243,+    225,242,231, 97,  3,199, 43,199, 53,199, 60,226,229,238,231,225,+    236,105,128,  9,131,228,229,246, 97,128,  9,  3,231,245,234,225,+    242,225,244,105,128, 10,131,237,239,238,239,243,240,225,227,101,+    128,255, 86,111,  3,199, 91,199,102,199,172,225,242,237,229,238,+    233,225,110,128,  5,120,233,227,229,100,  2,199,111,199,147,233,+    244,229,242,225,244,233,239,110,  2,199,125,199,136,232,233,242,+    225,231,225,238, 97,128, 48,158,235,225,244,225,235,225,238, 97,+    128, 48,254,237,225,242,235,235,225,238, 97,129, 48,155,199,160,+    232,225,236,230,247,233,228,244,104,128,255,158,235,225,244,225,+    235,225,238, 97,128, 48,250,240,225,242,229,110,128, 36,177,116,+      2,199,197,199,204,233,236,228,101,128, 30,125,245,242,238,229,+    100,128,  2,140,117,  2,199,218,199,229,232,233,242,225,231,225,+    238, 97,128, 48,148,235,225,244,225,235,225,238, 97,128, 48,244,+    119,143,  0,119,200, 18,200,251,201,  5,201, 28,201, 68,201,135,+    201,143,203,114,203,155,203,167,203,242,203,250,204,  1,204, 12,+    204, 21, 97,  8,200, 36,200, 43,200, 53,200, 64,200,102,200,134,+    200,146,200,182,227,245,244,101,128, 30,131,229,235,239,242,229,+    225,110,128, 49, 89,232,233,242,225,231,225,238, 97,128, 48,143,+    107,  2,200, 70,200, 94,225,244,225,235,225,238, 97,129, 48,239,+    200, 82,232,225,236,230,247,233,228,244,104,128,255,156,239,242,+    229,225,110,128, 49, 88,243,237,225,236,108,  2,200,112,200,123,+    232,233,242,225,231,225,238, 97,128, 48,142,235,225,244,225,235,+    225,238, 97,128, 48,238,244,244,239,243,241,245,225,242,101,128,+     51, 87,118,  2,200,152,200,160,229,228,225,243,104,128, 48, 28,+    249,245,238,228,229,242,243,227,239,242,229,246,229,242,244,233,+    227,225,108,128,254, 52,119,  3,200,190,200,199,200,213,225,242,+    225,226,233, 99,128,  6, 72,230,233,238,225,236,225,242,225,226,+    233, 99,128,254,238,232,225,237,250,225,225,226,239,246,101,  2,+    200,228,200,237,225,242,225,226,233, 99,128,  6, 36,230,233,238,+    225,236,225,242,225,226,233, 99,128,254,134,226,243,241,245,225,+    242,101,128, 51,221,227,233,242, 99,  2,201, 14,201, 19,236,101,+    128, 36,230,245,237,230,236,229,120,128,  1,117,100,  2,201, 34,+    201, 44,233,229,242,229,243,233,115,128, 30,133,239,116,  2,201,+     51,201, 60,225,227,227,229,238,116,128, 30,135,226,229,236,239,+    119,128, 30,137,101,  4,201, 78,201, 89,201,101,201,125,232,233,+    242,225,231,225,238, 97,128, 48,145,233,229,242,243,244,242,225,+    243,115,128, 33, 24,107,  2,201,107,201,117,225,244,225,235,225,+    238, 97,128, 48,241,239,242,229,225,110,128, 49, 94,239,235,239,+    242,229,225,110,128, 49, 93,231,242,225,246,101,128, 30,129,232,+    233,244,101,  8,201,164,201,173,202,  1,202, 91,202,175,202,220,+    203, 16,203, 72,226,245,236,236,229,116,128, 37,230, 99,  2,201,+    179,201,199,233,242,227,236,101,129, 37,203,201,189,233,238,246,+    229,242,243,101,128, 37,217,239,242,238,229,242,226,242,225,227,+    235,229,116,  2,201,216,201,236,236,229,230,116,129, 48, 14,201,+    225,246,229,242,244,233,227,225,108,128,254, 67,242,233,231,232,+    116,129, 48, 15,201,246,246,229,242,244,233,227,225,108,128,254,+     68,100,  2,202,  7,202, 48,233,225,237,239,238,100,129, 37,199,+    202, 18,227,239,238,244,225,233,238,233,238,231,226,236,225,227,+    235,243,237,225,236,236,228,233,225,237,239,238,100,128, 37,200,+    239,247,238,240,239,233,238,244,233,238,103,  2,202, 64,202, 80,+    243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37,191,+    244,242,233,225,238,231,236,101,128, 37,189,236,101,  2,202, 98,+    202,140,230,244,240,239,233,238,244,233,238,103,  2,202,113,202,+    129,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37,+    195,244,242,233,225,238,231,236,101,128, 37,193,238,244,233,227,+    245,236,225,242,226,242,225,227,235,229,116,  2,202,160,202,167,+    236,229,230,116,128, 48, 22,242,233,231,232,116,128, 48, 23,242,+    233,231,232,244,240,239,233,238,244,233,238,103,  2,202,193,202,+    209,243,237,225,236,236,244,242,233,225,238,231,236,101,128, 37,+    185,244,242,233,225,238,231,236,101,128, 37,183,115,  3,202,228,+    203,  2,203, 10,109,  2,202,234,202,246,225,236,236,243,241,245,+    225,242,101,128, 37,171,233,236,233,238,231,230,225,227,101,128,+     38, 58,241,245,225,242,101,128, 37,161,244,225,114,128, 38,  6,+    116,  2,203, 22,203, 33,229,236,229,240,232,239,238,101,128, 38,+     15,239,242,244,239,233,243,229,243,232,229,236,236,226,242,225,+    227,235,229,116,  2,203, 57,203, 64,236,229,230,116,128, 48, 24,+    242,233,231,232,116,128, 48, 25,245,240,240,239,233,238,244,233,+    238,103,  2,203, 87,203,103,243,237,225,236,236,244,242,233,225,+    238,231,236,101,128, 37,181,244,242,233,225,238,231,236,101,128,+     37,179,105,  2,203,120,203,131,232,233,242,225,231,225,238, 97,+    128, 48,144,107,  2,203,137,203,147,225,244,225,235,225,238, 97,+    128, 48,240,239,242,229,225,110,128, 49, 95,237,239,238,239,243,+    240,225,227,101,128,255, 87,111,  4,203,177,203,188,203,213,203,+    231,232,233,242,225,231,225,238, 97,128, 48,146,235,225,244,225,+    235,225,238, 97,129, 48,242,203,201,232,225,236,230,247,233,228,+    244,104,128,255,102,110,129, 32,169,203,219,237,239,238,239,243,+    240,225,227,101,128,255,230,247,225,229,238,244,232,225,105,128,+     14, 39,240,225,242,229,110,128, 36,178,242,233,238,103,128, 30,+    152,243,245,240,229,242,233,239,114,128,  2,183,244,245,242,238,+    229,100,128,  2,141,249,238,110,128,  1,191,120,137,  0,120,204,+     49,204, 60,204, 71,204, 80,204,107,204,120,204,124,204,136,204,+    144,225,226,239,246,229,227,237, 98,128,  3, 61,226,239,240,239,+    237,239,230,111,128, 49, 18,227,233,242,227,236,101,128, 36,231,+    100,  2,204, 86,204, 96,233,229,242,229,243,233,115,128, 30,141,+    239,244,225,227,227,229,238,116,128, 30,139,229,232,225,242,237,+    229,238,233,225,110,128,  5,109,105,128,  3,190,237,239,238,239,+    243,240,225,227,101,128,255, 88,240,225,242,229,110,128, 36,179,+    243,245,240,229,242,233,239,114,128,  2,227,121,143,  0,121,204,+    189,205,148,205,171,205,211,207,177,207,185,207,202,208, 10,208,+     22,209, 19,209, 59,209, 71,209, 82,209,103,210, 76, 97, 11,204,+    213,204,225,204,235,204,242,204,249,205,  3,205, 28,205, 39,205,+     77,205, 90,205,136,225,228,239,243,241,245,225,242,101,128, 51,+     78,226,229,238,231,225,236,105,128,  9,175,227,245,244,101,128,+      0,253,228,229,246, 97,128,  9, 47,229,235,239,242,229,225,110,+    128, 49, 82,231,117,  2,205, 10,205, 19,234,225,242,225,244,105,+    128, 10,175,242,237,245,235,232,105,128, 10, 47,232,233,242,225,+    231,225,238, 97,128, 48,132,107,  2,205, 45,205, 69,225,244,225,+    235,225,238, 97,129, 48,228,205, 57,232,225,236,230,247,233,228,+    244,104,128,255,148,239,242,229,225,110,128, 49, 81,237,225,235,+    235,225,238,244,232,225,105,128, 14, 78,243,237,225,236,108,  2,+    205,100,205,111,232,233,242,225,231,225,238, 97,128, 48,131,235,+    225,244,225,235,225,238, 97,129, 48,227,205,124,232,225,236,230,+    247,233,228,244,104,128,255,108,244,227,249,242,233,236,236,233,+     99,128,  4, 99,227,233,242, 99,  2,205,157,205,162,236,101,128,+     36,232,245,237,230,236,229,120,128,  1,119,100,  2,205,177,205,+    187,233,229,242,229,243,233,115,128,  0,255,239,116,  2,205,194,+    205,203,225,227,227,229,238,116,128, 30,143,226,229,236,239,119,+    128, 30,245,101,  7,205,227,206,235,206,244,207,  6,207, 38,207,+    114,207,165,104,  8,205,245,205,254,206, 32,206, 46,206,119,206,+    135,206,194,206,212,225,242,225,226,233, 99,128,  6, 74,226,225,+    242,242,229,101,  2,206,  9,206, 18,225,242,225,226,233, 99,128,+      6,210,230,233,238,225,236,225,242,225,226,233, 99,128,251,175,+    230,233,238,225,236,225,242,225,226,233, 99,128,254,242,232,225,+    237,250,225,225,226,239,246,101,  4,206, 65,206, 74,206, 88,206,+    104,225,242,225,226,233, 99,128,  6, 38,230,233,238,225,236,225,+    242,225,226,233, 99,128,254,138,233,238,233,244,233,225,236,225,+    242,225,226,233, 99,128,254,139,237,229,228,233,225,236,225,242,+    225,226,233, 99,128,254,140,233,238,233,244,233,225,236,225,242,+    225,226,233, 99,128,254,243,237,101,  2,206,142,206,155,228,233,+    225,236,225,242,225,226,233, 99,128,254,244,229,237,105,  2,206,+    163,206,178,238,233,244,233,225,236,225,242,225,226,233, 99,128,+    252,221,243,239,236,225,244,229,228,225,242,225,226,233, 99,128,+    252, 88,238,239,239,238,230,233,238,225,236,225,242,225,226,233,+     99,128,252,148,244,232,242,229,229,228,239,244,243,226,229,236,+    239,247,225,242,225,226,233, 99,128,  6,209,235,239,242,229,225,+    110,128, 49, 86,110,129,  0,165,206,250,237,239,238,239,243,240,+    225,227,101,128,255,229,111,  2,207, 12,207, 21,235,239,242,229,+    225,110,128, 49, 85,242,233,238,232,233,229,245,232,235,239,242,+    229,225,110,128, 49,134,114,  3,207, 46,207, 82,207, 94,225,232,+    226,229,238,249,239,237,111,  2,207, 60,207, 69,232,229,226,242,+    229,119,128,  5,170,236,229,230,244,232,229,226,242,229,119,128,+      5,170,233,227,249,242,233,236,236,233, 99,128,  4, 75,245,228,+    233,229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128,+      4,249,243,233,229,245,238,103,  3,207,127,207,136,207,152,235,+    239,242,229,225,110,128, 49,129,240,225,238,243,233,239,243,235,+    239,242,229,225,110,128, 49,131,243,233,239,243,235,239,242,229,+    225,110,128, 49,130,244,233,246,232,229,226,242,229,119,128,  5,+    154,231,242,225,246,101,128, 30,243,232,239,239,107,129,  1,180,+    207,194,225,226,239,246,101,128, 30,247,105,  5,207,214,207,225,+    207,236,207,245,207,253,225,242,237,229,238,233,225,110,128,  5,+    117,227,249,242,233,236,236,233, 99,128,  4, 87,235,239,242,229,+    225,110,128, 49, 98,238,249,225,238,103,128, 38, 47,247,238,225,+    242,237,229,238,233,225,110,128,  5,130,237,239,238,239,243,240,+    225,227,101,128,255, 89,111,  7,208, 38,208,108,208,119,208,129,+    208,167,208,213,208,222,100,131,  5,217,208, 48,208, 68,208, 77,+    228,225,231,229,243,104,129,251, 57,208, 59,232,229,226,242,229,+    119,128,251, 57,232,229,226,242,229,119,128,  5,217,249,239,100,+      2,208, 85,208, 94,232,229,226,242,229,119,128,  5,242,240,225,+    244,225,232,232,229,226,242,229,119,128,251, 31,232,233,242,225,+    231,225,238, 97,128, 48,136,233,235,239,242,229,225,110,128, 49,+    137,107,  2,208,135,208,159,225,244,225,235,225,238, 97,129, 48,+    232,208,147,232,225,236,230,247,233,228,244,104,128,255,150,239,+    242,229,225,110,128, 49, 91,243,237,225,236,108,  2,208,177,208,+    188,232,233,242,225,231,225,238, 97,128, 48,135,235,225,244,225,+    235,225,238, 97,129, 48,231,208,201,232,225,236,230,247,233,228,+    244,104,128,255,110,244,231,242,229,229,107,128,  3,243,121,  2,+    208,228,209,  9, 97,  2,208,234,208,244,229,235,239,242,229,225,+    110,128, 49,136,107,  2,208,250,209,  2,239,242,229,225,110,128,+     49,135,244,232,225,105,128, 14, 34,233,238,231,244,232,225,105,+    128, 14, 13,112,  2,209, 25,209, 32,225,242,229,110,128, 36,180,+    239,231,229,231,242,225,237,237,229,238,105,129,  3,122,209, 48,+    231,242,229,229,235,227,237, 98,128,  3, 69,114,129,  1,166,209,+     65,233,238,103,128, 30,153,243,245,240,229,242,233,239,114,128,+      2,184,116,  2,209, 88,209, 95,233,236,228,101,128, 30,249,245,+    242,238,229,100,128,  2,142,117,  5,209,115,209,126,209,136,209,+    174,210, 50,232,233,242,225,231,225,238, 97,128, 48,134,233,235,+    239,242,229,225,110,128, 49,140,107,  2,209,142,209,166,225,244,+    225,235,225,238, 97,129, 48,230,209,154,232,225,236,230,247,233,+    228,244,104,128,255,149,239,242,229,225,110,128, 49, 96,115,  3,+    209,182,209,220,210,  5,226,233,103,  2,209,190,209,201,227,249,+    242,233,236,236,233, 99,128,  4,107,233,239,244,233,230,233,229,+    228,227,249,242,233,236,236,233, 99,128,  4,109,236,233,244,244,+    236,101,  2,209,231,209,242,227,249,242,233,236,236,233, 99,128,+      4,103,233,239,244,233,230,233,229,228,227,249,242,233,236,236,+    233, 99,128,  4,105,237,225,236,108,  2,210, 14,210, 25,232,233,+    242,225,231,225,238, 97,128, 48,133,235,225,244,225,235,225,238,+     97,129, 48,229,210, 38,232,225,236,230,247,233,228,244,104,128,+    255,109,249,101,  2,210, 57,210, 66,235,239,242,229,225,110,128,+     49,139,239,235,239,242,229,225,110,128, 49,138,249, 97,  2,210,+     83,210, 93,226,229,238,231,225,236,105,128,  9,223,228,229,246,+     97,128,  9, 95,122,142,  0,122,210,132,211,140,211,151,211,194,+    211,221,213,  0,213,108,213,150,213,162,213,174,213,202,213,210,+    213,226,213,235, 97, 10,210,154,210,165,210,172,210,179,210,190,+    211, 12,211, 42,211, 53,211, 89,211,101,225,242,237,229,238,233,+    225,110,128,  5,102,227,245,244,101,128,  1,122,228,229,246, 97,+    128,  9, 91,231,245,242,237,245,235,232,105,128, 10, 91,104,  4,+    210,200,210,209,210,223,210,253,225,242,225,226,233, 99,128,  6,+     56,230,233,238,225,236,225,242,225,226,233, 99,128,254,198,105,+      2,210,229,210,244,238,233,244,233,225,236,225,242,225,226,233,+     99,128,254,199,242,225,231,225,238, 97,128, 48, 86,237,229,228,+    233,225,236,225,242,225,226,233, 99,128,254,200,233,110,  2,211,+     19,211, 28,225,242,225,226,233, 99,128,  6, 50,230,233,238,225,+    236,225,242,225,226,233, 99,128,254,176,235,225,244,225,235,225,+    238, 97,128, 48,182,241,229,102,  2,211, 61,211, 75,231,225,228,+    239,236,232,229,226,242,229,119,128,  5,149,241,225,244,225,238,+    232,229,226,242,229,119,128,  5,148,242,241,225,232,229,226,242,+    229,119,128,  5,152,249,233,110,130,  5,214,211,111,211,131,228,+    225,231,229,243,104,129,251, 54,211,122,232,229,226,242,229,119,+    128,251, 54,232,229,226,242,229,119,128,  5,214,226,239,240,239,+    237,239,230,111,128, 49, 23, 99,  3,211,159,211,166,211,188,225,+    242,239,110,128,  1,126,233,242, 99,  2,211,174,211,179,236,101,+    128, 36,233,245,237,230,236,229,120,128, 30,145,245,242,108,128,+      2,145,228,239,116,130,  1,124,211,204,211,213,225,227,227,229,+    238,116,128,  1,124,226,229,236,239,119,128, 30,147,101,  6,211,+    235,211,246,212, 33,212, 44,212, 55,212,251,227,249,242,233,236,+    236,233, 99,128,  4, 55,100,  2,211,252,212, 15,229,243,227,229,+    238,228,229,242,227,249,242,233,236,236,233, 99,128,  4,153,233,+    229,242,229,243,233,243,227,249,242,233,236,236,233, 99,128,  4,+    223,232,233,242,225,231,225,238, 97,128, 48, 92,235,225,244,225,+    235,225,238, 97,128, 48,188,242,111,140,  0, 48,212, 84,212, 93,+    212,103,212,110,212,135,212,148,212,159,212,171,212,182,212,192,+    212,203,212,210,225,242,225,226,233, 99,128,  6, 96,226,229,238,+    231,225,236,105,128,  9,230,228,229,246, 97,128,  9,102,231,117,+      2,212,117,212,126,234,225,242,225,244,105,128, 10,230,242,237,+    245,235,232,105,128, 10,102,232,225,227,235,225,242,225,226,233,+     99,128,  6, 96,233,238,230,229,242,233,239,114,128, 32,128,237,+    239,238,239,243,240,225,227,101,128,255, 16,239,236,228,243,244,+    249,236,101,128,247, 48,240,229,242,243,233,225,110,128,  6,240,+    243,245,240,229,242,233,239,114,128, 32,112,244,232,225,105,128,+     14, 80,247,233,228,244,104,  3,212,222,212,231,212,243,234,239,+    233,238,229,114,128,254,255,238,239,238,234,239,233,238,229,114,+    128, 32, 12,243,240,225,227,101,128, 32, 11,244, 97,128,  3,182,+    104,  2,213,  6,213, 17,226,239,240,239,237,239,230,111,128, 49,+     19,101,  4,213, 27,213, 38,213, 54,213, 65,225,242,237,229,238,+    233,225,110,128,  5,106,226,242,229,246,229,227,249,242,233,236,+    236,233, 99,128,  4,194,227,249,242,233,236,236,233, 99,128,  4,+     54,100,  2,213, 71,213, 90,229,243,227,229,238,228,229,242,227,+    249,242,233,236,236,233, 99,128,  4,151,233,229,242,229,243,233,+    243,227,249,242,233,236,236,233, 99,128,  4,221,105,  3,213,116,+    213,127,213,138,232,233,242,225,231,225,238, 97,128, 48, 88,235,+    225,244,225,235,225,238, 97,128, 48,184,238,239,242,232,229,226,+    242,229,119,128,  5,174,236,233,238,229,226,229,236,239,119,128,+     30,149,237,239,238,239,243,240,225,227,101,128,255, 90,111,  2,+    213,180,213,191,232,233,242,225,231,225,238, 97,128, 48, 94,235,+    225,244,225,235,225,238, 97,128, 48,190,240,225,242,229,110,128,+     36,181,242,229,244,242,239,230,236,229,248,232,239,239,107,128,+      2,144,243,244,242,239,235,101,128,  1,182,117,  2,213,241,213,+    252,232,233,242,225,231,225,238, 97,128, 48, 90,235,225,244,225,+    235,225,238, 97,128, 48,186+  };+++  /*+   *  This function searches the compressed table efficiently.+   */+  static unsigned long+  ft_get_adobe_glyph_index( const char*  name,+                            const char*  limit )+  {+    int                   c = 0;+    int                   count, min, max;+    const unsigned char*  p = ft_adobe_glyph_list;+++    if ( name == 0 || name >= limit )+      goto NotFound;++    c     = *name++;+    count = p[1];+    p    += 2;++    min = 0;+    max = count;++    while ( min < max )+    {+      int                   mid = ( min + max ) >> 1;+      const unsigned char*  q   = p + mid * 2;+      int                   c2;+++      q = ft_adobe_glyph_list + ( ( (int)q[0] << 8 ) | q[1] );++      c2 = q[0] & 127;+      if ( c2 == c )+      {+        p = q;+        goto Found;+      }+      if ( c2 < c )+        min = mid + 1;+      else+        max = mid;+    }+    goto NotFound;++  Found:+    for (;;)+    {+      /* assert (*p & 127) == c */++      if ( name >= limit )+      {+        if ( (p[0] & 128) == 0 &&+             (p[1] & 128) != 0 )+          return (unsigned long)( ( (int)p[2] << 8 ) | p[3] );++        goto NotFound;+      }+      c = *name++;+      if ( p[0] & 128 )+      {+        p++;+        if ( c != (p[0] & 127) )+          goto NotFound;++        continue;+      }++      p++;+      count = p[0] & 127;+      if ( p[0] & 128 )+        p += 2;++      p++;++      for ( ; count > 0; count--, p += 2 )+      {+        int                   offset = ( (int)p[0] << 8 ) | p[1];+        const unsigned char*  q      = ft_adobe_glyph_list + offset;++        if ( c == ( q[0] & 127 ) )+        {+          p = q;+          goto NextIter;+        }+      }+      goto NotFound;++    NextIter:+      ;+    }++  NotFound:+    return 0;+  }++#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */+++/* END */
+ src/raster/ftmisc.h view
@@ -0,0 +1,121 @@+/***************************************************************************/+/*                                                                         */+/*  ftmisc.h                                                               */+/*                                                                         */+/*    Miscellaneous macros for stand-alone rasterizer (specification       */+/*    only).                                                               */+/*                                                                         */+/*  Copyright 2005, 2009, 2010 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used        */+/*  modified and distributed under the terms of the FreeType project       */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /***************************************************/+  /*                                                 */+  /* This file is *not* portable!  You have to adapt */+  /* its definitions to your platform.               */+  /*                                                 */+  /***************************************************/++#ifndef __FTMISC_H__+#define __FTMISC_H__+++  /* memset */+#include FT_CONFIG_STANDARD_LIBRARY_H++#define FT_BEGIN_HEADER+#define FT_END_HEADER++#define FT_LOCAL_DEF( x )   static x+++  /* from include/freetype2/fttypes.h */++  typedef unsigned char  FT_Byte;+  typedef signed int     FT_Int;+  typedef unsigned int   FT_UInt;+  typedef signed long    FT_Long;+  typedef unsigned long  FT_ULong;+  typedef signed long    FT_F26Dot6;+  typedef int            FT_Error;++#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \+          ( ( (FT_ULong)_x1 << 24 ) |     \+            ( (FT_ULong)_x2 << 16 ) |     \+            ( (FT_ULong)_x3 <<  8 ) |     \+              (FT_ULong)_x4         )+++  /* from include/freetype2/ftsystem.h */++  typedef struct FT_MemoryRec_*  FT_Memory;++  typedef void* (*FT_Alloc_Func)( FT_Memory  memory,+                                  long       size );++  typedef void (*FT_Free_Func)( FT_Memory  memory,+                                void*      block );++  typedef void* (*FT_Realloc_Func)( FT_Memory  memory,+                                    long       cur_size,+                                    long       new_size,+                                    void*      block );++  typedef struct FT_MemoryRec_+  {+    void*            user;++    FT_Alloc_Func    alloc;+    FT_Free_Func     free;+    FT_Realloc_Func  realloc;++  } FT_MemoryRec;+++  /* from src/ftcalc.c */++#if ( defined _WIN32 || defined _WIN64 )++  typedef __int64  FT_Int64;++#else++#include "inttypes.h"++  typedef int64_t  FT_Int64;++#endif+++  static FT_Long+  FT_MulDiv( FT_Long  a,+             FT_Long  b,+             FT_Long  c )+  {+    FT_Int   s;+    FT_Long  d;+++    s = 1;+    if ( a < 0 ) { a = -a; s = -1; }+    if ( b < 0 ) { b = -b; s = -s; }+    if ( c < 0 ) { c = -c; s = -s; }++    d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c+                         : 0x7FFFFFFFL );++    return ( s > 0 ) ? d : -d;+  }++#endif /* __FTMISC_H__ */+++/* END */
+ src/raster/ftraster.c view
@@ -0,0 +1,3563 @@+/***************************************************************************/+/*                                                                         */+/*  ftraster.c                                                             */+/*                                                                         */+/*    The FreeType glyph rasterizer (body).                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* This file can be compiled without the rest of the FreeType engine, by */+  /* defining the _STANDALONE_ macro when compiling it.  You also need to  */+  /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir)           */+  /* directory.  Typically, you should do something like                   */+  /*                                                                       */+  /* - copy `src/raster/ftraster.c' (this file) to your current directory  */+  /*                                                                       */+  /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h'         */+  /*   to your current directory                                           */+  /*                                                                       */+  /* - compile `ftraster' with the _STANDALONE_ macro defined, as in       */+  /*                                                                       */+  /*     cc -c -D_STANDALONE_ ftraster.c                                   */+  /*                                                                       */+  /* The renderer can be initialized with a call to                        */+  /* `ft_standard_raster.raster_new'; a bitmap can be generated            */+  /* with a call to `ft_standard_raster.raster_render'.                    */+  /*                                                                       */+  /* See the comments and documentation in the file `ftimage.h' for more   */+  /* details on how the raster works.                                      */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This is a rewrite of the FreeType 1.x scan-line converter             */+  /*                                                                       */+  /*************************************************************************/++#ifdef _STANDALONE_++#define FT_CONFIG_STANDARD_LIBRARY_H  <stdlib.h>++#include <string.h>           /* for memset */++#include "ftmisc.h"+#include "ftimage.h"++#else /* !_STANDALONE_ */++#include <ft2build.h>+#include "ftraster.h"+#include FT_INTERNAL_CALC_H   /* for FT_MulDiv only */++#include "rastpic.h"++#endif /* !_STANDALONE_ */+++  /*************************************************************************/+  /*                                                                       */+  /* A simple technical note on how the raster works                       */+  /* -----------------------------------------------                       */+  /*                                                                       */+  /*   Converting an outline into a bitmap is achieved in several steps:   */+  /*                                                                       */+  /*   1 - Decomposing the outline into successive `profiles'.  Each       */+  /*       profile is simply an array of scanline intersections on a given */+  /*       dimension.  A profile's main attributes are                     */+  /*                                                                       */+  /*       o its scanline position boundaries, i.e. `Ymin' and `Ymax'      */+  /*                                                                       */+  /*       o an array of intersection coordinates for each scanline        */+  /*         between `Ymin' and `Ymax'                                     */+  /*                                                                       */+  /*       o a direction, indicating whether it was built going `up' or    */+  /*         `down', as this is very important for filling rules           */+  /*                                                                       */+  /*       o its drop-out mode                                             */+  /*                                                                       */+  /*   2 - Sweeping the target map's scanlines in order to compute segment */+  /*       `spans' which are then filled.  Additionally, this pass         */+  /*       performs drop-out control.                                      */+  /*                                                                       */+  /*   The outline data is parsed during step 1 only.  The profiles are    */+  /*   built from the bottom of the render pool, used as a stack.  The     */+  /*   following graphics shows the profile list under construction:       */+  /*                                                                       */+  /*     __________________________________________________________ _ _    */+  /*    |         |                 |         |                 |          */+  /*    | profile | coordinates for | profile | coordinates for |-->       */+  /*    |    1    |  profile 1      |    2    |  profile 2      |-->       */+  /*    |_________|_________________|_________|_________________|__ _ _    */+  /*                                                                       */+  /*    ^                                                       ^          */+  /*    |                                                       |          */+  /* start of render pool                                      top         */+  /*                                                                       */+  /*   The top of the profile stack is kept in the `top' variable.         */+  /*                                                                       */+  /*   As you can see, a profile record is pushed on top of the render     */+  /*   pool, which is then followed by its coordinates/intersections.  If  */+  /*   a change of direction is detected in the outline, a new profile is  */+  /*   generated until the end of the outline.                             */+  /*                                                                       */+  /*   Note that when all profiles have been generated, the function       */+  /*   Finalize_Profile_Table() is used to record, for each profile, its   */+  /*   bottom-most scanline as well as the scanline above its upmost       */+  /*   boundary.  These positions are called `y-turns' because they (sort  */+  /*   of) correspond to local extrema.  They are stored in a sorted list  */+  /*   built from the top of the render pool as a downwards stack:         */+  /*                                                                       */+  /*      _ _ _______________________________________                      */+  /*                            |                    |                     */+  /*                         <--| sorted list of     |                     */+  /*                         <--|  extrema scanlines |                     */+  /*      _ _ __________________|____________________|                     */+  /*                                                                       */+  /*                            ^                    ^                     */+  /*                            |                    |                     */+  /*                         maxBuff           sizeBuff = end of pool      */+  /*                                                                       */+  /*   This list is later used during the sweep phase in order to          */+  /*   optimize performance (see technical note on the sweep below).       */+  /*                                                                       */+  /*   Of course, the raster detects whether the two stacks collide and    */+  /*   handles the situation properly.                                     */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*************************************************************************/+  /**                                                                     **/+  /**  CONFIGURATION MACROS                                               **/+  /**                                                                     **/+  /*************************************************************************/+  /*************************************************************************/++  /* define DEBUG_RASTER if you want to compile a debugging version */+/* #define DEBUG_RASTER */++  /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */+  /* 5-levels anti-aliasing                                       */+/* #define FT_RASTER_OPTION_ANTI_ALIASING */++  /* The size of the two-lines intermediate bitmap used */+  /* for anti-aliasing, in bytes.                       */+#define RASTER_GRAY_LINES  2048+++  /*************************************************************************/+  /*************************************************************************/+  /**                                                                     **/+  /**  OTHER MACROS (do not change)                                       **/+  /**                                                                     **/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_raster+++#ifdef _STANDALONE_+++  /* This macro is used to indicate that a function parameter is unused. */+  /* Its purpose is simply to reduce compiler warnings.  Note also that  */+  /* simply defining it as `(void)x' doesn't avoid warnings with certain */+  /* ANSI compilers (e.g. LCC).                                          */+#define FT_UNUSED( x )  (x) = (x)++  /* Disable the tracing mechanism for simplicity -- developers can      */+  /* activate it easily by redefining these two macros.                  */+#ifndef FT_ERROR+#define FT_ERROR( x )  do { } while ( 0 )     /* nothing */+#endif++#ifndef FT_TRACE+#define FT_TRACE( x )   do { } while ( 0 )    /* nothing */+#define FT_TRACE1( x )  do { } while ( 0 )    /* nothing */+#define FT_TRACE6( x )  do { } while ( 0 )    /* nothing */+#endif++#define Raster_Err_None          0+#define Raster_Err_Not_Ini      -1+#define Raster_Err_Overflow     -2+#define Raster_Err_Neg_Height   -3+#define Raster_Err_Invalid      -4+#define Raster_Err_Unsupported  -5++#define ft_memset  memset++#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \+                                raster_reset_, raster_set_mode_,    \+                                raster_render_, raster_done_ )      \+          const FT_Raster_Funcs class_ =                            \+          {                                                         \+            glyph_format_,                                          \+            raster_new_,                                            \+            raster_reset_,                                          \+            raster_set_mode_,                                       \+            raster_render_,                                         \+            raster_done_                                            \+         };++#else /* !_STANDALONE_ */+++#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H        /* for FT_TRACE() and FT_ERROR() */++#include "rasterrs.h"++#define Raster_Err_None         Raster_Err_Ok+#define Raster_Err_Not_Ini      Raster_Err_Raster_Uninitialized+#define Raster_Err_Overflow     Raster_Err_Raster_Overflow+#define Raster_Err_Neg_Height   Raster_Err_Raster_Negative_Height+#define Raster_Err_Invalid      Raster_Err_Invalid_Outline+#define Raster_Err_Unsupported  Raster_Err_Cannot_Render_Glyph+++#endif /* !_STANDALONE_ */+++#ifndef FT_MEM_SET+#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )+#endif++#ifndef FT_MEM_ZERO+#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )+#endif++  /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is       */+  /* typically a small value and the result of a*b is known to fit into */+  /* 32 bits.                                                           */+#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )++  /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */+  /* for clipping computations.  It simply uses the FT_MulDiv() function   */+  /* defined in `ftcalc.h'.                                                */+#define SMulDiv  FT_MulDiv++  /* The rasterizer is a very general purpose component; please leave */+  /* the following redefinitions there (you never know your target    */+  /* environment).                                                    */++#ifndef TRUE+#define TRUE   1+#endif++#ifndef FALSE+#define FALSE  0+#endif++#ifndef NULL+#define NULL  (void*)0+#endif++#ifndef SUCCESS+#define SUCCESS  0+#endif++#ifndef FAILURE+#define FAILURE  1+#endif+++#define MaxBezier  32   /* The maximum number of stacked Bezier curves. */+                        /* Setting this constant to more than 32 is a   */+                        /* pure waste of space.                         */++#define Pixel_Bits  6   /* fractional bits of *input* coordinates */+++  /*************************************************************************/+  /*************************************************************************/+  /**                                                                     **/+  /**  SIMPLE TYPE DECLARATIONS                                           **/+  /**                                                                     **/+  /*************************************************************************/+  /*************************************************************************/++  typedef int             Int;+  typedef unsigned int    UInt;+  typedef short           Short;+  typedef unsigned short  UShort, *PUShort;+  typedef long            Long, *PLong;++  typedef unsigned char   Byte, *PByte;+  typedef char            Bool;+++  typedef union  Alignment_+  {+    long    l;+    void*   p;+    void  (*f)(void);++  } Alignment, *PAlignment;+++  typedef struct  TPoint_+  {+    Long  x;+    Long  y;++  } TPoint;+++  /* values for the `flags' bit field */+#define Flow_Up           0x8+#define Overshoot_Top     0x10+#define Overshoot_Bottom  0x20+++  /* States of each line, arc, and profile */+  typedef enum  TStates_+  {+    Unknown_State,+    Ascending_State,+    Descending_State,+    Flat_State++  } TStates;+++  typedef struct TProfile_  TProfile;+  typedef TProfile*         PProfile;++  struct  TProfile_+  {+    FT_F26Dot6  X;           /* current coordinate during sweep          */+    PProfile    link;        /* link to next profile (various purposes)  */+    PLong       offset;      /* start of profile's data in render pool   */+    unsigned    flags;       /* Bit 0-2: drop-out mode                   */+                             /* Bit 3: profile orientation (up/down)     */+                             /* Bit 4: is top profile?                   */+                             /* Bit 5: is bottom profile?                */+    long        height;      /* profile's height in scanlines            */+    long        start;       /* profile's starting scanline              */++    unsigned    countL;      /* number of lines to step before this      */+                             /* profile becomes drawable                 */++    PProfile    next;        /* next profile in same contour, used       */+                             /* during drop-out control                  */+  };++  typedef PProfile   TProfileList;+  typedef PProfile*  PProfileList;+++  /* Simple record used to implement a stack of bands, required */+  /* by the sub-banding mechanism                               */+  typedef struct  TBand_+  {+    Short  y_min;   /* band's minimum */+    Short  y_max;   /* band's maximum */++  } TBand;+++#define AlignProfileSize \+  ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) )+++#ifdef FT_STATIC_RASTER+++#define RAS_ARGS       /* void */+#define RAS_ARG        /* void */++#define RAS_VARS       /* void */+#define RAS_VAR        /* void */++#define FT_UNUSED_RASTER  do { } while ( 0 )+++#else /* !FT_STATIC_RASTER */+++#define RAS_ARGS       PWorker    worker,+#define RAS_ARG        PWorker    worker++#define RAS_VARS       worker,+#define RAS_VAR        worker++#define FT_UNUSED_RASTER  FT_UNUSED( worker )+++#endif /* !FT_STATIC_RASTER */+++  typedef struct TWorker_  TWorker, *PWorker;+++  /* prototypes used for sweep function dispatch */+  typedef void+  Function_Sweep_Init( RAS_ARGS Short*  min,+                                Short*  max );++  typedef void+  Function_Sweep_Span( RAS_ARGS Short       y,+                                FT_F26Dot6  x1,+                                FT_F26Dot6  x2,+                                PProfile    left,+                                PProfile    right );++  typedef void+  Function_Sweep_Step( RAS_ARG );+++  /* NOTE: These operations are only valid on 2's complement processors */++#define FLOOR( x )    ( (x) & -ras.precision )+#define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )+#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )+#define FRAC( x )     ( (x) & ( ras.precision - 1 ) )+#define SCALED( x )   ( ( (x) << ras.scale_shift ) - ras.precision_half )++#define IS_BOTTOM_OVERSHOOT( x )  ( CEILING( x ) - x >= ras.precision_half )+#define IS_TOP_OVERSHOOT( x )     ( x - FLOOR( x ) >= ras.precision_half )++  /* The most used variables are positioned at the top of the structure. */+  /* Thus, their offset can be coded with less opcodes, resulting in a   */+  /* smaller executable.                                                 */++  struct  TWorker_+  {+    Int         precision_bits;     /* precision related variables         */+    Int         precision;+    Int         precision_half;+    Int         precision_shift;+    Int         precision_step;+    Int         precision_jitter;++    Int         scale_shift;        /* == precision_shift   for bitmaps    */+                                    /* == precision_shift+1 for pixmaps    */++    PLong       buff;               /* The profiles buffer                 */+    PLong       sizeBuff;           /* Render pool size                    */+    PLong       maxBuff;            /* Profiles buffer size                */+    PLong       top;                /* Current cursor in buffer            */++    FT_Error    error;++    Int         numTurns;           /* number of Y-turns in outline        */++    TPoint*     arc;                /* current Bezier arc pointer          */++    UShort      bWidth;             /* target bitmap width                 */+    PByte       bTarget;            /* target bitmap buffer                */+    PByte       gTarget;            /* target pixmap buffer                */++    Long        lastX, lastY;+    Long        minY, maxY;++    UShort      num_Profs;          /* current number of profiles          */++    Bool        fresh;              /* signals a fresh new profile which   */+                                    /* `start' field must be completed     */+    Bool        joint;              /* signals that the last arc ended     */+                                    /* exactly on a scanline.  Allows      */+                                    /* removal of doublets                 */+    PProfile    cProfile;           /* current profile                     */+    PProfile    fProfile;           /* head of linked list of profiles     */+    PProfile    gProfile;           /* contour's first profile in case     */+                                    /* of impact                           */++    TStates     state;              /* rendering state                     */++    FT_Bitmap   target;             /* description of target bit/pixmap    */+    FT_Outline  outline;++    Long        traceOfs;           /* current offset in target bitmap     */+    Long        traceG;             /* current offset in target pixmap     */++    Short       traceIncr;          /* sweep's increment in target bitmap  */++    Short       gray_min_x;         /* current min x during gray rendering */+    Short       gray_max_x;         /* current max x during gray rendering */++    /* dispatch variables */++    Function_Sweep_Init*  Proc_Sweep_Init;+    Function_Sweep_Span*  Proc_Sweep_Span;+    Function_Sweep_Span*  Proc_Sweep_Drop;+    Function_Sweep_Step*  Proc_Sweep_Step;++    Byte        dropOutControl;     /* current drop_out control method     */++    Bool        second_pass;        /* indicates whether a horizontal pass */+                                    /* should be performed to control      */+                                    /* drop-out accurately when calling    */+                                    /* Render_Glyph.  Note that there is   */+                                    /* no horizontal pass during gray      */+                                    /* rendering.                          */++    TPoint      arcs[3 * MaxBezier + 1]; /* The Bezier stack               */++    TBand       band_stack[16];     /* band stack used for sub-banding     */+    Int         band_top;           /* band stack top                      */++#ifdef FT_RASTER_OPTION_ANTI_ALIASING++    Byte*       grays;++    Byte        gray_lines[RASTER_GRAY_LINES];+                                /* Intermediate table used to render the   */+                                /* graylevels pixmaps.                     */+                                /* gray_lines is a buffer holding two      */+                                /* monochrome scanlines                    */++    Short       gray_width;     /* width in bytes of one monochrome        */+                                /* intermediate scanline of gray_lines.    */+                                /* Each gray pixel takes 2 bits long there */++                       /* The gray_lines must hold 2 lines, thus with size */+                       /* in bytes of at least `gray_width*2'.             */++#endif /* FT_RASTER_ANTI_ALIASING */++  };+++  typedef struct  TRaster_+  {+    char*    buffer;+    long     buffer_size;+    void*    memory;+    PWorker  worker;+    Byte     grays[5];+    Short    gray_width;++  } TRaster, *PRaster;++#ifdef FT_STATIC_RASTER++  static TWorker  cur_ras;+#define ras  cur_ras++#else /* !FT_STATIC_RASTER */++#define ras  (*worker)++#endif /* !FT_STATIC_RASTER */+++#ifdef FT_RASTER_OPTION_ANTI_ALIASING++  /* A lookup table used to quickly count set bits in four gray 2x2 */+  /* cells.  The values of the table have been produced with the    */+  /* following code:                                                */+  /*                                                                */+  /*   for ( i = 0; i < 256; i++ )                                  */+  /*   {                                                            */+  /*     l = 0;                                                     */+  /*     j = i;                                                     */+  /*                                                                */+  /*     for ( c = 0; c < 4; c++ )                                  */+  /*     {                                                          */+  /*       l <<= 4;                                                 */+  /*                                                                */+  /*       if ( j & 0x80 ) l++;                                     */+  /*       if ( j & 0x40 ) l++;                                     */+  /*                                                                */+  /*       j = ( j << 2 ) & 0xFF;                                   */+  /*     }                                                          */+  /*     printf( "0x%04X", l );                                     */+  /*   }                                                            */+  /*                                                                */++  static const short  count_table[256] =+  {+    0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,+    0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,+    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,+    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,+    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,+    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,+    0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,+    0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,+    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,+    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,+    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,+    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,+    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,+    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,+    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,+    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,+    0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,+    0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,+    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,+    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,+    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,+    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,+    0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,+    0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222+  };++#endif /* FT_RASTER_OPTION_ANTI_ALIASING */++++  /*************************************************************************/+  /*************************************************************************/+  /**                                                                     **/+  /**  PROFILES COMPUTATION                                               **/+  /**                                                                     **/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Set_High_Precision                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Set precision variables according to param flag.                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    High :: Set to True for high precision (typically for ppem < 18),  */+  /*            false otherwise.                                           */+  /*                                                                       */+  static void+  Set_High_Precision( RAS_ARGS Int  High )+  {+    if ( High )+    {+      ras.precision_bits   = 12;+      ras.precision_step   = 256;+      ras.precision_jitter = 50;+    }+    else+    {+      ras.precision_bits   = 6;+      ras.precision_step   = 32;+      ras.precision_jitter = 2;+    }++    FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));++    ras.precision       = 1 << ras.precision_bits;+    ras.precision_half  = ras.precision / 2;+    ras.precision_shift = ras.precision_bits - Pixel_Bits;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    New_Profile                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Create a new profile in the render pool.                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    aState    :: The state/orientation of the new profile.             */+  /*                                                                       */+  /*    overshoot :: Whether the profile's unrounded start position        */+  /*                 differs by at least a half pixel.                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*   SUCCESS on success.  FAILURE in case of overflow or of incoherent   */+  /*   profile.                                                            */+  /*                                                                       */+  static Bool+  New_Profile( RAS_ARGS TStates  aState,+                        Bool     overshoot )+  {+    if ( !ras.fProfile )+    {+      ras.cProfile  = (PProfile)ras.top;+      ras.fProfile  = ras.cProfile;+      ras.top      += AlignProfileSize;+    }++    if ( ras.top >= ras.maxBuff )+    {+      ras.error = Raster_Err_Overflow;+      return FAILURE;+    }++    ras.cProfile->flags  = 0;+    ras.cProfile->start  = 0;+    ras.cProfile->height = 0;+    ras.cProfile->offset = ras.top;+    ras.cProfile->link   = (PProfile)0;+    ras.cProfile->next   = (PProfile)0;+    ras.cProfile->flags  = ras.dropOutControl;++    switch ( aState )+    {+    case Ascending_State:+      ras.cProfile->flags |= Flow_Up;+      if ( overshoot )+        ras.cProfile->flags |= Overshoot_Bottom;++      FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile ));+      break;++    case Descending_State:+      if ( overshoot )+        ras.cProfile->flags |= Overshoot_Top;+      FT_TRACE6(( "New descending profile = %p\n", ras.cProfile ));+      break;++    default:+      FT_ERROR(( "New_Profile: invalid profile direction\n" ));+      ras.error = Raster_Err_Invalid;+      return FAILURE;+    }++    if ( !ras.gProfile )+      ras.gProfile = ras.cProfile;++    ras.state = aState;+    ras.fresh = TRUE;+    ras.joint = FALSE;++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    End_Profile                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalize the current profile.                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    overshoot :: Whether the profile's unrounded end position differs  */+  /*                 by at least a half pixel.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success.  FAILURE in case of overflow or incoherency.   */+  /*                                                                       */+  static Bool+  End_Profile( RAS_ARGS Bool  overshoot )+  {+    Long      h;+    PProfile  oldProfile;+++    h = (Long)( ras.top - ras.cProfile->offset );++    if ( h < 0 )+    {+      FT_ERROR(( "End_Profile: negative height encountered\n" ));+      ras.error = Raster_Err_Neg_Height;+      return FAILURE;+    }++    if ( h > 0 )+    {+      FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n",+                  ras.cProfile, ras.cProfile->start, h ));++      ras.cProfile->height = h;+      if ( overshoot )+      {+        if ( ras.cProfile->flags & Flow_Up )+          ras.cProfile->flags |= Overshoot_Top;+        else+          ras.cProfile->flags |= Overshoot_Bottom;+      }++      oldProfile   = ras.cProfile;+      ras.cProfile = (PProfile)ras.top;++      ras.top += AlignProfileSize;++      ras.cProfile->height = 0;+      ras.cProfile->offset = ras.top;++      oldProfile->next = ras.cProfile;+      ras.num_Profs++;+    }++    if ( ras.top >= ras.maxBuff )+    {+      FT_TRACE1(( "overflow in End_Profile\n" ));+      ras.error = Raster_Err_Overflow;+      return FAILURE;+    }++    ras.joint = FALSE;++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Insert_Y_Turn                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Insert a salient into the sorted list placed on top of the render  */+  /*    pool.                                                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    New y scanline position.                                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success.  FAILURE in case of overflow.                  */+  /*                                                                       */+  static Bool+  Insert_Y_Turn( RAS_ARGS Int  y )+  {+    PLong  y_turns;+    Int    y2, n;+++    n       = ras.numTurns - 1;+    y_turns = ras.sizeBuff - ras.numTurns;++    /* look for first y value that is <= */+    while ( n >= 0 && y < y_turns[n] )+      n--;++    /* if it is <, simply insert it, ignore if == */+    if ( n >= 0 && y > y_turns[n] )+      while ( n >= 0 )+      {+        y2 = (Int)y_turns[n];+        y_turns[n] = y;+        y = y2;+        n--;+      }++    if ( n < 0 )+    {+      ras.maxBuff--;+      if ( ras.maxBuff <= ras.top )+      {+        ras.error = Raster_Err_Overflow;+        return FAILURE;+      }+      ras.numTurns++;+      ras.sizeBuff[-ras.numTurns] = y;+    }++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Finalize_Profile_Table                                             */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Adjust all links in the profiles list.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success.  FAILURE in case of overflow.                  */+  /*                                                                       */+  static Bool+  Finalize_Profile_Table( RAS_ARG )+  {+    Int       bottom, top;+    UShort    n;+    PProfile  p;+++    n = ras.num_Profs;+    p = ras.fProfile;++    if ( n > 1 && p )+    {+      while ( n > 0 )+      {+        if ( n > 1 )+          p->link = (PProfile)( p->offset + p->height );+        else+          p->link = NULL;++        if ( p->flags & Flow_Up )+        {+          bottom = (Int)p->start;+          top    = (Int)( p->start + p->height - 1 );+        }+        else+        {+          bottom     = (Int)( p->start - p->height + 1 );+          top        = (Int)p->start;+          p->start   = bottom;+          p->offset += p->height - 1;+        }++        if ( Insert_Y_Turn( RAS_VARS bottom )  ||+             Insert_Y_Turn( RAS_VARS top + 1 ) )+          return FAILURE;++        p = p->link;+        n--;+      }+    }+    else+      ras.fProfile = NULL;++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Split_Conic                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Subdivide one conic Bezier into two joint sub-arcs in the Bezier   */+  /*    stack.                                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    None (subdivided Bezier is taken from the top of the stack).       */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This routine is the `beef' of this component.  It is  _the_ inner  */+  /*    loop that should be optimized to hell to get the best performance. */+  /*                                                                       */+  static void+  Split_Conic( TPoint*  base )+  {+    Long  a, b;+++    base[4].x = base[2].x;+    b = base[1].x;+    a = base[3].x = ( base[2].x + b ) / 2;+    b = base[1].x = ( base[0].x + b ) / 2;+    base[2].x = ( a + b ) / 2;++    base[4].y = base[2].y;+    b = base[1].y;+    a = base[3].y = ( base[2].y + b ) / 2;+    b = base[1].y = ( base[0].y + b ) / 2;+    base[2].y = ( a + b ) / 2;++    /* hand optimized.  gcc doesn't seem to be too good at common      */+    /* expression substitution and instruction scheduling ;-)          */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Split_Cubic                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Subdivide a third-order Bezier arc into two joint sub-arcs in the  */+  /*    Bezier stack.                                                      */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This routine is the `beef' of the component.  It is one of _the_   */+  /*    inner loops that should be optimized like hell to get the best     */+  /*    performance.                                                       */+  /*                                                                       */+  static void+  Split_Cubic( TPoint*  base )+  {+    Long  a, b, c, d;+++    base[6].x = base[3].x;+    c = base[1].x;+    d = base[2].x;+    base[1].x = a = ( base[0].x + c + 1 ) >> 1;+    base[5].x = b = ( base[3].x + d + 1 ) >> 1;+    c = ( c + d + 1 ) >> 1;+    base[2].x = a = ( a + c + 1 ) >> 1;+    base[4].x = b = ( b + c + 1 ) >> 1;+    base[3].x = ( a + b + 1 ) >> 1;++    base[6].y = base[3].y;+    c = base[1].y;+    d = base[2].y;+    base[1].y = a = ( base[0].y + c + 1 ) >> 1;+    base[5].y = b = ( base[3].y + d + 1 ) >> 1;+    c = ( c + d + 1 ) >> 1;+    base[2].y = a = ( a + c + 1 ) >> 1;+    base[4].y = b = ( b + c + 1 ) >> 1;+    base[3].y = ( a + b + 1 ) >> 1;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Line_Up                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Compute the x-coordinates of an ascending line segment and store   */+  /*    them in the render pool.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    x1   :: The x-coordinate of the segment's start point.             */+  /*                                                                       */+  /*    y1   :: The y-coordinate of the segment's start point.             */+  /*                                                                       */+  /*    x2   :: The x-coordinate of the segment's end point.               */+  /*                                                                       */+  /*    y2   :: The y-coordinate of the segment's end point.               */+  /*                                                                       */+  /*    miny :: A lower vertical clipping bound value.                     */+  /*                                                                       */+  /*    maxy :: An upper vertical clipping bound value.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE on render pool overflow.               */+  /*                                                                       */+  static Bool+  Line_Up( RAS_ARGS Long  x1,+                    Long  y1,+                    Long  x2,+                    Long  y2,+                    Long  miny,+                    Long  maxy )+  {+    Long   Dx, Dy;+    Int    e1, e2, f1, f2, size;     /* XXX: is `Short' sufficient? */+    Long   Ix, Rx, Ax;++    PLong  top;+++    Dx = x2 - x1;+    Dy = y2 - y1;++    if ( Dy <= 0 || y2 < miny || y1 > maxy )+      return SUCCESS;++    if ( y1 < miny )+    {+      /* Take care: miny-y1 can be a very large value; we use     */+      /*            a slow MulDiv function to avoid clipping bugs */+      x1 += SMulDiv( Dx, miny - y1, Dy );+      e1  = (Int)TRUNC( miny );+      f1  = 0;+    }+    else+    {+      e1 = (Int)TRUNC( y1 );+      f1 = (Int)FRAC( y1 );+    }++    if ( y2 > maxy )+    {+      /* x2 += FMulDiv( Dx, maxy - y2, Dy );  UNNECESSARY */+      e2  = (Int)TRUNC( maxy );+      f2  = 0;+    }+    else+    {+      e2 = (Int)TRUNC( y2 );+      f2 = (Int)FRAC( y2 );+    }++    if ( f1 > 0 )+    {+      if ( e1 == e2 )+        return SUCCESS;+      else+      {+        x1 += SMulDiv( Dx, ras.precision - f1, Dy );+        e1 += 1;+      }+    }+    else+      if ( ras.joint )+      {+        ras.top--;+        ras.joint = FALSE;+      }++    ras.joint = (char)( f2 == 0 );++    if ( ras.fresh )+    {+      ras.cProfile->start = e1;+      ras.fresh           = FALSE;+    }++    size = e2 - e1 + 1;+    if ( ras.top + size >= ras.maxBuff )+    {+      ras.error = Raster_Err_Overflow;+      return FAILURE;+    }++    if ( Dx > 0 )+    {+      Ix = SMulDiv( ras.precision, Dx, Dy);+      Rx = ( ras.precision * Dx ) % Dy;+      Dx = 1;+    }+    else+    {+      Ix = SMulDiv( ras.precision, -Dx, Dy) * -1;+      Rx =    ( ras.precision * -Dx ) % Dy;+      Dx = -1;+    }++    Ax  = -Dy;+    top = ras.top;++    while ( size > 0 )+    {+      *top++ = x1;++      x1 += Ix;+      Ax += Rx;+      if ( Ax >= 0 )+      {+        Ax -= Dy;+        x1 += Dx;+      }+      size--;+    }++    ras.top = top;+    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Line_Down                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Compute the x-coordinates of an descending line segment and store  */+  /*    them in the render pool.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    x1   :: The x-coordinate of the segment's start point.             */+  /*                                                                       */+  /*    y1   :: The y-coordinate of the segment's start point.             */+  /*                                                                       */+  /*    x2   :: The x-coordinate of the segment's end point.               */+  /*                                                                       */+  /*    y2   :: The y-coordinate of the segment's end point.               */+  /*                                                                       */+  /*    miny :: A lower vertical clipping bound value.                     */+  /*                                                                       */+  /*    maxy :: An upper vertical clipping bound value.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE on render pool overflow.               */+  /*                                                                       */+  static Bool+  Line_Down( RAS_ARGS Long  x1,+                      Long  y1,+                      Long  x2,+                      Long  y2,+                      Long  miny,+                      Long  maxy )+  {+    Bool  result, fresh;+++    fresh  = ras.fresh;++    result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );++    if ( fresh && !ras.fresh )+      ras.cProfile->start = -ras.cProfile->start;++    return result;+  }+++  /* A function type describing the functions used to split Bezier arcs */+  typedef void  (*TSplitter)( TPoint*  base );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Bezier_Up                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Compute the x-coordinates of an ascending Bezier arc and store     */+  /*    them in the render pool.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */+  /*                                                                       */+  /*    splitter :: The function to split Bezier arcs.                     */+  /*                                                                       */+  /*    miny     :: A lower vertical clipping bound value.                 */+  /*                                                                       */+  /*    maxy     :: An upper vertical clipping bound value.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE on render pool overflow.               */+  /*                                                                       */+  static Bool+  Bezier_Up( RAS_ARGS Int        degree,+                      TSplitter  splitter,+                      Long       miny,+                      Long       maxy )+  {+    Long   y1, y2, e, e2, e0;+    Short  f1;++    TPoint*  arc;+    TPoint*  start_arc;++    PLong top;+++    arc = ras.arc;+    y1  = arc[degree].y;+    y2  = arc[0].y;+    top = ras.top;++    if ( y2 < miny || y1 > maxy )+      goto Fin;++    e2 = FLOOR( y2 );++    if ( e2 > maxy )+      e2 = maxy;++    e0 = miny;++    if ( y1 < miny )+      e = miny;+    else+    {+      e  = CEILING( y1 );+      f1 = (Short)( FRAC( y1 ) );+      e0 = e;++      if ( f1 == 0 )+      {+        if ( ras.joint )+        {+          top--;+          ras.joint = FALSE;+        }++        *top++ = arc[degree].x;++        e += ras.precision;+      }+    }++    if ( ras.fresh )+    {+      ras.cProfile->start = TRUNC( e0 );+      ras.fresh = FALSE;+    }++    if ( e2 < e )+      goto Fin;++    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )+    {+      ras.top   = top;+      ras.error = Raster_Err_Overflow;+      return FAILURE;+    }++    start_arc = arc;++    while ( arc >= start_arc && e <= e2 )+    {+      ras.joint = FALSE;++      y2 = arc[0].y;++      if ( y2 > e )+      {+        y1 = arc[degree].y;+        if ( y2 - y1 >= ras.precision_step )+        {+          splitter( arc );+          arc += degree;+        }+        else+        {+          *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x,+                                            e - y1, y2 - y1 );+          arc -= degree;+          e   += ras.precision;+        }+      }+      else+      {+        if ( y2 == e )+        {+          ras.joint  = TRUE;+          *top++     = arc[0].x;++          e += ras.precision;+        }+        arc -= degree;+      }+    }++  Fin:+    ras.top  = top;+    ras.arc -= degree;+    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Bezier_Down                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Compute the x-coordinates of an descending Bezier arc and store    */+  /*    them in the render pool.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */+  /*                                                                       */+  /*    splitter :: The function to split Bezier arcs.                     */+  /*                                                                       */+  /*    miny     :: A lower vertical clipping bound value.                 */+  /*                                                                       */+  /*    maxy     :: An upper vertical clipping bound value.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE on render pool overflow.               */+  /*                                                                       */+  static Bool+  Bezier_Down( RAS_ARGS Int        degree,+                        TSplitter  splitter,+                        Long       miny,+                        Long       maxy )+  {+    TPoint*  arc = ras.arc;+    Bool     result, fresh;+++    arc[0].y = -arc[0].y;+    arc[1].y = -arc[1].y;+    arc[2].y = -arc[2].y;+    if ( degree > 2 )+      arc[3].y = -arc[3].y;++    fresh = ras.fresh;++    result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );++    if ( fresh && !ras.fresh )+      ras.cProfile->start = -ras.cProfile->start;++    arc[0].y = -arc[0].y;+    return result;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Line_To                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Inject a new line segment and adjust the Profiles list.            */+  /*                                                                       */+  /* <Input>                                                               */+  /*   x :: The x-coordinate of the segment's end point (its start point   */+  /*        is stored in `lastX').                                         */+  /*                                                                       */+  /*   y :: The y-coordinate of the segment's end point (its start point   */+  /*        is stored in `lastY').                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */+  /*   profile.                                                            */+  /*                                                                       */+  static Bool+  Line_To( RAS_ARGS Long  x,+                    Long  y )+  {+    /* First, detect a change of direction */++    switch ( ras.state )+    {+    case Unknown_State:+      if ( y > ras.lastY )+      {+        if ( New_Profile( RAS_VARS Ascending_State,+                                   IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )+          return FAILURE;+      }+      else+      {+        if ( y < ras.lastY )+          if ( New_Profile( RAS_VARS Descending_State,+                                     IS_TOP_OVERSHOOT( ras.lastY ) ) )+            return FAILURE;+      }+      break;++    case Ascending_State:+      if ( y < ras.lastY )+      {+        if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) ||+             New_Profile( RAS_VARS Descending_State,+                                   IS_TOP_OVERSHOOT( ras.lastY ) ) )+          return FAILURE;+      }+      break;++    case Descending_State:+      if ( y > ras.lastY )+      {+        if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ||+             New_Profile( RAS_VARS Ascending_State,+                                   IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )+          return FAILURE;+      }+      break;++    default:+      ;+    }++    /* Then compute the lines */++    switch ( ras.state )+    {+    case Ascending_State:+      if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,+                             x, y, ras.minY, ras.maxY ) )+        return FAILURE;+      break;++    case Descending_State:+      if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,+                               x, y, ras.minY, ras.maxY ) )+        return FAILURE;+      break;++    default:+      ;+    }++    ras.lastX = x;+    ras.lastY = y;++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Conic_To                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Inject a new conic arc and adjust the profile list.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*   cx :: The x-coordinate of the arc's new control point.              */+  /*                                                                       */+  /*   cy :: The y-coordinate of the arc's new control point.              */+  /*                                                                       */+  /*   x  :: The x-coordinate of the arc's end point (its start point is   */+  /*         stored in `lastX').                                           */+  /*                                                                       */+  /*   y  :: The y-coordinate of the arc's end point (its start point is   */+  /*         stored in `lastY').                                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */+  /*   profile.                                                            */+  /*                                                                       */+  static Bool+  Conic_To( RAS_ARGS Long  cx,+                     Long  cy,+                     Long  x,+                     Long  y )+  {+    Long     y1, y2, y3, x3, ymin, ymax;+    TStates  state_bez;+++    ras.arc      = ras.arcs;+    ras.arc[2].x = ras.lastX;+    ras.arc[2].y = ras.lastY;+    ras.arc[1].x = cx;+    ras.arc[1].y = cy;+    ras.arc[0].x = x;+    ras.arc[0].y = y;++    do+    {+      y1 = ras.arc[2].y;+      y2 = ras.arc[1].y;+      y3 = ras.arc[0].y;+      x3 = ras.arc[0].x;++      /* first, categorize the Bezier arc */++      if ( y1 <= y3 )+      {+        ymin = y1;+        ymax = y3;+      }+      else+      {+        ymin = y3;+        ymax = y1;+      }++      if ( y2 < ymin || y2 > ymax )+      {+        /* this arc has no given direction, split it! */+        Split_Conic( ras.arc );+        ras.arc += 2;+      }+      else if ( y1 == y3 )+      {+        /* this arc is flat, ignore it and pop it from the Bezier stack */+        ras.arc -= 2;+      }+      else+      {+        /* the arc is y-monotonous, either ascending or descending */+        /* detect a change of direction                            */+        state_bez = y1 < y3 ? Ascending_State : Descending_State;+        if ( ras.state != state_bez )+        {+          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )+                                                 : IS_TOP_OVERSHOOT( y1 );+++          /* finalize current profile if any */+          if ( ras.state != Unknown_State &&+               End_Profile( RAS_VARS o )  )+            goto Fail;++          /* create a new profile */+          if ( New_Profile( RAS_VARS state_bez, o ) )+            goto Fail;+        }++        /* now call the appropriate routine */+        if ( state_bez == Ascending_State )+        {+          if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )+            goto Fail;+        }+        else+          if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )+            goto Fail;+      }++    } while ( ras.arc >= ras.arcs );++    ras.lastX = x3;+    ras.lastY = y3;++    return SUCCESS;++  Fail:+    return FAILURE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Cubic_To                                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Inject a new cubic arc and adjust the profile list.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*   cx1 :: The x-coordinate of the arc's first new control point.       */+  /*                                                                       */+  /*   cy1 :: The y-coordinate of the arc's first new control point.       */+  /*                                                                       */+  /*   cx2 :: The x-coordinate of the arc's second new control point.      */+  /*                                                                       */+  /*   cy2 :: The y-coordinate of the arc's second new control point.      */+  /*                                                                       */+  /*   x   :: The x-coordinate of the arc's end point (its start point is  */+  /*          stored in `lastX').                                          */+  /*                                                                       */+  /*   y   :: The y-coordinate of the arc's end point (its start point is  */+  /*          stored in `lastY').                                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */+  /*   profile.                                                            */+  /*                                                                       */+  static Bool+  Cubic_To( RAS_ARGS Long  cx1,+                     Long  cy1,+                     Long  cx2,+                     Long  cy2,+                     Long  x,+                     Long  y )+  {+    Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;+    TStates  state_bez;+++    ras.arc      = ras.arcs;+    ras.arc[3].x = ras.lastX;+    ras.arc[3].y = ras.lastY;+    ras.arc[2].x = cx1;+    ras.arc[2].y = cy1;+    ras.arc[1].x = cx2;+    ras.arc[1].y = cy2;+    ras.arc[0].x = x;+    ras.arc[0].y = y;++    do+    {+      y1 = ras.arc[3].y;+      y2 = ras.arc[2].y;+      y3 = ras.arc[1].y;+      y4 = ras.arc[0].y;+      x4 = ras.arc[0].x;++      /* first, categorize the Bezier arc */++      if ( y1 <= y4 )+      {+        ymin1 = y1;+        ymax1 = y4;+      }+      else+      {+        ymin1 = y4;+        ymax1 = y1;+      }++      if ( y2 <= y3 )+      {+        ymin2 = y2;+        ymax2 = y3;+      }+      else+      {+        ymin2 = y3;+        ymax2 = y2;+      }++      if ( ymin2 < ymin1 || ymax2 > ymax1 )+      {+        /* this arc has no given direction, split it! */+        Split_Cubic( ras.arc );+        ras.arc += 3;+      }+      else if ( y1 == y4 )+      {+        /* this arc is flat, ignore it and pop it from the Bezier stack */+        ras.arc -= 3;+      }+      else+      {+        state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State;++        /* detect a change of direction */+        if ( ras.state != state_bez )+        {+          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )+                                                 : IS_TOP_OVERSHOOT( y1 );+++          /* finalize current profile if any */+          if ( ras.state != Unknown_State &&+               End_Profile( RAS_VARS o )  )+            goto Fail;++          if ( New_Profile( RAS_VARS state_bez, o ) )+            goto Fail;+        }++        /* compute intersections */+        if ( state_bez == Ascending_State )+        {+          if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )+            goto Fail;+        }+        else+          if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )+            goto Fail;+      }++    } while ( ras.arc >= ras.arcs );++    ras.lastX = x4;+    ras.lastY = y4;++    return SUCCESS;++  Fail:+    return FAILURE;+  }+++#undef  SWAP_+#define SWAP_( x, y )  do                \+                       {                 \+                         Long  swap = x; \+                                         \+                                         \+                         x = y;          \+                         y = swap;       \+                       } while ( 0 )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Decompose_Curve                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Scan the outline arrays in order to emit individual segments and   */+  /*    Beziers by calling Line_To() and Bezier_To().  It handles all      */+  /*    weird cases, like when the first point is off the curve, or when   */+  /*    there are simply no `on' points in the contour!                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    first   :: The index of the first point in the contour.            */+  /*                                                                       */+  /*    last    :: The index of the last point in the contour.             */+  /*                                                                       */+  /*    flipped :: If set, flip the direction of the curve.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE on error.                              */+  /*                                                                       */+  static Bool+  Decompose_Curve( RAS_ARGS UShort  first,+                            UShort  last,+                            int     flipped )+  {+    FT_Vector   v_last;+    FT_Vector   v_control;+    FT_Vector   v_start;++    FT_Vector*  points;+    FT_Vector*  point;+    FT_Vector*  limit;+    char*       tags;++    unsigned    tag;       /* current point's state           */+++    points = ras.outline.points;+    limit  = points + last;++    v_start.x = SCALED( points[first].x );+    v_start.y = SCALED( points[first].y );+    v_last.x  = SCALED( points[last].x );+    v_last.y  = SCALED( points[last].y );++    if ( flipped )+    {+      SWAP_( v_start.x, v_start.y );+      SWAP_( v_last.x, v_last.y );+    }++    v_control = v_start;++    point = points + first;+    tags  = ras.outline.tags + first;++    /* set scan mode if necessary */+    if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )+      ras.dropOutControl = (Byte)tags[0] >> 5;++    tag = FT_CURVE_TAG( tags[0] );++    /* A contour cannot start with a cubic control point! */+    if ( tag == FT_CURVE_TAG_CUBIC )+      goto Invalid_Outline;++    /* check first point to determine origin */+    if ( tag == FT_CURVE_TAG_CONIC )+    {+      /* first point is conic control.  Yes, this happens. */+      if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON )+      {+        /* start at last point if it is on the curve */+        v_start = v_last;+        limit--;+      }+      else+      {+        /* if both first and last points are conic,         */+        /* start at their middle and record its position    */+        /* for closure                                      */+        v_start.x = ( v_start.x + v_last.x ) / 2;+        v_start.y = ( v_start.y + v_last.y ) / 2;++        v_last = v_start;+      }+      point--;+      tags--;+    }++    ras.lastX = v_start.x;+    ras.lastY = v_start.y;++    while ( point < limit )+    {+      point++;+      tags++;++      tag = FT_CURVE_TAG( tags[0] );++      switch ( tag )+      {+      case FT_CURVE_TAG_ON:  /* emit a single line_to */+        {+          Long  x, y;+++          x = SCALED( point->x );+          y = SCALED( point->y );+          if ( flipped )+            SWAP_( x, y );++          if ( Line_To( RAS_VARS x, y ) )+            goto Fail;+          continue;+        }++      case FT_CURVE_TAG_CONIC:  /* consume conic arcs */+        v_control.x = SCALED( point[0].x );+        v_control.y = SCALED( point[0].y );++        if ( flipped )+          SWAP_( v_control.x, v_control.y );++      Do_Conic:+        if ( point < limit )+        {+          FT_Vector  v_middle;+          Long       x, y;+++          point++;+          tags++;+          tag = FT_CURVE_TAG( tags[0] );++          x = SCALED( point[0].x );+          y = SCALED( point[0].y );++          if ( flipped )+            SWAP_( x, y );++          if ( tag == FT_CURVE_TAG_ON )+          {+            if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )+              goto Fail;+            continue;+          }++          if ( tag != FT_CURVE_TAG_CONIC )+            goto Invalid_Outline;++          v_middle.x = ( v_control.x + x ) / 2;+          v_middle.y = ( v_control.y + y ) / 2;++          if ( Conic_To( RAS_VARS v_control.x, v_control.y,+                                  v_middle.x,  v_middle.y ) )+            goto Fail;++          v_control.x = x;+          v_control.y = y;++          goto Do_Conic;+        }++        if ( Conic_To( RAS_VARS v_control.x, v_control.y,+                                v_start.x,   v_start.y ) )+          goto Fail;++        goto Close;++      default:  /* FT_CURVE_TAG_CUBIC */+        {+          Long  x1, y1, x2, y2, x3, y3;+++          if ( point + 1 > limit                             ||+               FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )+            goto Invalid_Outline;++          point += 2;+          tags  += 2;++          x1 = SCALED( point[-2].x );+          y1 = SCALED( point[-2].y );+          x2 = SCALED( point[-1].x );+          y2 = SCALED( point[-1].y );++          if ( flipped )+          {+            SWAP_( x1, y1 );+            SWAP_( x2, y2 );+          }++          if ( point <= limit )+          {+            x3 = SCALED( point[0].x );+            y3 = SCALED( point[0].y );++            if ( flipped )+              SWAP_( x3, y3 );++            if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )+              goto Fail;+            continue;+          }++          if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )+            goto Fail;+          goto Close;+        }+      }+    }++    /* close the contour with a line segment */+    if ( Line_To( RAS_VARS v_start.x, v_start.y ) )+      goto Fail;++  Close:+    return SUCCESS;++  Invalid_Outline:+    ras.error = Raster_Err_Invalid;++  Fail:+    return FAILURE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Convert_Glyph                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Convert a glyph into a series of segments and arcs and make a      */+  /*    profiles list with them.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    flipped :: If set, flip the direction of curve.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS on success, FAILURE if any error was encountered during    */+  /*    rendering.                                                         */+  /*                                                                       */+  static Bool+  Convert_Glyph( RAS_ARGS int  flipped )+  {+    int       i;+    unsigned  start;++    PProfile  lastProfile;+++    ras.fProfile = NULL;+    ras.joint    = FALSE;+    ras.fresh    = FALSE;++    ras.maxBuff  = ras.sizeBuff - AlignProfileSize;++    ras.numTurns = 0;++    ras.cProfile         = (PProfile)ras.top;+    ras.cProfile->offset = ras.top;+    ras.num_Profs        = 0;++    start = 0;++    for ( i = 0; i < ras.outline.n_contours; i++ )+    {+      Bool  o;+++      ras.state    = Unknown_State;+      ras.gProfile = NULL;++      if ( Decompose_Curve( RAS_VARS (unsigned short)start,+                                     ras.outline.contours[i],+                                     flipped ) )+        return FAILURE;++      start = ras.outline.contours[i] + 1;++      /* we must now check whether the extreme arcs join or not */+      if ( FRAC( ras.lastY ) == 0 &&+           ras.lastY >= ras.minY  &&+           ras.lastY <= ras.maxY  )+        if ( ras.gProfile                        &&+             ( ras.gProfile->flags & Flow_Up ) ==+               ( ras.cProfile->flags & Flow_Up ) )+          ras.top--;+        /* Note that ras.gProfile can be nil if the contour was too small */+        /* to be drawn.                                                   */++      lastProfile = ras.cProfile;+      if ( ras.cProfile->flags & Flow_Up )+        o = IS_TOP_OVERSHOOT( ras.lastY );+      else+        o = IS_BOTTOM_OVERSHOOT( ras.lastY );+      if ( End_Profile( RAS_VARS o ) )+        return FAILURE;++      /* close the `next profile in contour' linked list */+      if ( ras.gProfile )+        lastProfile->next = ras.gProfile;+    }++    if ( Finalize_Profile_Table( RAS_VAR ) )+      return FAILURE;++    return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );+  }+++  /*************************************************************************/+  /*************************************************************************/+  /**                                                                     **/+  /**  SCAN-LINE SWEEPS AND DRAWING                                       **/+  /**                                                                     **/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /*  Init_Linked                                                          */+  /*                                                                       */+  /*    Initializes an empty linked list.                                  */+  /*                                                                       */+  static void+  Init_Linked( TProfileList*  l )+  {+    *l = NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*  InsNew                                                               */+  /*                                                                       */+  /*    Inserts a new profile in a linked list.                            */+  /*                                                                       */+  static void+  InsNew( PProfileList  list,+          PProfile      profile )+  {+    PProfile  *old, current;+    Long       x;+++    old     = list;+    current = *old;+    x       = profile->X;++    while ( current )+    {+      if ( x < current->X )+        break;+      old     = &current->link;+      current = *old;+    }++    profile->link = current;+    *old          = profile;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*  DelOld                                                               */+  /*                                                                       */+  /*    Removes an old profile from a linked list.                         */+  /*                                                                       */+  static void+  DelOld( PProfileList  list,+          PProfile      profile )+  {+    PProfile  *old, current;+++    old     = list;+    current = *old;++    while ( current )+    {+      if ( current == profile )+      {+        *old = current->link;+        return;+      }++      old     = &current->link;+      current = *old;+    }++    /* we should never get there, unless the profile was not part of */+    /* the list.                                                     */+  }+++  /*************************************************************************/+  /*                                                                       */+  /*  Sort                                                                 */+  /*                                                                       */+  /*    Sorts a trace list.  In 95%, the list is already sorted.  We need  */+  /*    an algorithm which is fast in this case.  Bubble sort is enough    */+  /*    and simple.                                                        */+  /*                                                                       */+  static void+  Sort( PProfileList  list )+  {+    PProfile  *old, current, next;+++    /* First, set the new X coordinate of each profile */+    current = *list;+    while ( current )+    {+      current->X       = *current->offset;+      current->offset += current->flags & Flow_Up ? 1 : -1;+      current->height--;+      current = current->link;+    }++    /* Then sort them */+    old     = list;+    current = *old;++    if ( !current )+      return;++    next = current->link;++    while ( next )+    {+      if ( current->X <= next->X )+      {+        old     = &current->link;+        current = *old;++        if ( !current )+          return;+      }+      else+      {+        *old          = next;+        current->link = next->link;+        next->link    = current;++        old     = list;+        current = *old;+      }++      next = current->link;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /*  Vertical Sweep Procedure Set                                         */+  /*                                                                       */+  /*  These four routines are used during the vertical black/white sweep   */+  /*  phase by the generic Draw_Sweep() function.                          */+  /*                                                                       */+  /*************************************************************************/++  static void+  Vertical_Sweep_Init( RAS_ARGS Short*  min,+                                Short*  max )+  {+    Long  pitch = ras.target.pitch;++    FT_UNUSED( max );+++    ras.traceIncr = (Short)-pitch;+    ras.traceOfs  = -*min * pitch;+    if ( pitch > 0 )+      ras.traceOfs += ( ras.target.rows - 1 ) * pitch;++    ras.gray_min_x = 0;+    ras.gray_max_x = 0;+  }+++  static void+  Vertical_Sweep_Span( RAS_ARGS Short       y,+                                FT_F26Dot6  x1,+                                FT_F26Dot6  x2,+                                PProfile    left,+                                PProfile    right )+  {+    Long   e1, e2;+    int    c1, c2;+    Byte   f1, f2;+    Byte*  target;++    FT_UNUSED( y );+    FT_UNUSED( left );+    FT_UNUSED( right );+++    /* Drop-out control */++    e1 = TRUNC( CEILING( x1 ) );++    if ( x2 - x1 - ras.precision <= ras.precision_jitter )+      e2 = e1;+    else+      e2 = TRUNC( FLOOR( x2 ) );++    if ( e2 >= 0 && e1 < ras.bWidth )+    {+      if ( e1 < 0 )+        e1 = 0;+      if ( e2 >= ras.bWidth )+        e2 = ras.bWidth - 1;++      c1 = (Short)( e1 >> 3 );+      c2 = (Short)( e2 >> 3 );++      f1 = (Byte)  ( 0xFF >> ( e1 & 7 ) );+      f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );++      if ( ras.gray_min_x > c1 )+        ras.gray_min_x = (short)c1;+      if ( ras.gray_max_x < c2 )+        ras.gray_max_x = (short)c2;++      target = ras.bTarget + ras.traceOfs + c1;+      c2 -= c1;++      if ( c2 > 0 )+      {+        target[0] |= f1;++        /* memset() is slower than the following code on many platforms. */+        /* This is due to the fact that, in the vast majority of cases,  */+        /* the span length in bytes is relatively small.                 */+        c2--;+        while ( c2 > 0 )+        {+          *(++target) = 0xFF;+          c2--;+        }+        target[1] |= f2;+      }+      else+        *target |= ( f1 & f2 );+    }+  }+++  static void+  Vertical_Sweep_Drop( RAS_ARGS Short       y,+                                FT_F26Dot6  x1,+                                FT_F26Dot6  x2,+                                PProfile    left,+                                PProfile    right )+  {+    Long   e1, e2, pxl;+    Short  c1, f1;+++    /* Drop-out control */++    /*   e2            x2                    x1           e1   */+    /*                                                         */+    /*                 ^                     |                 */+    /*                 |                     |                 */+    /*   +-------------+---------------------+------------+    */+    /*                 |                     |                 */+    /*                 |                     v                 */+    /*                                                         */+    /* pixel         contour              contour       pixel  */+    /* center                                           center */++    /* drop-out mode    scan conversion rules (as defined in OpenType) */+    /* --------------------------------------------------------------- */+    /*  0                1, 2, 3                                       */+    /*  1                1, 2, 4                                       */+    /*  2                1, 2                                          */+    /*  3                same as mode 2                                */+    /*  4                1, 2, 5                                       */+    /*  5                1, 2, 6                                       */+    /*  6, 7             same as mode 2                                */++    e1  = CEILING( x1 );+    e2  = FLOOR  ( x2 );+    pxl = e1;++    if ( e1 > e2 )+    {+      Int  dropOutControl = left->flags & 7;+++      if ( e1 == e2 + ras.precision )+      {+        switch ( dropOutControl )+        {+        case 0: /* simple drop-outs including stubs */+          pxl = e2;+          break;++        case 4: /* smart drop-outs including stubs */+          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );+          break;++        case 1: /* simple drop-outs excluding stubs */+        case 5: /* smart drop-outs excluding stubs  */++          /* Drop-out Control Rules #4 and #6 */++          /* The specification neither provides an exact definition */+          /* of a `stub' nor gives exact rules to exclude them.     */+          /*                                                        */+          /* Here the constraints we use to recognize a stub.       */+          /*                                                        */+          /*  upper stub:                                           */+          /*                                                        */+          /*   - P_Left and P_Right are in the same contour         */+          /*   - P_Right is the successor of P_Left in that contour */+          /*   - y is the top of P_Left and P_Right                 */+          /*                                                        */+          /*  lower stub:                                           */+          /*                                                        */+          /*   - P_Left and P_Right are in the same contour         */+          /*   - P_Left is the successor of P_Right in that contour */+          /*   - y is the bottom of P_Left                          */+          /*                                                        */+          /* We draw a stub if the following constraints are met.   */+          /*                                                        */+          /*   - for an upper or lower stub, there is top or bottom */+          /*     overshoot, respectively                            */+          /*   - the covered interval is greater or equal to a half */+          /*     pixel                                              */++          /* upper stub test */+          if ( left->next == right                &&+               left->height <= 0                  &&+               !( left->flags & Overshoot_Top   &&+                  x2 - x1 >= ras.precision_half ) )+            return;++          /* lower stub test */+          if ( right->next == left                 &&+               left->start == y                    &&+               !( left->flags & Overshoot_Bottom &&+                  x2 - x1 >= ras.precision_half  ) )+            return;++          if ( dropOutControl == 1 )+            pxl = e2;+          else+            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );+          break;++        default: /* modes 2, 3, 6, 7 */+          return;  /* no drop-out control */+        }++        /* check that the other pixel isn't set */+        e1 = pxl == e1 ? e2 : e1;++        e1 = TRUNC( e1 );++        c1 = (Short)( e1 >> 3 );+        f1 = (Short)( e1 &  7 );++        if ( e1 >= 0 && e1 < ras.bWidth                      &&+             ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )+          return;+      }+      else+        return;+    }++    e1 = TRUNC( pxl );++    if ( e1 >= 0 && e1 < ras.bWidth )+    {+      c1 = (Short)( e1 >> 3 );+      f1 = (Short)( e1 & 7 );++      if ( ras.gray_min_x > c1 )+        ras.gray_min_x = c1;+      if ( ras.gray_max_x < c1 )+        ras.gray_max_x = c1;++      ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );+    }+  }+++  static void+  Vertical_Sweep_Step( RAS_ARG )+  {+    ras.traceOfs += ras.traceIncr;+  }+++  /***********************************************************************/+  /*                                                                     */+  /*  Horizontal Sweep Procedure Set                                     */+  /*                                                                     */+  /*  These four routines are used during the horizontal black/white     */+  /*  sweep phase by the generic Draw_Sweep() function.                  */+  /*                                                                     */+  /***********************************************************************/++  static void+  Horizontal_Sweep_Init( RAS_ARGS Short*  min,+                                  Short*  max )+  {+    /* nothing, really */+    FT_UNUSED_RASTER;+    FT_UNUSED( min );+    FT_UNUSED( max );+  }+++  static void+  Horizontal_Sweep_Span( RAS_ARGS Short       y,+                                  FT_F26Dot6  x1,+                                  FT_F26Dot6  x2,+                                  PProfile    left,+                                  PProfile    right )+  {+    Long   e1, e2;+    PByte  bits;+    Byte   f1;++    FT_UNUSED( left );+    FT_UNUSED( right );+++    if ( x2 - x1 < ras.precision )+    {+      e1 = CEILING( x1 );+      e2 = FLOOR  ( x2 );++      if ( e1 == e2 )+      {+        bits = ras.bTarget + ( y >> 3 );+        f1   = (Byte)( 0x80 >> ( y & 7 ) );++        e1 = TRUNC( e1 );++        if ( e1 >= 0 && e1 < ras.target.rows )+        {+          PByte  p;+++          p = bits - e1 * ras.target.pitch;+          if ( ras.target.pitch > 0 )+            p += ( ras.target.rows - 1 ) * ras.target.pitch;++          p[0] |= f1;+        }+      }+    }+  }+++  static void+  Horizontal_Sweep_Drop( RAS_ARGS Short       y,+                                  FT_F26Dot6  x1,+                                  FT_F26Dot6  x2,+                                  PProfile    left,+                                  PProfile    right )+  {+    Long   e1, e2, pxl;+    PByte  bits;+    Byte   f1;+++    /* During the horizontal sweep, we only take care of drop-outs */++    /* e1     +       <-- pixel center */+    /*        |                        */+    /* x1  ---+-->    <-- contour      */+    /*        |                        */+    /*        |                        */+    /* x2  <--+---    <-- contour      */+    /*        |                        */+    /*        |                        */+    /* e2     +       <-- pixel center */++    e1  = CEILING( x1 );+    e2  = FLOOR  ( x2 );+    pxl = e1;++    if ( e1 > e2 )+    {+      Int  dropOutControl = left->flags & 7;+++      if ( e1 == e2 + ras.precision )+      {+        switch ( dropOutControl )+        {+        case 0: /* simple drop-outs including stubs */+          pxl = e2;+          break;++        case 4: /* smart drop-outs including stubs */+          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );+          break;++        case 1: /* simple drop-outs excluding stubs */+        case 5: /* smart drop-outs excluding stubs  */+          /* see Vertical_Sweep_Drop for details */++          /* rightmost stub test */+          if ( left->next == right                &&+               left->height <= 0                  &&+               !( left->flags & Overshoot_Top   &&+                  x2 - x1 >= ras.precision_half ) )+            return;++          /* leftmost stub test */+          if ( right->next == left                 &&+               left->start == y                    &&+               !( left->flags & Overshoot_Bottom &&+                  x2 - x1 >= ras.precision_half  ) )+            return;++          if ( dropOutControl == 1 )+            pxl = e2;+          else+            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );+          break;++        default: /* modes 2, 3, 6, 7 */+          return;  /* no drop-out control */+        }++        /* check that the other pixel isn't set */+        e1 = pxl == e1 ? e2 : e1;++        e1 = TRUNC( e1 );++        bits = ras.bTarget + ( y >> 3 );+        f1   = (Byte)( 0x80 >> ( y & 7 ) );++        bits -= e1 * ras.target.pitch;+        if ( ras.target.pitch > 0 )+          bits += ( ras.target.rows - 1 ) * ras.target.pitch;++        if ( e1 >= 0              &&+             e1 < ras.target.rows &&+             *bits & f1           )+          return;+      }+      else+        return;+    }++    bits = ras.bTarget + ( y >> 3 );+    f1   = (Byte)( 0x80 >> ( y & 7 ) );++    e1 = TRUNC( pxl );++    if ( e1 >= 0 && e1 < ras.target.rows )+    {+      bits -= e1 * ras.target.pitch;+      if ( ras.target.pitch > 0 )+        bits += ( ras.target.rows - 1 ) * ras.target.pitch;++      bits[0] |= f1;+    }+  }+++  static void+  Horizontal_Sweep_Step( RAS_ARG )+  {+    /* Nothing, really */+    FT_UNUSED_RASTER;+  }+++#ifdef FT_RASTER_OPTION_ANTI_ALIASING+++  /*************************************************************************/+  /*                                                                       */+  /*  Vertical Gray Sweep Procedure Set                                    */+  /*                                                                       */+  /*  These two routines are used during the vertical gray-levels sweep    */+  /*  phase by the generic Draw_Sweep() function.                          */+  /*                                                                       */+  /*  NOTES                                                                */+  /*                                                                       */+  /*  - The target pixmap's width *must* be a multiple of 4.               */+  /*                                                                       */+  /*  - You have to use the function Vertical_Sweep_Span() for the gray    */+  /*    span call.                                                         */+  /*                                                                       */+  /*************************************************************************/++  static void+  Vertical_Gray_Sweep_Init( RAS_ARGS Short*  min,+                                     Short*  max )+  {+    Long  pitch, byte_len;+++    *min = *min & -2;+    *max = ( *max + 3 ) & -2;++    ras.traceOfs  = 0;+    pitch         = ras.target.pitch;+    byte_len      = -pitch;+    ras.traceIncr = (Short)byte_len;+    ras.traceG    = ( *min / 2 ) * byte_len;++    if ( pitch > 0 )+    {+      ras.traceG += ( ras.target.rows - 1 ) * pitch;+      byte_len    = -byte_len;+    }++    ras.gray_min_x =  (Short)byte_len;+    ras.gray_max_x = -(Short)byte_len;+  }+++  static void+  Vertical_Gray_Sweep_Step( RAS_ARG )+  {+    Int     c1, c2;+    PByte   pix, bit, bit2;+    short*  count = (short*)count_table;+    Byte*   grays;+++    ras.traceOfs += ras.gray_width;++    if ( ras.traceOfs > ras.gray_width )+    {+      pix   = ras.gTarget + ras.traceG + ras.gray_min_x * 4;+      grays = ras.grays;++      if ( ras.gray_max_x >= 0 )+      {+        Long  last_pixel = ras.target.width - 1;+        Int   last_cell  = last_pixel >> 2;+        Int   last_bit   = last_pixel & 3;+        Bool  over       = 0;+++        if ( ras.gray_max_x >= last_cell && last_bit != 3 )+        {+          ras.gray_max_x = last_cell - 1;+          over = 1;+        }++        if ( ras.gray_min_x < 0 )+          ras.gray_min_x = 0;++        bit  = ras.bTarget + ras.gray_min_x;+        bit2 = bit + ras.gray_width;++        c1 = ras.gray_max_x - ras.gray_min_x;++        while ( c1 >= 0 )+        {+          c2 = count[*bit] + count[*bit2];++          if ( c2 )+          {+            pix[0] = grays[(c2 >> 12) & 0x000F];+            pix[1] = grays[(c2 >> 8 ) & 0x000F];+            pix[2] = grays[(c2 >> 4 ) & 0x000F];+            pix[3] = grays[ c2        & 0x000F];++            *bit  = 0;+            *bit2 = 0;+          }++          bit++;+          bit2++;+          pix += 4;+          c1--;+        }++        if ( over )+        {+          c2 = count[*bit] + count[*bit2];+          if ( c2 )+          {+            switch ( last_bit )+            {+            case 2:+              pix[2] = grays[(c2 >> 4 ) & 0x000F];+            case 1:+              pix[1] = grays[(c2 >> 8 ) & 0x000F];+            default:+              pix[0] = grays[(c2 >> 12) & 0x000F];+            }++            *bit  = 0;+            *bit2 = 0;+          }+        }+      }++      ras.traceOfs = 0;+      ras.traceG  += ras.traceIncr;++      ras.gray_min_x =  32000;+      ras.gray_max_x = -32000;+    }+  }+++  static void+  Horizontal_Gray_Sweep_Span( RAS_ARGS Short       y,+                                       FT_F26Dot6  x1,+                                       FT_F26Dot6  x2,+                                       PProfile    left,+                                       PProfile    right )+  {+    /* nothing, really */+    FT_UNUSED_RASTER;+    FT_UNUSED( y );+    FT_UNUSED( x1 );+    FT_UNUSED( x2 );+    FT_UNUSED( left );+    FT_UNUSED( right );+  }+++  static void+  Horizontal_Gray_Sweep_Drop( RAS_ARGS Short       y,+                                       FT_F26Dot6  x1,+                                       FT_F26Dot6  x2,+                                       PProfile    left,+                                       PProfile    right )+  {+    Long   e1, e2;+    PByte  pixel;+    Byte   color;+++    /* During the horizontal sweep, we only take care of drop-outs */++    e1 = CEILING( x1 );+    e2 = FLOOR  ( x2 );++    if ( e1 > e2 )+    {+      Int  dropOutControl = left->flags & 7;+++      if ( e1 == e2 + ras.precision )+      {+        switch ( dropOutControl )+        {+        case 0: /* simple drop-outs including stubs */+          e1 = e2;+          break;++        case 4: /* smart drop-outs including stubs */+          e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );+          break;++        case 1: /* simple drop-outs excluding stubs */+        case 5: /* smart drop-outs excluding stubs  */+          /* see Vertical_Sweep_Drop for details */++          /* rightmost stub test */+          if ( left->next == right && left->height <= 0 )+            return;++          /* leftmost stub test */+          if ( right->next == left && left->start == y )+            return;++          if ( dropOutControl == 1 )+            e1 = e2;+          else+            e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );++          break;++        default: /* modes 2, 3, 6, 7 */+          return;  /* no drop-out control */+        }+      }+      else+        return;+    }++    if ( e1 >= 0 )+    {+      if ( x2 - x1 >= ras.precision_half )+        color = ras.grays[2];+      else+        color = ras.grays[1];++      e1 = TRUNC( e1 ) / 2;+      if ( e1 < ras.target.rows )+      {+        pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;+        if ( ras.target.pitch > 0 )+          pixel += ( ras.target.rows - 1 ) * ras.target.pitch;++        if ( pixel[0] == ras.grays[0] )+          pixel[0] = color;+      }+    }+  }+++#endif /* FT_RASTER_OPTION_ANTI_ALIASING */+++  /*************************************************************************/+  /*                                                                       */+  /*  Generic Sweep Drawing routine                                        */+  /*                                                                       */+  /*************************************************************************/++  static Bool+  Draw_Sweep( RAS_ARG )+  {+    Short         y, y_change, y_height;++    PProfile      P, Q, P_Left, P_Right;++    Short         min_Y, max_Y, top, bottom, dropouts;++    Long          x1, x2, xs, e1, e2;++    TProfileList  waiting;+    TProfileList  draw_left, draw_right;+++    /* initialize empty linked lists */++    Init_Linked( &waiting );++    Init_Linked( &draw_left  );+    Init_Linked( &draw_right );++    /* first, compute min and max Y */++    P     = ras.fProfile;+    max_Y = (Short)TRUNC( ras.minY );+    min_Y = (Short)TRUNC( ras.maxY );++    while ( P )+    {+      Q = P->link;++      bottom = (Short)P->start;+      top    = (Short)( P->start + P->height - 1 );++      if ( min_Y > bottom )+        min_Y = bottom;+      if ( max_Y < top )+        max_Y = top;++      P->X = 0;+      InsNew( &waiting, P );++      P = Q;+    }++    /* check the Y-turns */+    if ( ras.numTurns == 0 )+    {+      ras.error = Raster_Err_Invalid;+      return FAILURE;+    }++    /* now initialize the sweep */++    ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y );++    /* then compute the distance of each profile from min_Y */++    P = waiting;++    while ( P )+    {+      P->countL = (UShort)( P->start - min_Y );+      P = P->link;+    }++    /* let's go */++    y        = min_Y;+    y_height = 0;++    if ( ras.numTurns > 0                     &&+         ras.sizeBuff[-ras.numTurns] == min_Y )+      ras.numTurns--;++    while ( ras.numTurns > 0 )+    {+      /* check waiting list for new activations */++      P = waiting;++      while ( P )+      {+        Q = P->link;+        P->countL -= y_height;+        if ( P->countL == 0 )+        {+          DelOld( &waiting, P );++          if ( P->flags & Flow_Up )+            InsNew( &draw_left,  P );+          else+            InsNew( &draw_right, P );+        }++        P = Q;+      }++      /* sort the drawing lists */++      Sort( &draw_left );+      Sort( &draw_right );++      y_change = (Short)ras.sizeBuff[-ras.numTurns--];+      y_height = (Short)( y_change - y );++      while ( y < y_change )+      {+        /* let's trace */++        dropouts = 0;++        P_Left  = draw_left;+        P_Right = draw_right;++        while ( P_Left )+        {+          x1 = P_Left ->X;+          x2 = P_Right->X;++          if ( x1 > x2 )+          {+            xs = x1;+            x1 = x2;+            x2 = xs;+          }++          e1 = FLOOR( x1 );+          e2 = CEILING( x2 );++          if ( x2 - x1 <= ras.precision &&+               e1 != x1 && e2 != x2     )+          {+            if ( e1 > e2 || e2 == e1 + ras.precision )+            {+              Int  dropOutControl = P_Left->flags & 7;+++              if ( dropOutControl != 2 )+              {+                /* a drop-out was detected */++                P_Left ->X = x1;+                P_Right->X = x2;++                /* mark profile for drop-out processing */+                P_Left->countL = 1;+                dropouts++;+              }++              goto Skip_To_Next;+            }+          }++          ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );++        Skip_To_Next:++          P_Left  = P_Left->link;+          P_Right = P_Right->link;+        }++        /* handle drop-outs _after_ the span drawing --       */+        /* drop-out processing has been moved out of the loop */+        /* for performance tuning                             */+        if ( dropouts > 0 )+          goto Scan_DropOuts;++      Next_Line:++        ras.Proc_Sweep_Step( RAS_VAR );++        y++;++        if ( y < y_change )+        {+          Sort( &draw_left  );+          Sort( &draw_right );+        }+      }++      /* now finalize the profiles that need it */++      P = draw_left;+      while ( P )+      {+        Q = P->link;+        if ( P->height == 0 )+          DelOld( &draw_left, P );+        P = Q;+      }++      P = draw_right;+      while ( P )+      {+        Q = P->link;+        if ( P->height == 0 )+          DelOld( &draw_right, P );+        P = Q;+      }+    }++    /* for gray-scaling, flush the bitmap scanline cache */+    while ( y <= max_Y )+    {+      ras.Proc_Sweep_Step( RAS_VAR );+      y++;+    }++    return SUCCESS;++  Scan_DropOuts:++    P_Left  = draw_left;+    P_Right = draw_right;++    while ( P_Left )+    {+      if ( P_Left->countL )+      {+        P_Left->countL = 0;+#if 0+        dropouts--;  /* -- this is useful when debugging only */+#endif+        ras.Proc_Sweep_Drop( RAS_VARS y,+                                      P_Left->X,+                                      P_Right->X,+                                      P_Left,+                                      P_Right );+      }++      P_Left  = P_Left->link;+      P_Right = P_Right->link;+    }++    goto Next_Line;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Render_Single_Pass                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Perform one sweep with sub-banding.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    flipped :: If set, flip the direction of the outline.              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Renderer error code.                                               */+  /*                                                                       */+  static int+  Render_Single_Pass( RAS_ARGS Bool  flipped )+  {+    Short  i, j, k;+++    while ( ras.band_top >= 0 )+    {+      ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;+      ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;++      ras.top = ras.buff;++      ras.error = Raster_Err_None;++      if ( Convert_Glyph( RAS_VARS flipped ) )+      {+        if ( ras.error != Raster_Err_Overflow )+          return FAILURE;++        ras.error = Raster_Err_None;++        /* sub-banding */++#ifdef DEBUG_RASTER+        ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );+#endif++        i = ras.band_stack[ras.band_top].y_min;+        j = ras.band_stack[ras.band_top].y_max;++        k = (Short)( ( i + j ) / 2 );++        if ( ras.band_top >= 7 || k < i )+        {+          ras.band_top = 0;+          ras.error    = Raster_Err_Invalid;++          return ras.error;+        }++        ras.band_stack[ras.band_top + 1].y_min = k;+        ras.band_stack[ras.band_top + 1].y_max = j;++        ras.band_stack[ras.band_top].y_max = (Short)( k - 1 );++        ras.band_top++;+      }+      else+      {+        if ( ras.fProfile )+          if ( Draw_Sweep( RAS_VAR ) )+             return ras.error;+        ras.band_top--;+      }+    }++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Render_Glyph                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Render a glyph in a bitmap.  Sub-banding if needed.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  Render_Glyph( RAS_ARG )+  {+    FT_Error  error;+++    Set_High_Precision( RAS_VARS ras.outline.flags &+                                 FT_OUTLINE_HIGH_PRECISION );+    ras.scale_shift = ras.precision_shift;++    if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )+      ras.dropOutControl = 2;+    else+    {+      if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )+        ras.dropOutControl = 4;+      else+        ras.dropOutControl = 0;++      if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )+        ras.dropOutControl += 1;+    }++    ras.second_pass = (FT_Byte)( !( ras.outline.flags &+                                    FT_OUTLINE_SINGLE_PASS ) );++    /* Vertical Sweep */+    ras.Proc_Sweep_Init = Vertical_Sweep_Init;+    ras.Proc_Sweep_Span = Vertical_Sweep_Span;+    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;+    ras.Proc_Sweep_Step = Vertical_Sweep_Step;++    ras.band_top            = 0;+    ras.band_stack[0].y_min = 0;+    ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );++    ras.bWidth  = (unsigned short)ras.target.width;+    ras.bTarget = (Byte*)ras.target.buffer;++    if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )+      return error;++    /* Horizontal Sweep */+    if ( ras.second_pass && ras.dropOutControl != 2 )+    {+      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;+      ras.Proc_Sweep_Span = Horizontal_Sweep_Span;+      ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;+      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;++      ras.band_top            = 0;+      ras.band_stack[0].y_min = 0;+      ras.band_stack[0].y_max = (short)( ras.target.width - 1 );++      if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )+        return error;+    }++    return Raster_Err_None;+  }+++#ifdef FT_RASTER_OPTION_ANTI_ALIASING++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Render_Gray_Glyph                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Render a glyph with grayscaling.  Sub-banding if needed.           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  Render_Gray_Glyph( RAS_ARG )+  {+    Long      pixel_width;+    FT_Error  error;+++    Set_High_Precision( RAS_VARS ras.outline.flags &+                                 FT_OUTLINE_HIGH_PRECISION );+    ras.scale_shift = ras.precision_shift + 1;++    if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )+      ras.dropOutControl = 2;+    else+    {+      if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )+        ras.dropOutControl = 4;+      else+        ras.dropOutControl = 0;++      if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )+        ras.dropOutControl += 1;+    }++    ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );++    /* Vertical Sweep */++    ras.band_top            = 0;+    ras.band_stack[0].y_min = 0;+    ras.band_stack[0].y_max = 2 * ras.target.rows - 1;++    ras.bWidth  = ras.gray_width;+    pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );++    if ( ras.bWidth > pixel_width )+      ras.bWidth = pixel_width;++    ras.bWidth  = ras.bWidth * 8;+    ras.bTarget = (Byte*)ras.gray_lines;+    ras.gTarget = (Byte*)ras.target.buffer;++    ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;+    ras.Proc_Sweep_Span = Vertical_Sweep_Span;+    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;+    ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;++    error = Render_Single_Pass( RAS_VARS 0 );+    if ( error )+      return error;++    /* Horizontal Sweep */+    if ( ras.second_pass && ras.dropOutControl != 2 )+    {+      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;+      ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;+      ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;+      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;++      ras.band_top            = 0;+      ras.band_stack[0].y_min = 0;+      ras.band_stack[0].y_max = ras.target.width * 2 - 1;++      error = Render_Single_Pass( RAS_VARS 1 );+      if ( error )+        return error;+    }++    return Raster_Err_None;+  }++#else /* !FT_RASTER_OPTION_ANTI_ALIASING */++  FT_LOCAL_DEF( FT_Error )+  Render_Gray_Glyph( RAS_ARG )+  {+    FT_UNUSED_RASTER;++    return Raster_Err_Unsupported;+  }++#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */+++  static void+  ft_black_init( PRaster  raster )+  {+#ifdef FT_RASTER_OPTION_ANTI_ALIASING+    FT_UInt  n;+++    /* set default 5-levels gray palette */+    for ( n = 0; n < 5; n++ )+      raster->grays[n] = n * 255 / 4;++    raster->gray_width = RASTER_GRAY_LINES / 2;+#else+    FT_UNUSED( raster );+#endif+  }+++  /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/+  /****                         a static object.                  *****/+++#ifdef _STANDALONE_+++  static int+  ft_black_new( void*       memory,+                FT_Raster  *araster )+  {+     static TRaster  the_raster;+     FT_UNUSED( memory );+++     *araster = (FT_Raster)&the_raster;+     FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );+     ft_black_init( &the_raster );++     return 0;+  }+++  static void+  ft_black_done( FT_Raster  raster )+  {+    /* nothing */+    FT_UNUSED( raster );+  }+++#else /* !_STANDALONE_ */+++  static int+  ft_black_new( FT_Memory   memory,+                PRaster    *araster )+  {+    FT_Error  error;+    PRaster   raster = NULL;+++    *araster = 0;+    if ( !FT_NEW( raster ) )+    {+      raster->memory = memory;+      ft_black_init( raster );++      *araster = raster;+    }++    return error;+  }+++  static void+  ft_black_done( PRaster  raster )+  {+    FT_Memory  memory = (FT_Memory)raster->memory;+    FT_FREE( raster );+  }+++#endif /* !_STANDALONE_ */+++  static void+  ft_black_reset( PRaster  raster,+                  char*    pool_base,+                  long     pool_size )+  {+    if ( raster )+    {+      if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 )+      {+        PWorker  worker = (PWorker)pool_base;+++        raster->buffer      = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );+        raster->buffer_size = pool_base + pool_size - (char*)raster->buffer;+        raster->worker      = worker;+      }+      else+      {+        raster->buffer      = NULL;+        raster->buffer_size = 0;+        raster->worker      = NULL;+      }+    }+  }+++  static void+  ft_black_set_mode( PRaster        raster,+                     unsigned long  mode,+                     const char*    palette )+  {+#ifdef FT_RASTER_OPTION_ANTI_ALIASING++    if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )+    {+      /* set 5-levels gray palette */+      raster->grays[0] = palette[0];+      raster->grays[1] = palette[1];+      raster->grays[2] = palette[2];+      raster->grays[3] = palette[3];+      raster->grays[4] = palette[4];+    }++#else++    FT_UNUSED( raster );+    FT_UNUSED( mode );+    FT_UNUSED( palette );++#endif+  }+++  static int+  ft_black_render( PRaster                  raster,+                   const FT_Raster_Params*  params )+  {+    const FT_Outline*  outline    = (const FT_Outline*)params->source;+    const FT_Bitmap*   target_map = params->target;+    PWorker            worker;+++    if ( !raster || !raster->buffer || !raster->buffer_size )+      return Raster_Err_Not_Ini;++    if ( !outline )+      return Raster_Err_Invalid;++    /* return immediately if the outline is empty */+    if ( outline->n_points == 0 || outline->n_contours <= 0 )+      return Raster_Err_None;++    if ( !outline->contours || !outline->points )+      return Raster_Err_Invalid;++    if ( outline->n_points !=+           outline->contours[outline->n_contours - 1] + 1 )+      return Raster_Err_Invalid;++    worker = raster->worker;++    /* this version of the raster does not support direct rendering, sorry */+    if ( params->flags & FT_RASTER_FLAG_DIRECT )+      return Raster_Err_Unsupported;++    if ( !target_map )+      return Raster_Err_Invalid;++    /* nothing to do */+    if ( !target_map->width || !target_map->rows )+      return Raster_Err_None;++    if ( !target_map->buffer )+      return Raster_Err_Invalid;++    ras.outline = *outline;+    ras.target  = *target_map;++    worker->buff       = (PLong) raster->buffer;+    worker->sizeBuff   = worker->buff ++                           raster->buffer_size / sizeof ( Long );+#ifdef FT_RASTER_OPTION_ANTI_ALIASING+    worker->grays      = raster->grays;+    worker->gray_width = raster->gray_width;++    FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );+#endif++    return ( params->flags & FT_RASTER_FLAG_AA )+           ? Render_Gray_Glyph( RAS_VAR )+           : Render_Glyph( RAS_VAR );+  }+++  FT_DEFINE_RASTER_FUNCS( ft_standard_raster,+    FT_GLYPH_FORMAT_OUTLINE,+    (FT_Raster_New_Func)     ft_black_new,+    (FT_Raster_Reset_Func)   ft_black_reset,+    (FT_Raster_Set_Mode_Func)ft_black_set_mode,+    (FT_Raster_Render_Func)  ft_black_render,+    (FT_Raster_Done_Func)    ft_black_done+  )+++/* END */
+ src/raster/ftraster.h view
@@ -0,0 +1,46 @@+/***************************************************************************/+/*                                                                         */+/*  ftraster.h                                                             */+/*                                                                         */+/*    The FreeType glyph rasterizer (specification).                       */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used        */+/*  modified and distributed under the terms of the FreeType project       */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTRASTER_H__+#define __FTRASTER_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_IMAGE_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* Uncomment the following line if you are using ftraster.c as a         */+  /* standalone module, fully independent of FreeType.                     */+  /*                                                                       */+/* #define _STANDALONE_ */++  FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_standard_raster;+++FT_END_HEADER++#endif /* __FTRASTER_H__ */+++/* END */
+ src/raster/ftrend1.c view
@@ -0,0 +1,291 @@+/***************************************************************************/+/*                                                                         */+/*  ftrend1.c                                                              */+/*                                                                         */+/*    The FreeType glyph rasterizer interface (body).                      */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2005, 2006 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_OUTLINE_H+#include "ftrend1.h"+#include "ftraster.h"+#include "rastpic.h"++#include "rasterrs.h"+++  /* initialize renderer -- init its raster */+  static FT_Error+  ft_raster1_init( FT_Renderer  render )+  {+    FT_Library  library = FT_MODULE_LIBRARY( render );+++    render->clazz->raster_class->raster_reset( render->raster,+                                               library->raster_pool,+                                               library->raster_pool_size );++    return Raster_Err_Ok;+  }+++  /* set render-specific mode */+  static FT_Error+  ft_raster1_set_mode( FT_Renderer  render,+                       FT_ULong     mode_tag,+                       FT_Pointer   data )+  {+    /* we simply pass it to the raster */+    return render->clazz->raster_class->raster_set_mode( render->raster,+                                                         mode_tag,+                                                         data );+  }+++  /* transform a given glyph image */+  static FT_Error+  ft_raster1_transform( FT_Renderer       render,+                        FT_GlyphSlot      slot,+                        const FT_Matrix*  matrix,+                        const FT_Vector*  delta )+  {+    FT_Error error = Raster_Err_Ok;+++    if ( slot->format != render->glyph_format )+    {+      error = Raster_Err_Invalid_Argument;+      goto Exit;+    }++    if ( matrix )+      FT_Outline_Transform( &slot->outline, matrix );++    if ( delta )+      FT_Outline_Translate( &slot->outline, delta->x, delta->y );++  Exit:+    return error;+  }+++  /* return the glyph's control box */+  static void+  ft_raster1_get_cbox( FT_Renderer   render,+                       FT_GlyphSlot  slot,+                       FT_BBox*      cbox )+  {+    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );++    if ( slot->format == render->glyph_format )+      FT_Outline_Get_CBox( &slot->outline, cbox );+  }+++  /* convert a slot's glyph image into a bitmap */+  static FT_Error+  ft_raster1_render( FT_Renderer       render,+                     FT_GlyphSlot      slot,+                     FT_Render_Mode    mode,+                     const FT_Vector*  origin )+  {+    FT_Error     error;+    FT_Outline*  outline;+    FT_BBox      cbox;+    FT_UInt      width, height, pitch;+    FT_Bitmap*   bitmap;+    FT_Memory    memory;++    FT_Raster_Params  params;+++    /* check glyph image format */+    if ( slot->format != render->glyph_format )+    {+      error = Raster_Err_Invalid_Argument;+      goto Exit;+    }++    /* check rendering mode */+#ifndef FT_CONFIG_OPTION_PIC+    if ( mode != FT_RENDER_MODE_MONO )+    {+      /* raster1 is only capable of producing monochrome bitmaps */+      if ( render->clazz == &ft_raster1_renderer_class )+        return Raster_Err_Cannot_Render_Glyph;+    }+    else+    {+      /* raster5 is only capable of producing 5-gray-levels bitmaps */+      if ( render->clazz == &ft_raster5_renderer_class )+        return Raster_Err_Cannot_Render_Glyph;+    }+#else /* FT_CONFIG_OPTION_PIC */+    /* When PIC is enabled, we cannot get to the class object      */+    /* so instead we check the final character in the class name   */+    /* ("raster5" or "raster1"). Yes this is a hack.               */+    /* The "correct" thing to do is have different render function */+    /* for each of the classes.                                    */+    if ( mode != FT_RENDER_MODE_MONO )+    {+      /* raster1 is only capable of producing monochrome bitmaps */+      if ( render->clazz->root.module_name[6] == '1' )+        return Raster_Err_Cannot_Render_Glyph;+    }+    else+    {+      /* raster5 is only capable of producing 5-gray-levels bitmaps */+      if ( render->clazz->root.module_name[6] == '5' )+        return Raster_Err_Cannot_Render_Glyph;+    }+#endif /* FT_CONFIG_OPTION_PIC */++    outline = &slot->outline;++    /* translate the outline to the new origin if needed */+    if ( origin )+      FT_Outline_Translate( outline, origin->x, origin->y );++    /* compute the control box, and grid fit it */+    FT_Outline_Get_CBox( outline, &cbox );++    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );+    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );+    cbox.xMax = FT_PIX_CEIL( cbox.xMax );+    cbox.yMax = FT_PIX_CEIL( cbox.yMax );++    width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );+    height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );+    bitmap = &slot->bitmap;+    memory = render->root.memory;++    /* release old bitmap buffer */+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )+    {+      FT_FREE( bitmap->buffer );+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;+    }++    /* allocate new one, depends on pixel format */+    if ( !( mode & FT_RENDER_MODE_MONO ) )+    {+      /* we pad to 32 bits, only for backwards compatibility with FT 1.x */+      pitch              = FT_PAD_CEIL( width, 4 );+      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;+      bitmap->num_grays  = 256;+    }+    else+    {+      pitch              = ( ( width + 15 ) >> 4 ) << 1;+      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;+    }++    bitmap->width = width;+    bitmap->rows  = height;+    bitmap->pitch = pitch;++    if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) )+      goto Exit;++    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;++    /* translate outline to render it into the bitmap */+    FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );++    /* set up parameters */+    params.target = bitmap;+    params.source = outline;+    params.flags  = 0;++    if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY )+      params.flags |= FT_RASTER_FLAG_AA;++    /* render outline into the bitmap */+    error = render->raster_render( render->raster, &params );++    FT_Outline_Translate( outline, cbox.xMin, cbox.yMin );++    if ( error )+      goto Exit;++    slot->format      = FT_GLYPH_FORMAT_BITMAP;+    slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 );+    slot->bitmap_top  = (FT_Int)( cbox.yMax >> 6 );++  Exit:+    return error;+  }+++  FT_DEFINE_RENDERER(ft_raster1_renderer_class,+    +      FT_MODULE_RENDERER,+      sizeof( FT_RendererRec ),++      "raster1",+      0x10000L,+      0x20000L,++      0,    /* module specific interface */++      (FT_Module_Constructor)ft_raster1_init,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  0+    ,++    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Renderer_RenderFunc)   ft_raster1_render,+    (FT_Renderer_TransformFunc)ft_raster1_transform,+    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,+    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,++    (FT_Raster_Funcs*)    &FT_STANDARD_RASTER_GET+  )+++  /* This renderer is _NOT_ part of the default modules; you will need */+  /* to register it by hand in your application.  It should only be    */+  /* used for backwards-compatibility with FT 1.x anyway.              */+  /*                                                                   */+  FT_DEFINE_RENDERER(ft_raster5_renderer_class,+  +    +      FT_MODULE_RENDERER,+      sizeof( FT_RendererRec ),++      "raster5",+      0x10000L,+      0x20000L,++      0,    /* module specific interface */++      (FT_Module_Constructor)ft_raster1_init,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  0+    ,++    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Renderer_RenderFunc)   ft_raster1_render,+    (FT_Renderer_TransformFunc)ft_raster1_transform,+    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,+    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,++    (FT_Raster_Funcs*)    &FT_STANDARD_RASTER_GET+  )+++/* END */
+ src/raster/ftrend1.h view
@@ -0,0 +1,44 @@+/***************************************************************************/+/*                                                                         */+/*  ftrend1.h                                                              */+/*                                                                         */+/*    The FreeType glyph rasterizer interface (specification).             */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTREND1_H__+#define __FTREND1_H__+++#include <ft2build.h>+#include FT_RENDER_H+++FT_BEGIN_HEADER+++  FT_DECLARE_RENDERER( ft_raster1_renderer_class )++  /* this renderer is _NOT_ part of the default modules, you'll need */+  /* to register it by hand in your application.  It should only be  */+  /* used for backwards-compatibility with FT 1.x anyway.            */+  /*                                                                 */+  FT_DECLARE_RENDERER( ft_raster5_renderer_class )+++FT_END_HEADER++#endif /* __FTREND1_H__ */+++/* END */
+ src/raster/raster.c view
@@ -0,0 +1,27 @@+/***************************************************************************/+/*                                                                         */+/*  raster.c                                                               */+/*                                                                         */+/*    FreeType monochrome rasterer module component (body only).           */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "rastpic.c"+#include "ftraster.c"+#include "ftrend1.c"+++/* END */
+ src/raster/rasterrs.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  rasterrs.h                                                             */+/*                                                                         */+/*    monochrome renderer error codes (specification only).                */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the monochrome renderer error enumeration */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __RASTERRS_H__+#define __RASTERRS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  Raster_Err_+#define FT_ERR_BASE    FT_Mod_Err_Raster++#include FT_ERRORS_H++#endif /* __RASTERRS_H__ */+++/* END */
+ src/raster/rastpic.c view
@@ -0,0 +1,90 @@+/***************************************************************************/+/*                                                                         */+/*  rastpic.c                                                              */+/*                                                                         */+/*    The FreeType position independent code services for raster module.   */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "rastpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from ftraster.c */+  void FT_Init_Class_ft_standard_raster(FT_Raster_Funcs*);++  void+  ft_raster1_renderer_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->raster )+    {+      RasterPIC* container = (RasterPIC*)pic_container->raster;+      if(--container->ref_count)+        return;+      FT_FREE( container );+      pic_container->raster = NULL;+    }+  }+++  FT_Error+  ft_raster1_renderer_class_pic_init( FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Error          error         = Raster_Err_Ok;+    RasterPIC*        container;+    FT_Memory         memory        = library->memory;+++    /* since this function also serve raster5 renderer, +       it implements reference counting */+    if ( pic_container->raster )+    {+      ((RasterPIC*)pic_container->raster)->ref_count++;+      return error;+    }++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof(*container) );+    pic_container->raster = container;+    container->ref_count = 1;++    /* initialize pointer table - this is how the module usually expects this data */+    FT_Init_Class_ft_standard_raster(&container->ft_standard_raster);+/*Exit:*/+    if(error)+      ft_raster1_renderer_class_pic_free(library);+    return error;+  }++  /* re-route these init and free functions to the above functions */+  FT_Error ft_raster5_renderer_class_pic_init(FT_Library library)+  {+    return ft_raster1_renderer_class_pic_init(library);+  }+  void ft_raster5_renderer_class_pic_free(FT_Library library)+  {+    ft_raster1_renderer_class_pic_free(library);+  }++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/raster/rastpic.h view
@@ -0,0 +1,50 @@+/***************************************************************************/+/*                                                                         */+/*  rastpic.h                                                              */+/*                                                                         */+/*    The FreeType position independent code services for raster module.   */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __RASTPIC_H__+#define __RASTPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC+#define FT_STANDARD_RASTER_GET     ft_standard_raster++#else /* FT_CONFIG_OPTION_PIC */++  typedef struct RasterPIC_+  {+    int ref_count;+    FT_Raster_Funcs ft_standard_raster;+  } RasterPIC;++#define GET_PIC(lib)               ((RasterPIC*)((lib)->pic_container.raster))+#define FT_STANDARD_RASTER_GET     (GET_PIC(library)->ft_standard_raster)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __RASTPIC_H__ */+++/* END */
+ src/sfnt/sfdriver.c view
@@ -0,0 +1,651 @@+/***************************************************************************/+/*                                                                         */+/*  sfdriver.c                                                             */+/*                                                                         */+/*    High-level SFNT driver interface (body).                             */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_SFNT_H+#include FT_INTERNAL_OBJECTS_H++#include "sfdriver.h"+#include "ttload.h"+#include "sfobjs.h"+#include "sfntpic.h"++#include "sferrors.h"++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+#include "ttsbit.h"+#endif++#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+#include "ttpost.h"+#endif++#ifdef TT_CONFIG_OPTION_BDF+#include "ttbdf.h"+#include FT_SERVICE_BDF_H+#endif++#include "ttcmap.h"+#include "ttkern.h"+#include "ttmtx.h"++#include FT_SERVICE_GLYPH_DICT_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_SFNT_H+#include FT_SERVICE_TT_CMAP_H++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_sfdriver+++ /*+  *  SFNT TABLE SERVICE+  *+  */++  static void*+  get_sfnt_table( TT_Face      face,+                  FT_Sfnt_Tag  tag )+  {+    void*  table;+++    switch ( tag )+    {+    case ft_sfnt_head:+      table = &face->header;+      break;++    case ft_sfnt_hhea:+      table = &face->horizontal;+      break;++    case ft_sfnt_vhea:+      table = face->vertical_info ? &face->vertical : 0;+      break;++    case ft_sfnt_os2:+      table = face->os2.version == 0xFFFFU ? 0 : &face->os2;+      break;++    case ft_sfnt_post:+      table = &face->postscript;+      break;++    case ft_sfnt_maxp:+      table = &face->max_profile;+      break;++    case ft_sfnt_pclt:+      table = face->pclt.Version ? &face->pclt : 0;+      break;++    default:+      table = 0;+    }++    return table;+  }+++  static FT_Error+  sfnt_table_info( TT_Face    face,+                   FT_UInt    idx,+                   FT_ULong  *tag,+                   FT_ULong  *offset,+                   FT_ULong  *length )+  {+    if ( !tag || !offset || !length )+      return SFNT_Err_Invalid_Argument;++    if ( idx >= face->num_tables )+      return SFNT_Err_Table_Missing;++    *tag    = face->dir_tables[idx].Tag;+    *offset = face->dir_tables[idx].Offset;+    *length = face->dir_tables[idx].Length;++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,+    (FT_SFNT_TableLoadFunc)tt_face_load_any,+    (FT_SFNT_TableGetFunc) get_sfnt_table,+    (FT_SFNT_TableInfoFunc)sfnt_table_info+  )+++#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES++ /*+  *  GLYPH DICT SERVICE+  *+  */++  static FT_Error+  sfnt_get_glyph_name( TT_Face     face,+                       FT_UInt     glyph_index,+                       FT_Pointer  buffer,+                       FT_UInt     buffer_max )+  {+    FT_String*  gname;+    FT_Error    error;+++    error = tt_face_get_ps_name( face, glyph_index, &gname );+    if ( !error )+      FT_STRCPYN( buffer, gname, buffer_max );++    return error;+  }+++  static FT_UInt+  sfnt_get_name_index( TT_Face     face,+                       FT_String*  glyph_name )+  {+    FT_Face   root = &face->root;+    FT_UInt   i, max_gid = FT_UINT_MAX;+++    if ( root->num_glyphs < 0 )+      return 0;+    else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )+      max_gid = ( FT_UInt ) root->num_glyphs;+    else+      FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",+         FT_UINT_MAX, root->num_glyphs ));++    for ( i = 0; i < max_gid; i++ )+    {+      FT_String*  gname;+      FT_Error    error = tt_face_get_ps_name( face, i, &gname );+++      if ( error )+        continue;++      if ( !ft_strcmp( glyph_name, gname ) )+        return i;+    }++    return 0;+  }+++  FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,+    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,+    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index+  )++#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */+++ /*+  *  POSTSCRIPT NAME SERVICE+  *+  */++  static const char*+  sfnt_get_ps_name( TT_Face  face )+  {+    FT_Int       n, found_win, found_apple;+    const char*  result = NULL;+++    /* shouldn't happen, but just in case to avoid memory leaks */+    if ( face->postscript_name )+      return face->postscript_name;++    /* scan the name table to see whether we have a Postscript name here, */+    /* either in Macintosh or Windows platform encodings                  */+    found_win   = -1;+    found_apple = -1;++    for ( n = 0; n < face->num_names; n++ )+    {+      TT_NameEntryRec*  name = face->name_table.names + n;+++      if ( name->nameID == 6 && name->stringLength > 0 )+      {+        if ( name->platformID == 3     &&+             name->encodingID == 1     &&+             name->languageID == 0x409 )+          found_win = n;++        if ( name->platformID == 1 &&+             name->encodingID == 0 &&+             name->languageID == 0 )+          found_apple = n;+      }+    }++    if ( found_win != -1 )+    {+      FT_Memory         memory = face->root.memory;+      TT_NameEntryRec*  name   = face->name_table.names + found_win;+      FT_UInt           len    = name->stringLength / 2;+      FT_Error          error  = SFNT_Err_Ok;++      FT_UNUSED( error );+++      if ( !FT_ALLOC( result, name->stringLength + 1 ) )+      {+        FT_Stream   stream = face->name_table.stream;+        FT_String*  r      = (FT_String*)result;+        FT_Byte*    p      = (FT_Byte*)name->string;+++        if ( FT_STREAM_SEEK( name->stringOffset ) ||+             FT_FRAME_ENTER( name->stringLength ) )+        {+          FT_FREE( result );+          name->stringLength = 0;+          name->stringOffset = 0;+          FT_FREE( name->string );++          goto Exit;+        }++        p = (FT_Byte*)stream->cursor;++        for ( ; len > 0; len--, p += 2 )+        {+          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )+            *r++ = p[1];+        }+        *r = '\0';++        FT_FRAME_EXIT();+      }+      goto Exit;+    }++    if ( found_apple != -1 )+    {+      FT_Memory         memory = face->root.memory;+      TT_NameEntryRec*  name   = face->name_table.names + found_apple;+      FT_UInt           len    = name->stringLength;+      FT_Error          error  = SFNT_Err_Ok;++      FT_UNUSED( error );+++      if ( !FT_ALLOC( result, len + 1 ) )+      {+        FT_Stream  stream = face->name_table.stream;+++        if ( FT_STREAM_SEEK( name->stringOffset ) ||+             FT_STREAM_READ( result, len )        )+        {+          name->stringOffset = 0;+          name->stringLength = 0;+          FT_FREE( name->string );+          FT_FREE( result );+          goto Exit;+        }+        ((char*)result)[len] = '\0';+      }+    }++  Exit:+    face->postscript_name = result;+    return result;+  }++  FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,+    (FT_PsName_GetFunc)sfnt_get_ps_name+  )+++  /*+   *  TT CMAP INFO+   */+  FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,+    (TT_CMap_Info_GetFunc)tt_get_cmap_info+  )+++#ifdef TT_CONFIG_OPTION_BDF++  static FT_Error+  sfnt_get_charset_id( TT_Face       face,+                       const char*  *acharset_encoding,+                       const char*  *acharset_registry )+  {+    BDF_PropertyRec  encoding, registry;+    FT_Error         error;+++    /* XXX: I don't know whether this is correct, since+     *      tt_face_find_bdf_prop only returns something correct if we have+     *      previously selected a size that is listed in the BDF table.+     *      Should we change the BDF table format to include single offsets+     *      for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?+     */+    error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );+    if ( !error )+    {+      error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );+      if ( !error )+      {+        if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&+             encoding.type == BDF_PROPERTY_TYPE_ATOM )+        {+          *acharset_encoding = encoding.u.atom;+          *acharset_registry = registry.u.atom;+        }+        else+          error = SFNT_Err_Invalid_Argument;+      }+    }++    return error;+  }+++  FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,+    (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,+    (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop+  )++#endif /* TT_CONFIG_OPTION_BDF */+++  /*+   *  SERVICE LIST+   */++#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF+  FT_DEFINE_SERVICEDESCREC5(sfnt_services,+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,+    FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET+  )+#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES+  FT_DEFINE_SERVICEDESCREC4(sfnt_services,+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET+  )+#elif defined TT_CONFIG_OPTION_BDF+  FT_DEFINE_SERVICEDESCREC4(sfnt_services,+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET+  )+#else+  FT_DEFINE_SERVICEDESCREC3(sfnt_services,+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET+  )+#endif+++  FT_CALLBACK_DEF( FT_Module_Interface )+  sfnt_get_interface( FT_Module    module,+                      const char*  module_interface )+  {+    FT_UNUSED( module );++    return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );+  }+++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_CALLBACK_DEF( FT_Error )+  tt_face_load_sfnt_header_stub( TT_Face      face,+                                 FT_Stream    stream,+                                 FT_Long      face_index,+                                 SFNT_Header  header )+  {+    FT_UNUSED( face );+    FT_UNUSED( stream );+    FT_UNUSED( face_index );+    FT_UNUSED( header );++    return SFNT_Err_Unimplemented_Feature;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_load_directory_stub( TT_Face      face,+                               FT_Stream    stream,+                               SFNT_Header  header )+  {+    FT_UNUSED( face );+    FT_UNUSED( stream );+    FT_UNUSED( header );++    return SFNT_Err_Unimplemented_Feature;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_load_hdmx_stub( TT_Face    face,+                          FT_Stream  stream )+  {+    FT_UNUSED( face );+    FT_UNUSED( stream );++    return SFNT_Err_Unimplemented_Feature;+  }+++  FT_CALLBACK_DEF( void )+  tt_face_free_hdmx_stub( TT_Face  face )+  {+    FT_UNUSED( face );+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_set_sbit_strike_stub( TT_Face    face,+                                FT_UInt    x_ppem,+                                FT_UInt    y_ppem,+                                FT_ULong*  astrike_index )+  {+    /*+     * We simply forge a FT_Size_Request and call the real function+     * that does all the work.+     *+     * This stub might be called by libXfont in the X.Org Xserver,+     * compiled against version 2.1.8 or newer.+     */++    FT_Size_RequestRec  req;+++    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;+    req.width          = (FT_F26Dot6)x_ppem;+    req.height         = (FT_F26Dot6)y_ppem;+    req.horiResolution = 0;+    req.vertResolution = 0;++    *astrike_index = 0x7FFFFFFFUL;++    return tt_face_set_sbit_strike( face, &req, astrike_index );+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_load_sbit_stub( TT_Face    face,+                          FT_Stream  stream )+  {+    FT_UNUSED( face );+    FT_UNUSED( stream );++    /*+     *  This function was originally implemented to load the sbit table.+     *  However, it has been replaced by `tt_face_load_eblc', and this stub+     *  is only there for some rogue clients which would want to call it+     *  directly (which doesn't make much sense).+     */+    return SFNT_Err_Unimplemented_Feature;+  }+++  FT_CALLBACK_DEF( void )+  tt_face_free_sbit_stub( TT_Face  face )+  {+    /* nothing to do in this stub */+    FT_UNUSED( face );+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_load_charmap_stub( TT_Face    face,+                             void*      cmap,+                             FT_Stream  input )+  {+    FT_UNUSED( face );+    FT_UNUSED( cmap );+    FT_UNUSED( input );++    return SFNT_Err_Unimplemented_Feature;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_face_free_charmap_stub( TT_Face  face,+                             void*    cmap )+  {+    FT_UNUSED( face );+    FT_UNUSED( cmap );++    return SFNT_Err_Ok;+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+#define PUT_EMBEDDED_BITMAPS(a) a +#else+#define PUT_EMBEDDED_BITMAPS(a) 0 +#endif+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+#define PUT_PS_NAMES(a) a +#else+#define PUT_PS_NAMES(a) 0 +#endif++  FT_DEFINE_SFNT_INTERFACE(sfnt_interface,+    tt_face_goto_table,++    sfnt_init_face,+    sfnt_load_face,+    sfnt_done_face,+    sfnt_get_interface,++    tt_face_load_any,++    tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    tt_face_load_head,+    tt_face_load_hhea,+    tt_face_load_cmap,+    tt_face_load_maxp,+    tt_face_load_os2,+    tt_face_load_post,++    tt_face_load_name,+    tt_face_free_name,++    tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    tt_face_load_kern,+    tt_face_load_gasp,+    tt_face_load_pclt,++    /* see `ttload.h' */+    PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),++    tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),++    tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    /* see `ttpost.h' */+    PUT_PS_NAMES(tt_face_get_ps_name),+    PUT_PS_NAMES(tt_face_free_ps_names),++    tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    /* since version 2.1.8 */++    tt_face_get_kerning,++    /* since version 2.2 */++    tt_face_load_font_dir,+    tt_face_load_hmtx,++    /* see `ttsbit.h' and `sfnt.h' */+    PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),+    PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),++    PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),+    PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),++    tt_face_get_metrics+  )+++  FT_DEFINE_MODULE(sfnt_module_class,+  +    0,  /* not a font driver or renderer */+    sizeof( FT_ModuleRec ),++    "sfnt",     /* driver name                            */+    0x10000L,   /* driver version 1.0                     */+    0x20000L,   /* driver requires FreeType 2.0 or higher */++    (const void*)&FT_SFNT_INTERFACE_GET,  /* module specific interface */++    (FT_Module_Constructor)0,+    (FT_Module_Destructor) 0,+    (FT_Module_Requester)  sfnt_get_interface+  )+++/* END */
+ src/sfnt/sfdriver.h view
@@ -0,0 +1,38 @@+/***************************************************************************/+/*                                                                         */+/*  sfdriver.h                                                             */+/*                                                                         */+/*    High-level SFNT driver interface (specification).                    */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SFDRIVER_H__+#define __SFDRIVER_H__+++#include <ft2build.h>+#include FT_MODULE_H+++FT_BEGIN_HEADER+++  FT_DECLARE_MODULE( sfnt_module_class )+++FT_END_HEADER++#endif /* __SFDRIVER_H__ */+++/* END */
+ src/sfnt/sferrors.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  sferrors.h                                                             */+/*                                                                         */+/*    SFNT error codes (specification only).                               */+/*                                                                         */+/*  Copyright 2001, 2004 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the SFNT error enumeration constants.     */+  /*                                                                       */+  /*************************************************************************/++#ifndef __SFERRORS_H__+#define __SFERRORS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  SFNT_Err_+#define FT_ERR_BASE    FT_Mod_Err_SFNT++#define FT_KEEP_ERR_PREFIX++#include FT_ERRORS_H++#endif /* __SFERRORS_H__ */++/* END */
+ src/sfnt/sfnt.c view
@@ -0,0 +1,42 @@+/***************************************************************************/+/*                                                                         */+/*  sfnt.c                                                                 */+/*                                                                         */+/*    Single object library component.                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by                   */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "sfntpic.c"+#include "ttload.c"+#include "ttmtx.c"+#include "ttcmap.c"+#include "ttkern.c"+#include "sfobjs.c"+#include "sfdriver.c"++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+#include "ttsbit.c"+#endif++#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+#include "ttpost.c"+#endif++#ifdef TT_CONFIG_OPTION_BDF+#include "ttbdf.c"+#endif++/* END */
+ src/sfnt/sfntpic.c view
@@ -0,0 +1,102 @@+/***************************************************************************/+/*                                                                         */+/*  sfntpic.c                                                              */+/*                                                                         */+/*    The FreeType position independent code services for sfnt module.     */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "sfntpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from sfdriver.c */+  FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**);+  void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*);+  void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*);+  void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*);+  void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*);+  void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*);+  void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*);+  void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*);++  /* forward declaration of PIC init functions from ttcmap.c */+  FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**);+  void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*);++  void+  sfnt_module_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->sfnt )+    {+      sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt;+      if(container->sfnt_services)+        FT_Destroy_Class_sfnt_services(library, container->sfnt_services);+      container->sfnt_services = NULL;+      if(container->tt_cmap_classes)+        FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes);+      container->tt_cmap_classes = NULL;+      FT_FREE( container );+      pic_container->sfnt = NULL;+    }+  }+++  FT_Error+  sfnt_module_class_pic_init(  FT_Library library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error = SFNT_Err_Ok;+    sfntModulePIC*     container;+    FT_Memory          memory = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof ( *container ) );+    pic_container->sfnt = container;++    /* initialize pointer table - this is how the module usually expects this data */+    error = FT_Create_Class_sfnt_services(library, &container->sfnt_services);+    if(error) +      goto Exit;+    error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes);+    if(error) +      goto Exit;+    FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict);+    FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name);+    FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info);+    FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table);+#ifdef TT_CONFIG_OPTION_BDF+    FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf);+#endif+    FT_Init_Class_sfnt_interface(library, &container->sfnt_interface);++Exit:+    if(error)+      sfnt_module_class_pic_free(library);+    return error;+  }++++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/sfnt/sfntpic.h view
@@ -0,0 +1,88 @@+/***************************************************************************/+/*                                                                         */+/*  sfntpic.h                                                              */+/*                                                                         */+/*    The FreeType position independent code services for sfnt module.     */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SFNTPIC_H__+#define __SFNTPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++ #ifndef FT_CONFIG_OPTION_PIC+#define FT_SFNT_SERVICES_GET             sfnt_services+#define FT_SFNT_SERVICE_GLYPH_DICT_GET   sfnt_service_glyph_dict+#define FT_SFNT_SERVICE_PS_NAME_GET      sfnt_service_ps_name+#define FT_TT_SERVICE_GET_CMAP_INFO_GET  tt_service_get_cmap_info+#define FT_SFNT_SERVICES_GET             sfnt_services+#define FT_TT_CMAP_CLASSES_GET           tt_cmap_classes+#define FT_SFNT_SERVICE_SFNT_TABLE_GET   sfnt_service_sfnt_table+#define FT_SFNT_SERVICE_BDF_GET          sfnt_service_bdf+#define FT_SFNT_INTERFACE_GET            sfnt_interface++#else /* FT_CONFIG_OPTION_PIC */++/* some include files required for members of sfntModulePIC */+#include FT_SERVICE_GLYPH_DICT_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_SFNT_H+#include FT_SERVICE_TT_CMAP_H+#ifdef TT_CONFIG_OPTION_BDF+#include "ttbdf.h"+#include FT_SERVICE_BDF_H+#endif+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include "ttcmap.h"++typedef struct sfntModulePIC_+  {+    FT_ServiceDescRec* sfnt_services;+    FT_Service_GlyphDictRec sfnt_service_glyph_dict;+    FT_Service_PsFontNameRec  sfnt_service_ps_name;+    FT_Service_TTCMapsRec  tt_service_get_cmap_info;+    TT_CMap_Class* tt_cmap_classes;+    FT_Service_SFNT_TableRec sfnt_service_sfnt_table;+#ifdef TT_CONFIG_OPTION_BDF+    FT_Service_BDFRec sfnt_service_bdf;+#endif+    SFNT_Interface sfnt_interface;+  } sfntModulePIC;++#define GET_PIC(lib)                      ((sfntModulePIC*)((lib)->pic_container.sfnt))+#define FT_SFNT_SERVICES_GET              (GET_PIC(library)->sfnt_services)+#define FT_SFNT_SERVICE_GLYPH_DICT_GET    (GET_PIC(library)->sfnt_service_glyph_dict)+#define FT_SFNT_SERVICE_PS_NAME_GET       (GET_PIC(library)->sfnt_service_ps_name)+#define FT_TT_SERVICE_GET_CMAP_INFO_GET   (GET_PIC(library)->tt_service_get_cmap_info)+#define FT_SFNT_SERVICES_GET              (GET_PIC(library)->sfnt_services)+#define FT_TT_CMAP_CLASSES_GET            (GET_PIC(library)->tt_cmap_classes)+#define FT_SFNT_SERVICE_SFNT_TABLE_GET    (GET_PIC(library)->sfnt_service_sfnt_table)+#define FT_SFNT_SERVICE_BDF_GET           (GET_PIC(library)->sfnt_service_bdf)+#define FT_SFNT_INTERFACE_GET             (GET_PIC(library)->sfnt_interface)++#endif /* FT_CONFIG_OPTION_PIC */++/* */++FT_END_HEADER++#endif /* __SFNTPIC_H__ */+++/* END */
+ src/sfnt/sfobjs.c view
@@ -0,0 +1,1147 @@+/***************************************************************************/+/*                                                                         */+/*  sfobjs.c                                                               */+/*                                                                         */+/*    SFNT object management (base).                                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "sfobjs.h"+#include "ttload.h"+#include "ttcmap.h"+#include "ttkern.h"+#include FT_INTERNAL_SFNT_H+#include FT_INTERNAL_DEBUG_H+#include FT_TRUETYPE_IDS_H+#include FT_TRUETYPE_TAGS_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_SFNT_NAMES_H+#include "sferrors.h"++#ifdef TT_CONFIG_OPTION_BDF+#include "ttbdf.h"+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_sfobjs++++  /* convert a UTF-16 name entry to ASCII */+  static FT_String*+  tt_name_entry_ascii_from_utf16( TT_NameEntry  entry,+                                  FT_Memory     memory )+  {+    FT_String*  string = NULL;+    FT_UInt     len, code, n;+    FT_Byte*    read   = (FT_Byte*)entry->string;+    FT_Error    error;+++    len = (FT_UInt)entry->stringLength / 2;++    if ( FT_NEW_ARRAY( string, len + 1 ) )+      return NULL;++    for ( n = 0; n < len; n++ )+    {+      code = FT_NEXT_USHORT( read );+      if ( code < 32 || code > 127 )+        code = '?';++      string[n] = (char)code;+    }++    string[len] = 0;++    return string;+  }+++  /* convert an Apple Roman or symbol name entry to ASCII */+  static FT_String*+  tt_name_entry_ascii_from_other( TT_NameEntry  entry,+                                  FT_Memory     memory )+  {+    FT_String*  string = NULL;+    FT_UInt     len, code, n;+    FT_Byte*    read   = (FT_Byte*)entry->string;+    FT_Error    error;+++    len = (FT_UInt)entry->stringLength;++    if ( FT_NEW_ARRAY( string, len + 1 ) )+      return NULL;++    for ( n = 0; n < len; n++ )+    {+      code = *read++;+      if ( code < 32 || code > 127 )+        code = '?';++      string[n] = (char)code;+    }++    string[len] = 0;++    return string;+  }+++  typedef FT_String*  (*TT_NameEntry_ConvertFunc)( TT_NameEntry  entry,+                                                   FT_Memory     memory );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_get_name                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Returns a given ENGLISH name record in ASCII.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the source face object.                      */+  /*                                                                       */+  /*    nameid :: The name id of the name record to return.                */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    name   :: The address of a string pointer.  NULL if no name is     */+  /*              present.                                                 */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  tt_face_get_name( TT_Face      face,+                    FT_UShort    nameid,+                    FT_String**  name )+  {+    FT_Memory         memory = face->root.memory;+    FT_Error          error  = SFNT_Err_Ok;+    FT_String*        result = NULL;+    FT_UShort         n;+    TT_NameEntryRec*  rec;+    FT_Int            found_apple         = -1;+    FT_Int            found_apple_roman   = -1;+    FT_Int            found_apple_english = -1;+    FT_Int            found_win           = -1;+    FT_Int            found_unicode       = -1;++    FT_Bool           is_english = 0;++    TT_NameEntry_ConvertFunc  convert;+++    FT_ASSERT( name );++    rec = face->name_table.names;+    for ( n = 0; n < face->num_names; n++, rec++ )+    {+      /* According to the OpenType 1.3 specification, only Microsoft or  */+      /* Apple platform IDs might be used in the `name' table.  The      */+      /* `Unicode' platform is reserved for the `cmap' table, and the    */+      /* `ISO' one is deprecated.                                        */+      /*                                                                 */+      /* However, the Apple TrueType specification doesn't say the same  */+      /* thing and goes to suggest that all Unicode `name' table entries */+      /* should be coded in UTF-16 (in big-endian format I suppose).     */+      /*                                                                 */+      if ( rec->nameID == nameid && rec->stringLength > 0 )+      {+        switch ( rec->platformID )+        {+        case TT_PLATFORM_APPLE_UNICODE:+        case TT_PLATFORM_ISO:+          /* there is `languageID' to check there.  We should use this */+          /* field only as a last solution when nothing else is        */+          /* available.                                                */+          /*                                                           */+          found_unicode = n;+          break;++        case TT_PLATFORM_MACINTOSH:+          /* This is a bit special because some fonts will use either    */+          /* an English language id, or a Roman encoding id, to indicate */+          /* the English version of its font name.                       */+          /*                                                             */+          if ( rec->languageID == TT_MAC_LANGID_ENGLISH )+            found_apple_english = n;+          else if ( rec->encodingID == TT_MAC_ID_ROMAN )+            found_apple_roman = n;+          break;++        case TT_PLATFORM_MICROSOFT:+          /* we only take a non-English name when there is nothing */+          /* else available in the font                            */+          /*                                                       */+          if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )+          {+            switch ( rec->encodingID )+            {+            case TT_MS_ID_SYMBOL_CS:+            case TT_MS_ID_UNICODE_CS:+            case TT_MS_ID_UCS_4:+              is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );+              found_win  = n;+              break;++            default:+              ;+            }+          }+          break;++        default:+          ;+        }+      }+    }++    found_apple = found_apple_roman;+    if ( found_apple_english >= 0 )+      found_apple = found_apple_english;++    /* some fonts contain invalid Unicode or Macintosh formatted entries; */+    /* we will thus favor names encoded in Windows formats if available   */+    /* (provided it is an English name)                                   */+    /*                                                                    */+    convert = NULL;+    if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )+    {+      rec = face->name_table.names + found_win;+      switch ( rec->encodingID )+      {+        /* all Unicode strings are encoded using UTF-16BE */+      case TT_MS_ID_UNICODE_CS:+      case TT_MS_ID_SYMBOL_CS:+        convert = tt_name_entry_ascii_from_utf16;+        break;++      case TT_MS_ID_UCS_4:+        /* Apparently, if this value is found in a name table entry, it is */+        /* documented as `full Unicode repertoire'.  Experience with the   */+        /* MsGothic font shipped with Windows Vista shows that this really */+        /* means UTF-16 encoded names (UCS-4 values are only used within   */+        /* charmaps).                                                      */+        convert = tt_name_entry_ascii_from_utf16;+        break;++      default:+        ;+      }+    }+    else if ( found_apple >= 0 )+    {+      rec     = face->name_table.names + found_apple;+      convert = tt_name_entry_ascii_from_other;+    }+    else if ( found_unicode >= 0 )+    {+      rec     = face->name_table.names + found_unicode;+      convert = tt_name_entry_ascii_from_utf16;+    }++    if ( rec && convert )+    {+      if ( rec->string == NULL )+      {+        FT_Stream  stream = face->name_table.stream;+++        if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||+             FT_STREAM_SEEK( rec->stringOffset )              ||+             FT_STREAM_READ( rec->string, rec->stringLength ) )+        {+          FT_FREE( rec->string );+          rec->stringLength = 0;+          result            = NULL;+          goto Exit;+        }+      }++      result = convert( rec, memory );+    }++  Exit:+    *name = result;+    return error;+  }+++  static FT_Encoding+  sfnt_find_encoding( int  platform_id,+                      int  encoding_id )+  {+    typedef struct  TEncoding_+    {+      int          platform_id;+      int          encoding_id;+      FT_Encoding  encoding;++    } TEncoding;++    static+    const TEncoding  tt_encodings[] =+    {+      { TT_PLATFORM_ISO,           -1,                  FT_ENCODING_UNICODE },++      { TT_PLATFORM_APPLE_UNICODE, -1,                  FT_ENCODING_UNICODE },++      { TT_PLATFORM_MACINTOSH,     TT_MAC_ID_ROMAN,     FT_ENCODING_APPLE_ROMAN },++      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SYMBOL_CS,  FT_ENCODING_MS_SYMBOL },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UCS_4,      FT_ENCODING_UNICODE },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SJIS,       FT_ENCODING_SJIS },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_GB2312,     FT_ENCODING_GB2312 },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_BIG_5,      FT_ENCODING_BIG5 },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_WANSUNG,    FT_ENCODING_WANSUNG },+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,      FT_ENCODING_JOHAB }+    };++    const TEncoding  *cur, *limit;+++    cur   = tt_encodings;+    limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );++    for ( ; cur < limit; cur++ )+    {+      if ( cur->platform_id == platform_id )+      {+        if ( cur->encoding_id == encoding_id ||+             cur->encoding_id == -1          )+          return cur->encoding;+      }+    }++    return FT_ENCODING_NONE;+  }+++  /* Fill in face->ttc_header.  If the font is not a TTC, it is */+  /* synthesized into a TTC with one offset table.              */+  static FT_Error+  sfnt_open_font( FT_Stream  stream,+                  TT_Face    face )+  {+    FT_Memory  memory = stream->memory;+    FT_Error   error;+    FT_ULong   tag, offset;++    static const FT_Frame_Field  ttc_header_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TTC_HeaderRec++      FT_FRAME_START( 8 ),+        FT_FRAME_LONG( version ),+        FT_FRAME_LONG( count   ),+      FT_FRAME_END+    };+++    face->ttc_header.tag     = 0;+    face->ttc_header.version = 0;+    face->ttc_header.count   = 0;++    offset = FT_STREAM_POS();++    if ( FT_READ_ULONG( tag ) )+      return error;++    if ( tag != 0x00010000UL &&+         tag != TTAG_ttcf    &&+         tag != TTAG_OTTO    &&+         tag != TTAG_true    &&+         tag != TTAG_typ1    &&+         tag != 0x00020000UL )+      return SFNT_Err_Unknown_File_Format;++    face->ttc_header.tag = TTAG_ttcf;++    if ( tag == TTAG_ttcf )+    {+      FT_Int  n;+++      FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));++      if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )+        return error;++      /* now read the offsets of each font in the file */+      if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )+        return error;++      if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )+        return error;++      for ( n = 0; n < face->ttc_header.count; n++ )+        face->ttc_header.offsets[n] = FT_GET_ULONG();++      FT_FRAME_EXIT();+    }+    else+    {+      FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));++      face->ttc_header.version = 1 << 16;+      face->ttc_header.count   = 1;++      if ( FT_NEW( face->ttc_header.offsets ) )+        return error;++      face->ttc_header.offsets[0] = offset;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  sfnt_init_face( FT_Stream      stream,+                  TT_Face        face,+                  FT_Int         face_index,+                  FT_Int         num_params,+                  FT_Parameter*  params )+  {+    FT_Error        error;+    FT_Library      library = face->root.driver->root.library;+    SFNT_Service    sfnt;+++    /* for now, parameters are unused */+    FT_UNUSED( num_params );+    FT_UNUSED( params );+++    sfnt = (SFNT_Service)face->sfnt;+    if ( !sfnt )+    {+      sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );+      if ( !sfnt )+        return SFNT_Err_Invalid_File_Format;++      face->sfnt       = sfnt;+      face->goto_table = sfnt->goto_table;+    }++    FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );++    error = sfnt_open_font( stream, face );+    if ( error )+      return error;++    FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));++    if ( face_index < 0 )+      face_index = 0;++    if ( face_index >= face->ttc_header.count )+      return SFNT_Err_Invalid_Argument;++    if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )+      return error;++    /* check that we have a valid TrueType file */+    error = sfnt->load_font_dir( face, stream );+    if ( error )+      return error;++    face->root.num_faces  = face->ttc_header.count;+    face->root.face_index = face_index;++    return error;+  }+++#define LOAD_( x )                                            \+  do {                                                        \+    FT_TRACE2(( "`" #x "' " ));                               \+    FT_TRACE3(( "-->\n" ));                                   \+                                                              \+    error = sfnt->load_##x( face, stream );                   \+                                                              \+    FT_TRACE2(( "%s\n", ( !error )                            \+                        ? "loaded"                            \+                        : ( error == SFNT_Err_Table_Missing ) \+                          ? "missing"                         \+                          : "failed to load" ));              \+    FT_TRACE3(( "\n" ));                                      \+  } while ( 0 )++#define LOADM_( x, vertical )                                 \+  do {                                                        \+    FT_TRACE2(( "`%s" #x "' ",                                \+                vertical ? "vertical " : "" ));               \+    FT_TRACE3(( "-->\n" ));                                   \+                                                              \+    error = sfnt->load_##x( face, stream, vertical );         \+                                                              \+    FT_TRACE2(( "%s\n", ( !error )                            \+                        ? "loaded"                            \+                        : ( error == SFNT_Err_Table_Missing ) \+                          ? "missing"                         \+                          : "failed to load" ));              \+    FT_TRACE3(( "\n" ));                                      \+  } while ( 0 )++#define GET_NAME( id, field )                                 \+  do {                                                        \+    error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \+    if ( error )                                              \+      goto Exit;                                              \+  } while ( 0 )+++  FT_LOCAL_DEF( FT_Error )+  sfnt_load_face( FT_Stream      stream,+                  TT_Face        face,+                  FT_Int         face_index,+                  FT_Int         num_params,+                  FT_Parameter*  params )+  {+    FT_Error      error;+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+    FT_Error      psnames_error;+#endif+    FT_Bool       has_outline;+    FT_Bool       is_apple_sbit;+    FT_Bool       ignore_preferred_family = FALSE;+    FT_Bool       ignore_preferred_subfamily = FALSE;++    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;++    FT_UNUSED( face_index );++    /* Check parameters */+    +    {+      FT_Int  i;+++      for ( i = 0; i < num_params; i++ )+      {+        if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )+          ignore_preferred_family = TRUE;+        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )+          ignore_preferred_subfamily = TRUE;+      }+    }++    /* Load tables */++    /* We now support two SFNT-based bitmapped font formats.  They */+    /* are recognized easily as they do not include a `glyf'       */+    /* table.                                                      */+    /*                                                             */+    /* The first format comes from Apple, and uses a table named   */+    /* `bhed' instead of `head' to store the font header (using    */+    /* the same format).  It also doesn't include horizontal and   */+    /* vertical metrics tables (i.e. `hhea' and `vhea' tables are  */+    /* missing).                                                   */+    /*                                                             */+    /* The other format comes from Microsoft, and is used with     */+    /* WinCE/PocketPC.  It looks like a standard TTF, except that  */+    /* it doesn't contain outlines.                                */+    /*                                                             */++    FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));++    /* do we have outlines in there? */+#ifdef FT_CONFIG_OPTION_INCREMENTAL+    has_outline   = FT_BOOL( face->root.internal->incremental_interface != 0 ||+                             tt_face_lookup_table( face, TTAG_glyf )    != 0 ||+                             tt_face_lookup_table( face, TTAG_CFF )     != 0 );+#else+    has_outline   = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||+                             tt_face_lookup_table( face, TTAG_CFF )  != 0 );+#endif++    is_apple_sbit = 0;++    /* if this font doesn't contain outlines, we try to load */+    /* a `bhed' table                                        */+    if ( !has_outline && sfnt->load_bhed )+    {+      LOAD_( bhed );+      is_apple_sbit = FT_BOOL( !error );+    }++    /* load the font header (`head' table) if this isn't an Apple */+    /* sbit font file                                             */+    if ( !is_apple_sbit )+    {+      LOAD_( head );+      if ( error )+        goto Exit;+    }++    if ( face->header.Units_Per_EM == 0 )+    {+      error = SFNT_Err_Invalid_Table;++      goto Exit;+    }++    /* the following tables are often not present in embedded TrueType */+    /* fonts within PDF documents, so don't check for them.            */+    LOAD_( maxp );+    LOAD_( cmap );++    /* the following tables are optional in PCL fonts -- */+    /* don't check for errors                            */+    LOAD_( name );+    LOAD_( post );++#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+    psnames_error = error;+#endif++    /* do not load the metrics headers and tables if this is an Apple */+    /* sbit font file                                                 */+    if ( !is_apple_sbit )+    {+      /* load the `hhea' and `hmtx' tables */+      LOADM_( hhea, 0 );+      if ( !error )+      {+        LOADM_( hmtx, 0 );+        if ( error == SFNT_Err_Table_Missing )+        {+          error = SFNT_Err_Hmtx_Table_Missing;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+          /* If this is an incrementally loaded font and there are */+          /* overriding metrics, tolerate a missing `hmtx' table.  */+          if ( face->root.internal->incremental_interface          &&+               face->root.internal->incremental_interface->funcs->+                 get_glyph_metrics                                 )+          {+            face->horizontal.number_Of_HMetrics = 0;+            error = SFNT_Err_Ok;+          }+#endif+        }+      }+      else if ( error == SFNT_Err_Table_Missing )+      {+        /* No `hhea' table necessary for SFNT Mac fonts. */+        if ( face->format_tag == TTAG_true )+        {+          FT_TRACE2(( "This is an SFNT Mac font.\n" ));+          has_outline = 0;+          error = SFNT_Err_Ok;+        }+        else+        {+          error = SFNT_Err_Horiz_Header_Missing;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+          /* If this is an incrementally loaded font and there are */+          /* overriding metrics, tolerate a missing `hhea' table.  */+          if ( face->root.internal->incremental_interface          &&+               face->root.internal->incremental_interface->funcs->+                 get_glyph_metrics                                 )+          {+            face->horizontal.number_Of_HMetrics = 0;+            error = SFNT_Err_Ok;+          }+#endif++        }+      }++      if ( error )+        goto Exit;++      /* try to load the `vhea' and `vmtx' tables */+      LOADM_( hhea, 1 );+      if ( !error )+      {+        LOADM_( hmtx, 1 );+        if ( !error )+          face->vertical_info = 1;+      }++      if ( error && error != SFNT_Err_Table_Missing )+        goto Exit;++      LOAD_( os2 );+      if ( error )+      {+        /* we treat the table as missing if there are any errors */+        face->os2.version = 0xFFFFU;+      }+    }++    /* the optional tables */++    /* embedded bitmap support */+    if ( sfnt->load_eblc )+    {+      LOAD_( eblc );+      if ( error )+      {+        /* a font which contains neither bitmaps nor outlines is */+        /* still valid (although rather useless in most cases);  */+        /* however, you can find such stripped fonts in PDFs     */+        if ( error == SFNT_Err_Table_Missing )+          error = SFNT_Err_Ok;+        else+          goto Exit;+      }+    }++    LOAD_( pclt );+    if ( error )+    {+      if ( error != SFNT_Err_Table_Missing )+        goto Exit;++      face->pclt.Version = 0;+    }++    /* consider the kerning and gasp tables as optional */+    LOAD_( gasp );+    LOAD_( kern );++    face->root.num_glyphs = face->max_profile.numGlyphs;++    /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes  */+    /* a WWS-only font face.  `WWS' stands for `weight', width', and */+    /* `slope', a term used by Microsoft's Windows Presentation      */+    /* Foundation (WPF).  This flag has been introduced in version   */+    /* 1.5 of the OpenType specification (May 2008).                 */++    face->root.family_name = NULL;+    face->root.style_name  = NULL;+    if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )+    {+      if ( !ignore_preferred_family )+        GET_NAME( PREFERRED_FAMILY, &face->root.family_name );+      if ( !face->root.family_name )+        GET_NAME( FONT_FAMILY, &face->root.family_name );++      if ( !ignore_preferred_subfamily )+        GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );+      if ( !face->root.style_name )+        GET_NAME( FONT_SUBFAMILY, &face->root.style_name );+    }+    else+    {+      GET_NAME( WWS_FAMILY, &face->root.family_name );+      if ( !face->root.family_name && !ignore_preferred_family )+        GET_NAME( PREFERRED_FAMILY, &face->root.family_name );+      if ( !face->root.family_name )+        GET_NAME( FONT_FAMILY, &face->root.family_name );++      GET_NAME( WWS_SUBFAMILY, &face->root.style_name );+      if ( !face->root.style_name && !ignore_preferred_subfamily )+        GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );+      if ( !face->root.style_name )+        GET_NAME( FONT_SUBFAMILY, &face->root.style_name );+    }++    /* now set up root fields */+    {+      FT_Face  root  = &face->root;+      FT_Long  flags = root->face_flags;+++      /*********************************************************************/+      /*                                                                   */+      /* Compute face flags.                                               */+      /*                                                                   */+      if ( has_outline == TRUE )+        flags |= FT_FACE_FLAG_SCALABLE;   /* scalable outlines */++      /* The sfnt driver only supports bitmap fonts natively, thus we */+      /* don't set FT_FACE_FLAG_HINTER.                               */+      flags |= FT_FACE_FLAG_SFNT       |  /* SFNT file format  */+               FT_FACE_FLAG_HORIZONTAL;   /* horizontal data   */++#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES+      if ( psnames_error == SFNT_Err_Ok               &&+           face->postscript.FormatType != 0x00030000L )+        flags |= FT_FACE_FLAG_GLYPH_NAMES;+#endif++      /* fixed width font? */+      if ( face->postscript.isFixedPitch )+        flags |= FT_FACE_FLAG_FIXED_WIDTH;++      /* vertical information? */+      if ( face->vertical_info )+        flags |= FT_FACE_FLAG_VERTICAL;++      /* kerning available ? */+      if ( TT_FACE_HAS_KERNING( face ) )+        flags |= FT_FACE_FLAG_KERNING;++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+      /* Don't bother to load the tables unless somebody asks for them. */+      /* No need to do work which will (probably) not be used.          */+      if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&+           tt_face_lookup_table( face, TTAG_fvar ) != 0 &&+           tt_face_lookup_table( face, TTAG_gvar ) != 0 )+        flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;+#endif++      root->face_flags = flags;++      /*********************************************************************/+      /*                                                                   */+      /* Compute style flags.                                              */+      /*                                                                   */++      flags = 0;+      if ( has_outline == TRUE && face->os2.version != 0xFFFFU )+      {+        /* We have an OS/2 table; use the `fsSelection' field.  Bit 9 */+        /* indicates an oblique font face.  This flag has been        */+        /* introduced in version 1.5 of the OpenType specification.   */++        if ( face->os2.fsSelection & 512 )       /* bit 9 */+          flags |= FT_STYLE_FLAG_ITALIC;+        else if ( face->os2.fsSelection & 1 )    /* bit 0 */+          flags |= FT_STYLE_FLAG_ITALIC;++        if ( face->os2.fsSelection & 32 )        /* bit 5 */+          flags |= FT_STYLE_FLAG_BOLD;+      }+      else+      {+        /* this is an old Mac font, use the header field */++        if ( face->header.Mac_Style & 1 )+          flags |= FT_STYLE_FLAG_BOLD;++        if ( face->header.Mac_Style & 2 )+          flags |= FT_STYLE_FLAG_ITALIC;+      }++      root->style_flags = flags;++      /*********************************************************************/+      /*                                                                   */+      /* Polish the charmaps.                                              */+      /*                                                                   */+      /*   Try to set the charmap encoding according to the platform &     */+      /*   encoding ID of each charmap.                                    */+      /*                                                                   */++      tt_face_build_cmaps( face );  /* ignore errors */+++      /* set the encoding fields */+      {+        FT_Int  m;+++        for ( m = 0; m < root->num_charmaps; m++ )+        {+          FT_CharMap  charmap = root->charmaps[m];+++          charmap->encoding = sfnt_find_encoding( charmap->platform_id,+                                                  charmap->encoding_id );++#if 0+          if ( root->charmap     == NULL &&+               charmap->encoding == FT_ENCODING_UNICODE )+          {+            /* set 'root->charmap' to the first Unicode encoding we find */+            root->charmap = charmap;+          }+#endif+        }+      }++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++      /*+       *  Now allocate the root array of FT_Bitmap_Size records and+       *  populate them.  Unfortunately, it isn't possible to indicate bit+       *  depths in the FT_Bitmap_Size record.  This is a design error.+       */+      {+        FT_UInt  i, count;+++#ifndef FT_CONFIG_OPTION_OLD_INTERNALS+        count = face->sbit_num_strikes;+#else+        count = (FT_UInt)face->num_sbit_strikes;+#endif++        if ( count > 0 )+        {+          FT_Memory        memory   = face->root.stream->memory;+          FT_UShort        em_size  = face->header.Units_Per_EM;+          FT_Short         avgwidth = face->os2.xAvgCharWidth;+          FT_Size_Metrics  metrics;+++          if ( em_size == 0 || face->os2.version == 0xFFFFU )+          {+            avgwidth = 0;+            em_size = 1;+          }++          if ( FT_NEW_ARRAY( root->available_sizes, count ) )+            goto Exit;++          for ( i = 0; i < count; i++ )+          {+            FT_Bitmap_Size*  bsize = root->available_sizes + i;+++            error = sfnt->load_strike_metrics( face, i, &metrics );+            if ( error )+              goto Exit;++            bsize->height = (FT_Short)( metrics.height >> 6 );+            bsize->width = (FT_Short)(+                ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );++            bsize->x_ppem = metrics.x_ppem << 6;+            bsize->y_ppem = metrics.y_ppem << 6;++            /* assume 72dpi */+            bsize->size   = metrics.y_ppem << 6;+          }++          root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;+          root->num_fixed_sizes = (FT_Int)count;+        }+      }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */++      /* a font with no bitmaps and no outlines is scalable; */+      /* it has only empty glyphs then                       */+      if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )+        root->face_flags |= FT_FACE_FLAG_SCALABLE;+++      /*********************************************************************/+      /*                                                                   */+      /*  Set up metrics.                                                  */+      /*                                                                   */+      if ( FT_IS_SCALABLE( root ) )+      {+        /* XXX What about if outline header is missing */+        /*     (e.g. sfnt wrapped bitmap)?             */+        root->bbox.xMin    = face->header.xMin;+        root->bbox.yMin    = face->header.yMin;+        root->bbox.xMax    = face->header.xMax;+        root->bbox.yMax    = face->header.yMax;+        root->units_per_EM = face->header.Units_Per_EM;+++        /* XXX: Computing the ascender/descender/height is very different */+        /*      from what the specification tells you.  Apparently, we    */+        /*      must be careful because                                   */+        /*                                                                */+        /*      - not all fonts have an OS/2 table; in this case, we take */+        /*        the values in the horizontal header.  However, these    */+        /*        values very often are not reliable.                     */+        /*                                                                */+        /*      - otherwise, the correct typographic values are in the    */+        /*        sTypoAscender, sTypoDescender & sTypoLineGap fields.    */+        /*                                                                */+        /*        However, certain fonts have these fields set to 0.      */+        /*        Rather, they have usWinAscent & usWinDescent correctly  */+        /*        set (but with different values).                        */+        /*                                                                */+        /*      As an example, Arial Narrow is implemented through four   */+        /*      files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */+        /*                                                                */+        /*      Strangely, all fonts have the same values in their        */+        /*      sTypoXXX fields, except ARIALNB which sets them to 0.     */+        /*                                                                */+        /*      On the other hand, they all have different                */+        /*      usWinAscent/Descent values -- as a conclusion, the OS/2   */+        /*      table cannot be used to compute the text height reliably! */+        /*                                                                */++        /* The ascender/descender/height are computed from the OS/2 table */+        /* when found.  Otherwise, they're taken from the horizontal      */+        /* header.                                                        */+        /*                                                                */++        root->ascender  = face->horizontal.Ascender;+        root->descender = face->horizontal.Descender;++        root->height    = (FT_Short)( root->ascender - root->descender ++                                      face->horizontal.Line_Gap );++#if 0+        /* if the line_gap is 0, we add an extra 15% to the text height --  */+        /* this computation is based on various versions of Times New Roman */+        if ( face->horizontal.Line_Gap == 0 )+          root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 );+#endif /* 0 */++#if 0+        /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */+        /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF             */+        if ( face->os2.version != 0xFFFFU && root->ascender )+        {+          FT_Int  height;+++          root->ascender  =  face->os2.sTypoAscender;+          root->descender = -face->os2.sTypoDescender;++          height = root->ascender + root->descender + face->os2.sTypoLineGap;+          if ( height > root->height )+            root->height = height;+        }+#endif /* 0 */++        root->max_advance_width  = face->horizontal.advance_Width_Max;+        root->max_advance_height = (FT_Short)( face->vertical_info+                                     ? face->vertical.advance_Height_Max+                                     : root->height );++        /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */+        /* Adjust underline position from top edge to centre of     */+        /* stroke to convert TrueType meaning to FreeType meaning.  */+        root->underline_position  = face->postscript.underlinePosition -+                                    face->postscript.underlineThickness / 2;+        root->underline_thickness = face->postscript.underlineThickness;+      }++    }++  Exit:+    FT_TRACE2(( "sfnt_load_face: done\n" ));++    return error;+  }+++#undef LOAD_+#undef LOADM_+#undef GET_NAME+++  FT_LOCAL_DEF( void )+  sfnt_done_face( TT_Face  face )+  {+    FT_Memory     memory;+    SFNT_Service  sfnt;+++    if ( !face )+      return;++    memory = face->root.memory;+    sfnt   = (SFNT_Service)face->sfnt;++    if ( sfnt )+    {+      /* destroy the postscript names table if it is loaded */+      if ( sfnt->free_psnames )+        sfnt->free_psnames( face );++      /* destroy the embedded bitmaps table if it is loaded */+      if ( sfnt->free_eblc )+        sfnt->free_eblc( face );+    }++#ifdef TT_CONFIG_OPTION_BDF+    /* freeing the embedded BDF properties */+    tt_face_free_bdf_props( face );+#endif++    /* freeing the kerning table */+    tt_face_done_kern( face );++    /* freeing the collection table */+    FT_FREE( face->ttc_header.offsets );+    face->ttc_header.count = 0;++    /* freeing table directory */+    FT_FREE( face->dir_tables );+    face->num_tables = 0;++    {+      FT_Stream  stream = FT_FACE_STREAM( face );+++      /* simply release the 'cmap' table frame */+      FT_FRAME_RELEASE( face->cmap_table );+      face->cmap_size = 0;+    }++    /* freeing the horizontal metrics */+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS+    {+      FT_Stream  stream = FT_FACE_STREAM( face );+++      FT_FRAME_RELEASE( face->horz_metrics );+      FT_FRAME_RELEASE( face->vert_metrics );+      face->horz_metrics_size = 0;+      face->vert_metrics_size = 0;+    }+#else+    FT_FREE( face->horizontal.long_metrics );+    FT_FREE( face->horizontal.short_metrics );+#endif++    /* freeing the vertical ones, if any */+    if ( face->vertical_info )+    {+      FT_FREE( face->vertical.long_metrics  );+      FT_FREE( face->vertical.short_metrics );+      face->vertical_info = 0;+    }++    /* freeing the gasp table */+    FT_FREE( face->gasp.gaspRanges );+    face->gasp.numRanges = 0;++    /* freeing the name table */+    if ( sfnt )+      sfnt->free_name( face );++    /* freeing family and style name */+    FT_FREE( face->root.family_name );+    FT_FREE( face->root.style_name );++    /* freeing sbit size table */+    FT_FREE( face->root.available_sizes );+    face->root.num_fixed_sizes = 0;++    FT_FREE( face->postscript_name );++    face->sfnt = 0;+  }+++/* END */
+ src/sfnt/sfobjs.h view
@@ -0,0 +1,54 @@+/***************************************************************************/+/*                                                                         */+/*  sfobjs.h                                                               */+/*                                                                         */+/*    SFNT object management (specification).                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __SFOBJS_H__+#define __SFOBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_SFNT_H+#include FT_INTERNAL_OBJECTS_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  sfnt_init_face( FT_Stream      stream,+                  TT_Face        face,+                  FT_Int         face_index,+                  FT_Int         num_params,+                  FT_Parameter*  params );++  FT_LOCAL( FT_Error )+  sfnt_load_face( FT_Stream      stream,+                  TT_Face        face,+                  FT_Int         face_index,+                  FT_Int         num_params,+                  FT_Parameter*  params );++  FT_LOCAL( void )+  sfnt_done_face( TT_Face  face );+++FT_END_HEADER++#endif /* __SFDRIVER_H__ */+++/* END */
+ src/sfnt/ttbdf.c view
@@ -0,0 +1,250 @@+/***************************************************************************/+/*                                                                         */+/*  ttbdf.c                                                                */+/*                                                                         */+/*    TrueType and OpenType embedded BDF properties (body).                */+/*                                                                         */+/*  Copyright 2005, 2006, 2010 by                                          */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttbdf.h"++#include "sferrors.h"+++#ifdef TT_CONFIG_OPTION_BDF++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttbdf+++  FT_LOCAL_DEF( void )+  tt_face_free_bdf_props( TT_Face  face )+  {+    TT_BDF  bdf = &face->bdf;+++    if ( bdf->loaded )+    {+      FT_Stream  stream = FT_FACE(face)->stream;+++      if ( bdf->table != NULL )+        FT_FRAME_RELEASE( bdf->table );++      bdf->table_end    = NULL;+      bdf->strings      = NULL;+      bdf->strings_size = 0;+    }+  }+++  static FT_Error+  tt_face_load_bdf_props( TT_Face    face,+                          FT_Stream  stream )+  {+    TT_BDF    bdf = &face->bdf;+    FT_ULong  length;+    FT_Error  error;+++    FT_ZERO( bdf );++    error = tt_face_goto_table( face, TTAG_BDF, stream, &length );+    if ( error                                  ||+         length < 8                             ||+         FT_FRAME_EXTRACT( length, bdf->table ) )+    {+      error = SFNT_Err_Invalid_Table;+      goto Exit;+    }++    bdf->table_end = bdf->table + length;++    {+      FT_Byte*   p           = bdf->table;+      FT_UInt    version     = FT_NEXT_USHORT( p );+      FT_UInt    num_strikes = FT_NEXT_USHORT( p );+      FT_ULong   strings     = FT_NEXT_ULONG ( p );+      FT_UInt    count;+      FT_Byte*   strike;+++      if ( version != 0x0001                 ||+           strings < 8                       ||+           ( strings - 8 ) / 4 < num_strikes ||+           strings + 1 > length              )+      {+        goto BadTable;+      }++      bdf->num_strikes  = num_strikes;+      bdf->strings      = bdf->table + strings;+      bdf->strings_size = length - strings;++      count  = bdf->num_strikes;+      p      = bdf->table + 8;+      strike = p + count * 4;+++      for ( ; count > 0; count-- )+      {+        FT_UInt  num_items = FT_PEEK_USHORT( p + 2 );++        /*+         *  We don't need to check the value sets themselves, since this+         *  is done later.+         */+        strike += 10 * num_items;++        p += 4;+      }++      if ( strike > bdf->strings )+        goto BadTable;+    }++    bdf->loaded = 1;++  Exit:+    return error;++  BadTable:+    FT_FRAME_RELEASE( bdf->table );+    FT_ZERO( bdf );+    error = SFNT_Err_Invalid_Table;+    goto Exit;+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_find_bdf_prop( TT_Face           face,+                         const char*       property_name,+                         BDF_PropertyRec  *aprop )+  {+    TT_BDF     bdf   = &face->bdf;+    FT_Size    size  = FT_FACE(face)->size;+    FT_Error   error = SFNT_Err_Ok;+    FT_Byte*   p;+    FT_UInt    count;+    FT_Byte*   strike;+    FT_Offset  property_len;+++    aprop->type = BDF_PROPERTY_TYPE_NONE;++    if ( bdf->loaded == 0 )+    {+      error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );+      if ( error )+        goto Exit;+    }++    count  = bdf->num_strikes;+    p      = bdf->table + 8;+    strike = p + 4 * count;++    error = SFNT_Err_Invalid_Argument;++    if ( size == NULL || property_name == NULL )+      goto Exit;++    property_len = ft_strlen( property_name );+    if ( property_len == 0 )+      goto Exit;++    for ( ; count > 0; count-- )+    {+      FT_UInt  _ppem  = FT_NEXT_USHORT( p );+      FT_UInt  _count = FT_NEXT_USHORT( p );++      if ( _ppem == size->metrics.y_ppem )+      {+        count = _count;+        goto FoundStrike;+      }++      strike += 10 * _count;+    }+    goto Exit;++  FoundStrike:+    p = strike;+    for ( ; count > 0; count-- )+    {+      FT_UInt  type = FT_PEEK_USHORT( p + 4 );++      if ( ( type & 0x10 ) != 0 )+      {+        FT_UInt32  name_offset = FT_PEEK_ULONG( p     );+        FT_UInt32  value       = FT_PEEK_ULONG( p + 6 );++        /* be a bit paranoid for invalid entries here */+        if ( name_offset < bdf->strings_size                    &&+             property_len < bdf->strings_size - name_offset     &&+             ft_strncmp( property_name,+                         (const char*)bdf->strings + name_offset,+                         bdf->strings_size - name_offset ) == 0 )+        {+          switch ( type & 0x0F )+          {+          case 0x00:  /* string */+          case 0x01:  /* atoms */+            /* check that the content is really 0-terminated */+            if ( value < bdf->strings_size &&+                 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )+            {+              aprop->type   = BDF_PROPERTY_TYPE_ATOM;+              aprop->u.atom = (const char*)bdf->strings + value;+              error         = SFNT_Err_Ok;+              goto Exit;+            }+            break;++          case 0x02:+            aprop->type      = BDF_PROPERTY_TYPE_INTEGER;+            aprop->u.integer = (FT_Int32)value;+            error            = SFNT_Err_Ok;+            goto Exit;++          case 0x03:+            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;+            aprop->u.cardinal = value;+            error             = SFNT_Err_Ok;+            goto Exit;++          default:+            ;+          }+        }+      }+      p += 10;+    }++  Exit:+    return error;+  }++#endif /* TT_CONFIG_OPTION_BDF */+++/* END */
+ src/sfnt/ttbdf.h view
@@ -0,0 +1,46 @@+/***************************************************************************/+/*                                                                         */+/*  ttbdf.h                                                                */+/*                                                                         */+/*    TrueType and OpenType embedded BDF properties (specification).       */+/*                                                                         */+/*  Copyright 2005 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTBDF_H__+#define __TTBDF_H__+++#include <ft2build.h>+#include "ttload.h"+#include FT_BDF_H+++FT_BEGIN_HEADER+++  FT_LOCAL( void )+  tt_face_free_bdf_props( TT_Face  face );+++  FT_LOCAL( FT_Error )+  tt_face_find_bdf_prop( TT_Face           face,+                         const char*       property_name,+                         BDF_PropertyRec  *aprop );+++FT_END_HEADER++#endif /* __TTBDF_H__ */+++/* END */
+ src/sfnt/ttcmap.c view
@@ -0,0 +1,3512 @@+/***************************************************************************/+/*                                                                         */+/*  ttcmap.c                                                               */+/*                                                                         */+/*    TrueType character mapping table (cmap) support (body).              */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H++#include "sferrors.h"           /* must come before FT_INTERNAL_VALIDATE_H */++#include FT_INTERNAL_VALIDATE_H+#include FT_INTERNAL_STREAM_H+#include "ttload.h"+#include "ttcmap.h"+#include "sfntpic.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttcmap+++#define TT_PEEK_SHORT   FT_PEEK_SHORT+#define TT_PEEK_USHORT  FT_PEEK_USHORT+#define TT_PEEK_UINT24  FT_PEEK_UOFF3+#define TT_PEEK_LONG    FT_PEEK_LONG+#define TT_PEEK_ULONG   FT_PEEK_ULONG++#define TT_NEXT_SHORT   FT_NEXT_SHORT+#define TT_NEXT_USHORT  FT_NEXT_USHORT+#define TT_NEXT_UINT24  FT_NEXT_UOFF3+#define TT_NEXT_LONG    FT_NEXT_LONG+#define TT_NEXT_ULONG   FT_NEXT_ULONG+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap_init( TT_CMap   cmap,+                FT_Byte*  table )+  {+    cmap->data = table;+    return SFNT_Err_Ok;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                           FORMAT 0                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET         TYPE          DESCRIPTION                */+  /*                                                                       */+  /*   format      0              USHORT        must be 0                  */+  /*   length      2              USHORT        table length in bytes      */+  /*   language    4              USHORT        Mac language code          */+  /*   glyph_ids   6              BYTE[256]     array of glyph indices     */+  /*               262                                                     */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_0++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap0_validate( FT_Byte*      table,+                     FT_Validator  valid )+  {+    FT_Byte*  p      = table + 2;+    FT_UInt   length = TT_NEXT_USHORT( p );+++    if ( table + length > valid->limit || length < 262 )+      FT_INVALID_TOO_SHORT;++    /* check glyph indices whenever necessary */+    if ( valid->level >= FT_VALIDATE_TIGHT )+    {+      FT_UInt  n, idx;+++      p = table + 6;+      for ( n = 0; n < 256; n++ )+      {+        idx = *p++;+        if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )+          FT_INVALID_GLYPH_ID;+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap0_char_index( TT_CMap    cmap,+                       FT_UInt32  char_code )+  {+    FT_Byte*  table = cmap->data;+++    return char_code < 256 ? table[6 + char_code] : 0;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap0_char_next( TT_CMap     cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_Byte*   table    = cmap->data;+    FT_UInt32  charcode = *pchar_code;+    FT_UInt32  result   = 0;+    FT_UInt    gindex   = 0;+++    table += 6;  /* go to glyph IDs */+    while ( ++charcode < 256 )+    {+      gindex = table[charcode];+      if ( gindex != 0 )+      {+        result = charcode;+        break;+      }+    }++    *pchar_code = result;+    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap0_get_info( TT_CMap       cmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 4;+++    cmap_info->format   = 0;+    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap0_class_rec,+      sizeof ( TT_CMapRec ),++      (FT_CMap_InitFunc)     tt_cmap_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap0_char_index,+      (FT_CMap_CharNextFunc) tt_cmap0_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    0,+    (TT_CMap_ValidateFunc)   tt_cmap0_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap0_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_0 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 2                             *****/+  /*****                                                               *****/+  /***** This is used for certain CJK encodings that encode text in a  *****/+  /***** mixed 8/16 bits encoding along the following lines:           *****/+  /*****                                                               *****/+  /***** * Certain byte values correspond to an 8-bit character code   *****/+  /*****   (typically in the range 0..127 for ASCII compatibility).    *****/+  /*****                                                               *****/+  /***** * Certain byte values signal the first byte of a 2-byte       *****/+  /*****   character code (but these values are also valid as the      *****/+  /*****   second byte of a 2-byte character).                         *****/+  /*****                                                               *****/+  /***** The following charmap lookup and iteration functions all      *****/+  /***** assume that the value "charcode" correspond to following:     *****/+  /*****                                                               *****/+  /*****   - For one byte characters, "charcode" is simply the         *****/+  /*****     character code.                                           *****/+  /*****                                                               *****/+  /*****   - For two byte characters, "charcode" is the 2-byte         *****/+  /*****     character code in big endian format.  More exactly:       *****/+  /*****                                                               *****/+  /*****       (charcode >> 8)    is the first byte value              *****/+  /*****       (charcode & 0xFF)  is the second byte value             *****/+  /*****                                                               *****/+  /***** Note that not all values of "charcode" are valid according    *****/+  /***** to these rules, and the function moderately check the         *****/+  /***** arguments.                                                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET         TYPE            DESCRIPTION              */+  /*                                                                       */+  /*   format      0              USHORT          must be 2                */+  /*   length      2              USHORT          table length in bytes    */+  /*   language    4              USHORT          Mac language code        */+  /*   keys        6              USHORT[256]     sub-header keys          */+  /*   subs        518            SUBHEAD[NSUBS]  sub-headers array        */+  /*   glyph_ids   518+NSUB*8     USHORT[]        glyph ID array           */+  /*                                                                       */+  /* The `keys' table is used to map charcode high-bytes to sub-headers.   */+  /* The value of `NSUBS' is the number of sub-headers defined in the      */+  /* table and is computed by finding the maximum of the `keys' table.     */+  /*                                                                       */+  /* Note that for any n, `keys[n]' is a byte offset within the `subs'     */+  /* table, i.e., it is the corresponding sub-header index multiplied      */+  /* by 8.                                                                 */+  /*                                                                       */+  /* Each sub-header has the following format:                             */+  /*                                                                       */+  /*   NAME        OFFSET      TYPE            DESCRIPTION                 */+  /*                                                                       */+  /*   first       0           USHORT          first valid low-byte        */+  /*   count       2           USHORT          number of valid low-bytes   */+  /*   delta       4           SHORT           see below                   */+  /*   offset      6           USHORT          see below                   */+  /*                                                                       */+  /* A sub-header defines, for each high-byte, the range of valid          */+  /* low-bytes within the charmap.  Note that the range defined by `first' */+  /* and `count' must be completely included in the interval [0..255]      */+  /* according to the specification.                                       */+  /*                                                                       */+  /* If a character code is contained within a given sub-header, then      */+  /* mapping it to a glyph index is done as follows:                       */+  /*                                                                       */+  /* * The value of `offset' is read.  This is a _byte_ distance from the  */+  /*   location of the `offset' field itself into a slice of the           */+  /*   `glyph_ids' table.  Let's call it `slice' (it is a USHORT[] too).   */+  /*                                                                       */+  /* * The value `slice[char.lo - first]' is read.  If it is 0, there is   */+  /*   no glyph for the charcode.  Otherwise, the value of `delta' is      */+  /*   added to it (modulo 65536) to form a new glyph index.               */+  /*                                                                       */+  /* It is up to the validation routine to check that all offsets fall     */+  /* within the glyph IDs table (and not within the `subs' table itself or */+  /* outside of the CMap).                                                 */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_2++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap2_validate( FT_Byte*      table,+                     FT_Validator  valid )+  {+    FT_Byte*  p      = table + 2;           /* skip format */+    FT_UInt   length = TT_PEEK_USHORT( p );+    FT_UInt   n, max_subs;+    FT_Byte*  keys;                         /* keys table */+    FT_Byte*  subs;                         /* sub-headers */+    FT_Byte*  glyph_ids;                    /* glyph ID array */+++    if ( table + length > valid->limit || length < 6 + 512 )+      FT_INVALID_TOO_SHORT;++    keys = table + 6;++    /* parse keys to compute sub-headers count */+    p        = keys;+    max_subs = 0;+    for ( n = 0; n < 256; n++ )+    {+      FT_UInt  idx = TT_NEXT_USHORT( p );+++      /* value must be multiple of 8 */+      if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 )+        FT_INVALID_DATA;++      idx >>= 3;++      if ( idx > max_subs )+        max_subs = idx;+    }++    FT_ASSERT( p == table + 518 );++    subs      = p;+    glyph_ids = subs + (max_subs + 1) * 8;+    if ( glyph_ids > valid->limit )+      FT_INVALID_TOO_SHORT;++    /* parse sub-headers */+    for ( n = 0; n <= max_subs; n++ )+    {+      FT_UInt   first_code, code_count, offset;+      FT_Int    delta;+      FT_Byte*  ids;+++      first_code = TT_NEXT_USHORT( p );+      code_count = TT_NEXT_USHORT( p );+      delta      = TT_NEXT_SHORT( p );+      offset     = TT_NEXT_USHORT( p );++      /* many Dynalab fonts have empty sub-headers */+      if ( code_count == 0 )+        continue;++      /* check range within 0..255 */+      if ( valid->level >= FT_VALIDATE_PARANOID )+      {+        if ( first_code >= 256 || first_code + code_count > 256 )+          FT_INVALID_DATA;+      }++      /* check offset */+      if ( offset != 0 )+      {+        ids = p - 2 + offset;+        if ( ids < glyph_ids || ids + code_count*2 > table + length )+          FT_INVALID_OFFSET;++        /* check glyph IDs */+        if ( valid->level >= FT_VALIDATE_TIGHT )+        {+          FT_Byte*  limit = p + code_count * 2;+          FT_UInt   idx;+++          for ( ; p < limit; )+          {+            idx = TT_NEXT_USHORT( p );+            if ( idx != 0 )+            {+              idx = ( idx + delta ) & 0xFFFFU;+              if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )+                FT_INVALID_GLYPH_ID;+            }+          }+        }+      }+    }++    return SFNT_Err_Ok;+  }+++  /* return sub header corresponding to a given character code */+  /* NULL on invalid charcode                                  */+  static FT_Byte*+  tt_cmap2_get_subheader( FT_Byte*   table,+                          FT_UInt32  char_code )+  {+    FT_Byte*  result = NULL;+++    if ( char_code < 0x10000UL )+    {+      FT_UInt   char_lo = (FT_UInt)( char_code & 0xFF );+      FT_UInt   char_hi = (FT_UInt)( char_code >> 8 );+      FT_Byte*  p       = table + 6;    /* keys table */+      FT_Byte*  subs    = table + 518;  /* subheaders table */+      FT_Byte*  sub;+++      if ( char_hi == 0 )+      {+        /* an 8-bit character code -- we use subHeader 0 in this case */+        /* to test whether the character code is in the charmap       */+        /*                                                            */+        sub = subs;  /* jump to first sub-header */++        /* check that the sub-header for this byte is 0, which */+        /* indicates that it is really a valid one-byte value  */+        /* Otherwise, return 0                                 */+        /*                                                     */+        p += char_lo * 2;+        if ( TT_PEEK_USHORT( p ) != 0 )+          goto Exit;+      }+      else+      {+        /* a 16-bit character code */++        /* jump to key entry  */+        p  += char_hi * 2;+        /* jump to sub-header */+        sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );++        /* check that the high byte isn't a valid one-byte value */+        if ( sub == subs )+          goto Exit;+      }+      result = sub;+    }+  Exit:+    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap2_char_index( TT_CMap    cmap,+                       FT_UInt32  char_code )+  {+    FT_Byte*  table   = cmap->data;+    FT_UInt   result  = 0;+    FT_Byte*  subheader;+++    subheader = tt_cmap2_get_subheader( table, char_code );+    if ( subheader )+    {+      FT_Byte*  p   = subheader;+      FT_UInt   idx = (FT_UInt)(char_code & 0xFF);+      FT_UInt   start, count;+      FT_Int    delta;+      FT_UInt   offset;+++      start  = TT_NEXT_USHORT( p );+      count  = TT_NEXT_USHORT( p );+      delta  = TT_NEXT_SHORT ( p );+      offset = TT_PEEK_USHORT( p );++      idx -= start;+      if ( idx < count && offset != 0 )+      {+        p  += offset + 2 * idx;+        idx = TT_PEEK_USHORT( p );++        if ( idx != 0 )+          result = (FT_UInt)( idx + delta ) & 0xFFFFU;+      }+    }+    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap2_char_next( TT_CMap     cmap,+                      FT_UInt32  *pcharcode )+  {+    FT_Byte*   table    = cmap->data;+    FT_UInt    gindex   = 0;+    FT_UInt32  result   = 0;+    FT_UInt32  charcode = *pcharcode + 1;+    FT_Byte*   subheader;+++    while ( charcode < 0x10000UL )+    {+      subheader = tt_cmap2_get_subheader( table, charcode );+      if ( subheader )+      {+        FT_Byte*  p       = subheader;+        FT_UInt   start   = TT_NEXT_USHORT( p );+        FT_UInt   count   = TT_NEXT_USHORT( p );+        FT_Int    delta   = TT_NEXT_SHORT ( p );+        FT_UInt   offset  = TT_PEEK_USHORT( p );+        FT_UInt   char_lo = (FT_UInt)( charcode & 0xFF );+        FT_UInt   pos, idx;+++        if ( offset == 0 )+          goto Next_SubHeader;++        if ( char_lo < start )+        {+          char_lo = start;+          pos     = 0;+        }+        else+          pos = (FT_UInt)( char_lo - start );++        p       += offset + pos * 2;+        charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo;++        for ( ; pos < count; pos++, charcode++ )+        {+          idx = TT_NEXT_USHORT( p );++          if ( idx != 0 )+          {+            gindex = ( idx + delta ) & 0xFFFFU;+            if ( gindex != 0 )+            {+              result = charcode;+              goto Exit;+            }+          }+        }+      }++      /* jump to next sub-header, i.e. higher byte value */+    Next_SubHeader:+      charcode = FT_PAD_FLOOR( charcode, 256 ) + 256;+    }++  Exit:+    *pcharcode = result;++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap2_get_info( TT_CMap       cmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 4;+++    cmap_info->format   = 2;+    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap2_class_rec,+      sizeof ( TT_CMapRec ),++      (FT_CMap_InitFunc)     tt_cmap_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap2_char_index,+      (FT_CMap_CharNextFunc) tt_cmap2_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    2,+    (TT_CMap_ValidateFunc)   tt_cmap2_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap2_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_2 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                           FORMAT 4                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME          OFFSET         TYPE              DESCRIPTION          */+  /*                                                                       */+  /*   format        0              USHORT            must be 4            */+  /*   length        2              USHORT            table length         */+  /*                                                  in bytes             */+  /*   language      4              USHORT            Mac language code    */+  /*                                                                       */+  /*   segCountX2    6              USHORT            2*NUM_SEGS           */+  /*   searchRange   8              USHORT            2*(1 << LOG_SEGS)    */+  /*   entrySelector 10             USHORT            LOG_SEGS             */+  /*   rangeShift    12             USHORT            segCountX2 -         */+  /*                                                    searchRange        */+  /*                                                                       */+  /*   endCount      14             USHORT[NUM_SEGS]  end charcode for     */+  /*                                                  each segment; last   */+  /*                                                  is 0xFFFF            */+  /*                                                                       */+  /*   pad           14+NUM_SEGS*2  USHORT            padding              */+  /*                                                                       */+  /*   startCount    16+NUM_SEGS*2  USHORT[NUM_SEGS]  first charcode for   */+  /*                                                  each segment         */+  /*                                                                       */+  /*   idDelta       16+NUM_SEGS*4  SHORT[NUM_SEGS]   delta for each       */+  /*                                                  segment              */+  /*   idOffset      16+NUM_SEGS*6  SHORT[NUM_SEGS]   range offset for     */+  /*                                                  each segment; can be */+  /*                                                  zero                 */+  /*                                                                       */+  /*   glyphIds      16+NUM_SEGS*8  USHORT[]          array of glyph ID    */+  /*                                                  ranges               */+  /*                                                                       */+  /* Character codes are modelled by a series of ordered (increasing)      */+  /* intervals called segments.  Each segment has start and end codes,     */+  /* provided by the `startCount' and `endCount' arrays.  Segments must    */+  /* not overlap, and the last segment should always contain the value     */+  /* 0xFFFF for `endCount'.                                                */+  /*                                                                       */+  /* The fields `searchRange', `entrySelector' and `rangeShift' are better */+  /* ignored (they are traces of over-engineering in the TrueType          */+  /* specification).                                                       */+  /*                                                                       */+  /* Each segment also has a signed `delta', as well as an optional offset */+  /* within the `glyphIds' table.                                          */+  /*                                                                       */+  /* If a segment's idOffset is 0, the glyph index corresponding to any    */+  /* charcode within the segment is obtained by adding the value of        */+  /* `idDelta' directly to the charcode, modulo 65536.                     */+  /*                                                                       */+  /* Otherwise, a glyph index is taken from the glyph IDs sub-array for    */+  /* the segment, and the value of `idDelta' is added to it.               */+  /*                                                                       */+  /*                                                                       */+  /* Finally, note that a lot of fonts contain an invalid last segment,    */+  /* where `start' and `end' are correctly set to 0xFFFF but both `delta'  */+  /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with     */+  /* OpenOffice.org).  We need special code to deal with them correctly.   */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_4++  typedef struct  TT_CMap4Rec_+  {+    TT_CMapRec  cmap;+    FT_UInt32   cur_charcode;   /* current charcode */+    FT_UInt     cur_gindex;     /* current glyph index */++    FT_UInt     num_ranges;+    FT_UInt     cur_range;+    FT_UInt     cur_start;+    FT_UInt     cur_end;+    FT_Int      cur_delta;+    FT_Byte*    cur_values;++  } TT_CMap4Rec, *TT_CMap4;+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap4_init( TT_CMap4  cmap,+                 FT_Byte*  table )+  {+    FT_Byte*  p;+++    cmap->cmap.data    = table;++    p                  = table + 6;+    cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;+    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;+    cmap->cur_gindex   = 0;++    return SFNT_Err_Ok;+  }+++  static FT_Int+  tt_cmap4_set_range( TT_CMap4  cmap,+                      FT_UInt   range_index )+  {+    FT_Byte*  table = cmap->cmap.data;+    FT_Byte*  p;+    FT_UInt   num_ranges = cmap->num_ranges;+++    while ( range_index < num_ranges )+    {+      FT_UInt  offset;+++      p             = table + 14 + range_index * 2;+      cmap->cur_end = FT_PEEK_USHORT( p );++      p              += 2 + num_ranges * 2;+      cmap->cur_start = FT_PEEK_USHORT( p );++      p              += num_ranges * 2;+      cmap->cur_delta = FT_PEEK_SHORT( p );++      p     += num_ranges * 2;+      offset = FT_PEEK_USHORT( p );++      /* some fonts have an incorrect last segment; */+      /* we have to catch it                        */+      if ( range_index     >= num_ranges - 1 &&+           cmap->cur_start == 0xFFFFU        &&+           cmap->cur_end   == 0xFFFFU        )+      {+        TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;+        FT_Byte*  limit = face->cmap_table + face->cmap_size;+++        if ( offset && p + offset + 2 > limit )+        {+          cmap->cur_delta = 1;+          offset          = 0;+        }+      }++      if ( offset != 0xFFFFU )+      {+        cmap->cur_values = offset ? p + offset : NULL;+        cmap->cur_range  = range_index;+        return 0;+      }++      /* we skip empty segments */+      range_index++;+    }++    return -1;+  }+++  /* search the index of the charcode next to cmap->cur_charcode; */+  /* caller should call tt_cmap4_set_range with proper range      */+  /* before calling this function                                 */+  /*                                                              */+  static void+  tt_cmap4_next( TT_CMap4  cmap )+  {+    FT_UInt  charcode;+++    if ( cmap->cur_charcode >= 0xFFFFUL )+      goto Fail;++    charcode = (FT_UInt)cmap->cur_charcode + 1;++    if ( charcode < cmap->cur_start )+      charcode = cmap->cur_start;++    for ( ;; )+    {+      FT_Byte*  values = cmap->cur_values;+      FT_UInt   end    = cmap->cur_end;+      FT_Int    delta  = cmap->cur_delta;+++      if ( charcode <= end )+      {+        if ( values )+        {+          FT_Byte*  p = values + 2 * ( charcode - cmap->cur_start );+++          do+          {+            FT_UInt  gindex = FT_NEXT_USHORT( p );+++            if ( gindex != 0 )+            {+              gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU );+              if ( gindex != 0 )+              {+                cmap->cur_charcode = charcode;+                cmap->cur_gindex   = gindex;+                return;+              }+            }+          } while ( ++charcode <= end );+        }+        else+        {+          do+          {+            FT_UInt  gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU );+++            if ( gindex != 0 )+            {+              cmap->cur_charcode = charcode;+              cmap->cur_gindex   = gindex;+              return;+            }+          } while ( ++charcode <= end );+        }+      }++      /* we need to find another range */+      if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )+        break;++      if ( charcode < cmap->cur_start )+        charcode = cmap->cur_start;+    }++  Fail:+    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;+    cmap->cur_gindex   = 0;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap4_validate( FT_Byte*      table,+                     FT_Validator  valid )+  {+    FT_Byte*  p      = table + 2;               /* skip format */+    FT_UInt   length = TT_NEXT_USHORT( p );+    FT_Byte   *ends, *starts, *offsets, *deltas, *glyph_ids;+    FT_UInt   num_segs;+    FT_Error  error = SFNT_Err_Ok;+++    if ( length < 16 )+      FT_INVALID_TOO_SHORT;++    /* in certain fonts, the `length' field is invalid and goes */+    /* out of bound.  We try to correct this here...            */+    if ( table + length > valid->limit )+    {+      if ( valid->level >= FT_VALIDATE_TIGHT )+        FT_INVALID_TOO_SHORT;++      length = (FT_UInt)( valid->limit - table );+    }++    p        = table + 6;+    num_segs = TT_NEXT_USHORT( p );   /* read segCountX2 */++    if ( valid->level >= FT_VALIDATE_PARANOID )+    {+      /* check that we have an even value here */+      if ( num_segs & 1 )+        FT_INVALID_DATA;+    }++    num_segs /= 2;++    if ( length < 16 + num_segs * 2 * 4 )+      FT_INVALID_TOO_SHORT;++    /* check the search parameters - even though we never use them */+    /*                                                             */+    if ( valid->level >= FT_VALIDATE_PARANOID )+    {+      /* check the values of `searchRange', `entrySelector', `rangeShift' */+      FT_UInt  search_range   = TT_NEXT_USHORT( p );+      FT_UInt  entry_selector = TT_NEXT_USHORT( p );+      FT_UInt  range_shift    = TT_NEXT_USHORT( p );+++      if ( ( search_range | range_shift ) & 1 )  /* must be even values */+        FT_INVALID_DATA;++      search_range /= 2;+      range_shift  /= 2;++      /* `search range' is the greatest power of 2 that is <= num_segs */++      if ( search_range                > num_segs                 ||+           search_range * 2            < num_segs                 ||+           search_range + range_shift != num_segs                 ||+           search_range               != ( 1U << entry_selector ) )+        FT_INVALID_DATA;+    }++    ends      = table   + 14;+    starts    = table   + 16 + num_segs * 2;+    deltas    = starts  + num_segs * 2;+    offsets   = deltas  + num_segs * 2;+    glyph_ids = offsets + num_segs * 2;++    /* check last segment; its end count value must be 0xFFFF */+    if ( valid->level >= FT_VALIDATE_PARANOID )+    {+      p = ends + ( num_segs - 1 ) * 2;+      if ( TT_PEEK_USHORT( p ) != 0xFFFFU )+        FT_INVALID_DATA;+    }++    {+      FT_UInt   start, end, offset, n;+      FT_UInt   last_start = 0, last_end = 0;+      FT_Int    delta;+      FT_Byte*  p_start   = starts;+      FT_Byte*  p_end     = ends;+      FT_Byte*  p_delta   = deltas;+      FT_Byte*  p_offset  = offsets;+++      for ( n = 0; n < num_segs; n++ )+      {+        p      = p_offset;+        start  = TT_NEXT_USHORT( p_start );+        end    = TT_NEXT_USHORT( p_end );+        delta  = TT_NEXT_SHORT( p_delta );+        offset = TT_NEXT_USHORT( p_offset );++        if ( start > end )+          FT_INVALID_DATA;++        /* this test should be performed at default validation level; */+        /* unfortunately, some popular Asian fonts have overlapping   */+        /* ranges in their charmaps                                   */+        /*                                                            */+        if ( start <= last_end && n > 0 )+        {+          if ( valid->level >= FT_VALIDATE_TIGHT )+            FT_INVALID_DATA;+          else+          {+            /* allow overlapping segments, provided their start points */+            /* and end points, respectively, are in ascending order    */+            /*                                                         */+            if ( last_start > start || last_end > end )+              error |= TT_CMAP_FLAG_UNSORTED;+            else+              error |= TT_CMAP_FLAG_OVERLAPPING;+          }+        }++        if ( offset && offset != 0xFFFFU )+        {+          p += offset;  /* start of glyph ID array */++          /* check that we point within the glyph IDs table only */+          if ( valid->level >= FT_VALIDATE_TIGHT )+          {+            if ( p < glyph_ids                                ||+                 p + ( end - start + 1 ) * 2 > table + length )+              FT_INVALID_DATA;+          }+          /* Some fonts handle the last segment incorrectly.  In */+          /* theory, 0xFFFF might point to an ordinary glyph --  */+          /* a cmap 4 is versatile and could be used for any     */+          /* encoding, not only Unicode.  However, reality shows */+          /* that far too many fonts are sloppy and incorrectly  */+          /* set all fields but `start' and `end' for the last   */+          /* segment if it contains only a single character.     */+          /*                                                     */+          /* We thus omit the test here, delaying it to the      */+          /* routines which actually access the cmap.            */+          else if ( n != num_segs - 1                       ||+                    !( start == 0xFFFFU && end == 0xFFFFU ) )+          {+            if ( p < glyph_ids                              ||+                 p + ( end - start + 1 ) * 2 > valid->limit )+              FT_INVALID_DATA;+          }++          /* check glyph indices within the segment range */+          if ( valid->level >= FT_VALIDATE_TIGHT )+          {+            FT_UInt  i, idx;+++            for ( i = start; i < end; i++ )+            {+              idx = FT_NEXT_USHORT( p );+              if ( idx != 0 )+              {+                idx = (FT_UInt)( idx + delta ) & 0xFFFFU;++                if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )+                  FT_INVALID_GLYPH_ID;+              }+            }+          }+        }+        else if ( offset == 0xFFFFU )+        {+          /* some fonts (erroneously?) use a range offset of 0xFFFF */+          /* to mean missing glyph in cmap table                    */+          /*                                                        */+          if ( valid->level >= FT_VALIDATE_PARANOID    ||+               n != num_segs - 1                       ||+               !( start == 0xFFFFU && end == 0xFFFFU ) )+            FT_INVALID_DATA;+        }++        last_start = start;+        last_end   = end;+      }+    }++    return error;+  }+++  static FT_UInt+  tt_cmap4_char_map_linear( TT_CMap     cmap,+                            FT_UInt32*  pcharcode,+                            FT_Bool     next )+  {+    FT_UInt    num_segs2, start, end, offset;+    FT_Int     delta;+    FT_UInt    i, num_segs;+    FT_UInt32  charcode = *pcharcode;+    FT_UInt    gindex   = 0;+    FT_Byte*   p;+++    p = cmap->data + 6;+    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );++    num_segs = num_segs2 >> 1;++    if ( !num_segs )+      return 0;++    if ( next )+      charcode++;++    /* linear search */+    for ( ; charcode <= 0xFFFFU; charcode++ )+    {+      FT_Byte*  q;+++      p = cmap->data + 14;               /* ends table   */+      q = cmap->data + 16 + num_segs2;   /* starts table */++      for ( i = 0; i < num_segs; i++ )+      {+        end   = TT_NEXT_USHORT( p );+        start = TT_NEXT_USHORT( q );++        if ( charcode >= start && charcode <= end )+        {+          p       = q - 2 + num_segs2;+          delta   = TT_PEEK_SHORT( p );+          p      += num_segs2;+          offset  = TT_PEEK_USHORT( p );++          /* some fonts have an incorrect last segment; */+          /* we have to catch it                        */+          if ( i >= num_segs - 1                  &&+               start == 0xFFFFU && end == 0xFFFFU )+          {+            TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;+            FT_Byte*  limit = face->cmap_table + face->cmap_size;+++            if ( offset && p + offset + 2 > limit )+            {+              delta  = 1;+              offset = 0;+            }+          }++          if ( offset == 0xFFFFU )+            continue;++          if ( offset )+          {+            p += offset + ( charcode - start ) * 2;+            gindex = TT_PEEK_USHORT( p );+            if ( gindex != 0 )+              gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;+          }+          else+            gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;++          break;+        }+      }++      if ( !next || gindex )+        break;+    }++    if ( next && gindex )+      *pcharcode = charcode;++    return gindex;+  }+++  static FT_UInt+  tt_cmap4_char_map_binary( TT_CMap     cmap,+                            FT_UInt32*  pcharcode,+                            FT_Bool     next )+  {+    FT_UInt   num_segs2, start, end, offset;+    FT_Int    delta;+    FT_UInt   max, min, mid, num_segs;+    FT_UInt   charcode = (FT_UInt)*pcharcode;+    FT_UInt   gindex   = 0;+    FT_Byte*  p;+++    p = cmap->data + 6;+    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );++    if ( !num_segs2 )+      return 0;++    num_segs = num_segs2 >> 1;++    /* make compiler happy */+    mid = num_segs;+    end = 0xFFFFU;++    if ( next )+      charcode++;++    min = 0;+    max = num_segs;++    /* binary search */+    while ( min < max )+    {+      mid    = ( min + max ) >> 1;+      p      = cmap->data + 14 + mid * 2;+      end    = TT_PEEK_USHORT( p );+      p     += 2 + num_segs2;+      start  = TT_PEEK_USHORT( p );++      if ( charcode < start )+        max = mid;+      else if ( charcode > end )+        min = mid + 1;+      else+      {+        p     += num_segs2;+        delta  = TT_PEEK_SHORT( p );+        p     += num_segs2;+        offset = TT_PEEK_USHORT( p );++        /* some fonts have an incorrect last segment; */+        /* we have to catch it                        */+        if ( mid >= num_segs - 1                &&+             start == 0xFFFFU && end == 0xFFFFU )+        {+          TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;+          FT_Byte*  limit = face->cmap_table + face->cmap_size;+++          if ( offset && p + offset + 2 > limit )+          {+            delta  = 1;+            offset = 0;+          }+        }++        /* search the first segment containing `charcode' */+        if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )+        {+          FT_UInt  i;+++          /* call the current segment `max' */+          max = mid;++          if ( offset == 0xFFFFU )+            mid = max + 1;++          /* search in segments before the current segment */+          for ( i = max ; i > 0; i-- )+          {+            FT_UInt   prev_end;+            FT_Byte*  old_p;+++            old_p    = p;+            p        = cmap->data + 14 + ( i - 1 ) * 2;+            prev_end = TT_PEEK_USHORT( p );++            if ( charcode > prev_end )+            {+              p = old_p;+              break;+            }++            end    = prev_end;+            p     += 2 + num_segs2;+            start  = TT_PEEK_USHORT( p );+            p     += num_segs2;+            delta  = TT_PEEK_SHORT( p );+            p     += num_segs2;+            offset = TT_PEEK_USHORT( p );++            if ( offset != 0xFFFFU )+              mid = i - 1;+          }++          /* no luck */+          if ( mid == max + 1 )+          {+            if ( i != max )+            {+              p      = cmap->data + 14 + max * 2;+              end    = TT_PEEK_USHORT( p );+              p     += 2 + num_segs2;+              start  = TT_PEEK_USHORT( p );+              p     += num_segs2;+              delta  = TT_PEEK_SHORT( p );+              p     += num_segs2;+              offset = TT_PEEK_USHORT( p );+            }++            mid = max;++            /* search in segments after the current segment */+            for ( i = max + 1; i < num_segs; i++ )+            {+              FT_UInt  next_end, next_start;+++              p          = cmap->data + 14 + i * 2;+              next_end   = TT_PEEK_USHORT( p );+              p         += 2 + num_segs2;+              next_start = TT_PEEK_USHORT( p );++              if ( charcode < next_start )+                break;++              end    = next_end;+              start  = next_start;+              p     += num_segs2;+              delta  = TT_PEEK_SHORT( p );+              p     += num_segs2;+              offset = TT_PEEK_USHORT( p );++              if ( offset != 0xFFFFU )+                mid = i;+            }+            i--;++            /* still no luck */+            if ( mid == max )+            {+              mid = i;++              break;+            }+          }++          /* end, start, delta, and offset are for the i'th segment */+          if ( mid != i )+          {+            p      = cmap->data + 14 + mid * 2;+            end    = TT_PEEK_USHORT( p );+            p     += 2 + num_segs2;+            start  = TT_PEEK_USHORT( p );+            p     += num_segs2;+            delta  = TT_PEEK_SHORT( p );+            p     += num_segs2;+            offset = TT_PEEK_USHORT( p );+          }+        }+        else+        {+          if ( offset == 0xFFFFU )+            break;+        }++        if ( offset )+        {+          p += offset + ( charcode - start ) * 2;+          gindex = TT_PEEK_USHORT( p );+          if ( gindex != 0 )+            gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;+        }+        else+          gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;++        break;+      }+    }++    if ( next )+    {+      TT_CMap4  cmap4 = (TT_CMap4)cmap;+++      /* if `charcode' is not in any segment, then `mid' is */+      /* the segment nearest to `charcode'                  */+      /*                                                    */++      if ( charcode > end )+      {+        mid++;+        if ( mid == num_segs )+          return 0;+      }++      if ( tt_cmap4_set_range( cmap4, mid ) )+      {+        if ( gindex )+          *pcharcode = charcode;+      }+      else+      {+        cmap4->cur_charcode = charcode;++        if ( gindex )+          cmap4->cur_gindex = gindex;+        else+        {+          cmap4->cur_charcode = charcode;+          tt_cmap4_next( cmap4 );+          gindex = cmap4->cur_gindex;+        }++        if ( gindex )+          *pcharcode = cmap4->cur_charcode;+      }+    }++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap4_char_index( TT_CMap    cmap,+                       FT_UInt32  char_code )+  {+    if ( char_code >= 0x10000UL )+      return 0;++    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )+      return tt_cmap4_char_map_linear( cmap, &char_code, 0 );+    else+      return tt_cmap4_char_map_binary( cmap, &char_code, 0 );+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap4_char_next( TT_CMap     cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_UInt  gindex;+++    if ( *pchar_code >= 0xFFFFU )+      return 0;++    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )+      gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );+    else+    {+      TT_CMap4  cmap4 = (TT_CMap4)cmap;+++      /* no need to search */+      if ( *pchar_code == cmap4->cur_charcode )+      {+        tt_cmap4_next( cmap4 );+        gindex = cmap4->cur_gindex;+        if ( gindex )+          *pchar_code = cmap4->cur_charcode;+      }+      else+        gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );+    }++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap4_get_info( TT_CMap       cmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 4;+++    cmap_info->format   = 4;+    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap4_class_rec,+      sizeof ( TT_CMap4Rec ),+      (FT_CMap_InitFunc)     tt_cmap4_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap4_char_index,+      (FT_CMap_CharNextFunc) tt_cmap4_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    4,+    (TT_CMap_ValidateFunc)   tt_cmap4_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap4_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_4 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 6                             *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET          TYPE             DESCRIPTION            */+  /*                                                                       */+  /*   format       0              USHORT           must be 4              */+  /*   length       2              USHORT           table length in bytes  */+  /*   language     4              USHORT           Mac language code      */+  /*                                                                       */+  /*   first        6              USHORT           first segment code     */+  /*   count        8              USHORT           segment size in chars  */+  /*   glyphIds     10             USHORT[count]    glyph IDs              */+  /*                                                                       */+  /* A very simplified segment mapping.                                    */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_6++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap6_validate( FT_Byte*      table,+                     FT_Validator  valid )+  {+    FT_Byte*  p;+    FT_UInt   length, count;+++    if ( table + 10 > valid->limit )+      FT_INVALID_TOO_SHORT;++    p      = table + 2;+    length = TT_NEXT_USHORT( p );++    p      = table + 8;             /* skip language and start index */+    count  = TT_NEXT_USHORT( p );++    if ( table + length > valid->limit || length < 10 + count * 2 )+      FT_INVALID_TOO_SHORT;++    /* check glyph indices */+    if ( valid->level >= FT_VALIDATE_TIGHT )+    {+      FT_UInt  gindex;+++      for ( ; count > 0; count-- )+      {+        gindex = TT_NEXT_USHORT( p );+        if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )+          FT_INVALID_GLYPH_ID;+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap6_char_index( TT_CMap    cmap,+                       FT_UInt32  char_code )+  {+    FT_Byte*  table  = cmap->data;+    FT_UInt   result = 0;+    FT_Byte*  p      = table + 6;+    FT_UInt   start  = TT_NEXT_USHORT( p );+    FT_UInt   count  = TT_NEXT_USHORT( p );+    FT_UInt   idx    = (FT_UInt)( char_code - start );+++    if ( idx < count )+    {+      p += 2 * idx;+      result = TT_PEEK_USHORT( p );+    }+    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap6_char_next( TT_CMap     cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_Byte*   table     = cmap->data;+    FT_UInt32  result    = 0;+    FT_UInt32  char_code = *pchar_code + 1;+    FT_UInt    gindex    = 0;++    FT_Byte*   p         = table + 6;+    FT_UInt    start     = TT_NEXT_USHORT( p );+    FT_UInt    count     = TT_NEXT_USHORT( p );+    FT_UInt    idx;+++    if ( char_code >= 0x10000UL )+      goto Exit;++    if ( char_code < start )+      char_code = start;++    idx = (FT_UInt)( char_code - start );+    p  += 2 * idx;++    for ( ; idx < count; idx++ )+    {+      gindex = TT_NEXT_USHORT( p );+      if ( gindex != 0 )+      {+        result = char_code;+        break;+      }+      char_code++;+    }++  Exit:+    *pchar_code = result;+    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap6_get_info( TT_CMap       cmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 4;+++    cmap_info->format   = 6;+    cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap6_class_rec,+      sizeof ( TT_CMapRec ),++      (FT_CMap_InitFunc)     tt_cmap_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap6_char_index,+      (FT_CMap_CharNextFunc) tt_cmap6_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    6,+    (TT_CMap_ValidateFunc)   tt_cmap6_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap6_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_6 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 8                             *****/+  /*****                                                               *****/+  /***** It is hard to completely understand what the OpenType spec    *****/+  /***** says about this format, but here is my conclusion.            *****/+  /*****                                                               *****/+  /***** The purpose of this format is to easily map UTF-16 text to    *****/+  /***** glyph indices.  Basically, the `char_code' must be in one of  *****/+  /***** the following formats:                                        *****/+  /*****                                                               *****/+  /*****   - A 16-bit value that isn't part of the Unicode Surrogates  *****/+  /*****     Area (i.e. U+D800-U+DFFF).                                *****/+  /*****                                                               *****/+  /*****   - A 32-bit value, made of two surrogate values, i.e.. if    *****/+  /*****     `char_code = (char_hi << 16) | char_lo', then both        *****/+  /*****     `char_hi' and `char_lo' must be in the Surrogates Area.   *****/+  /*****      Area.                                                    *****/+  /*****                                                               *****/+  /***** The `is32' table embedded in the charmap indicates whether a  *****/+  /***** given 16-bit value is in the surrogates area or not.          *****/+  /*****                                                               *****/+  /***** So, for any given `char_code', we can assert the following:   *****/+  /*****                                                               *****/+  /*****   If `char_hi == 0' then we must have `is32[char_lo] == 0'.   *****/+  /*****                                                               *****/+  /*****   If `char_hi != 0' then we must have both                    *****/+  /*****   `is32[char_hi] != 0' and `is32[char_lo] != 0'.              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET         TYPE        DESCRIPTION                  */+  /*                                                                       */+  /*   format      0              USHORT      must be 8                    */+  /*   reserved    2              USHORT      reserved                     */+  /*   length      4              ULONG       length in bytes              */+  /*   language    8              ULONG       Mac language code            */+  /*   is32        12             BYTE[8192]  32-bitness bitmap            */+  /*   count       8204           ULONG       number of groups             */+  /*                                                                       */+  /* This header is followed by `count' groups of the following format:    */+  /*                                                                       */+  /*   start       0              ULONG       first charcode               */+  /*   end         4              ULONG       last charcode                */+  /*   startId     8              ULONG       start glyph ID for the group */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_8++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap8_validate( FT_Byte*      table,+                     FT_Validator  valid )+  {+    FT_Byte*   p = table + 4;+    FT_Byte*   is32;+    FT_UInt32  length;+    FT_UInt32  num_groups;+++    if ( table + 16 + 8192 > valid->limit )+      FT_INVALID_TOO_SHORT;++    length = TT_NEXT_ULONG( p );+    if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )+      FT_INVALID_TOO_SHORT;++    is32       = table + 12;+    p          = is32  + 8192;          /* skip `is32' array */+    num_groups = TT_NEXT_ULONG( p );++    if ( p + num_groups * 12 > valid->limit )+      FT_INVALID_TOO_SHORT;++    /* check groups, they must be in increasing order */+    {+      FT_UInt32  n, start, end, start_id, count, last = 0;+++      for ( n = 0; n < num_groups; n++ )+      {+        FT_UInt   hi, lo;+++        start    = TT_NEXT_ULONG( p );+        end      = TT_NEXT_ULONG( p );+        start_id = TT_NEXT_ULONG( p );++        if ( start > end )+          FT_INVALID_DATA;++        if ( n > 0 && start <= last )+          FT_INVALID_DATA;++        if ( valid->level >= FT_VALIDATE_TIGHT )+        {+          if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )+            FT_INVALID_GLYPH_ID;++          count = (FT_UInt32)( end - start + 1 );++          if ( start & ~0xFFFFU )+          {+            /* start_hi != 0; check that is32[i] is 1 for each i in */+            /* the `hi' and `lo' of the range [start..end]          */+            for ( ; count > 0; count--, start++ )+            {+              hi = (FT_UInt)( start >> 16 );+              lo = (FT_UInt)( start & 0xFFFFU );++              if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )+                FT_INVALID_DATA;++              if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )+                FT_INVALID_DATA;+            }+          }+          else+          {+            /* start_hi == 0; check that is32[i] is 0 for each i in */+            /* the range [start..end]                               */++            /* end_hi cannot be != 0! */+            if ( end & ~0xFFFFU )+              FT_INVALID_DATA;++            for ( ; count > 0; count--, start++ )+            {+              lo = (FT_UInt)( start & 0xFFFFU );++              if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )+                FT_INVALID_DATA;+            }+          }+        }++        last = end;+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap8_char_index( TT_CMap    cmap,+                       FT_UInt32  char_code )+  {+    FT_Byte*   table      = cmap->data;+    FT_UInt    result     = 0;+    FT_Byte*   p          = table + 8204;+    FT_UInt32  num_groups = TT_NEXT_ULONG( p );+    FT_UInt32  start, end, start_id;+++    for ( ; num_groups > 0; num_groups-- )+    {+      start    = TT_NEXT_ULONG( p );+      end      = TT_NEXT_ULONG( p );+      start_id = TT_NEXT_ULONG( p );++      if ( char_code < start )+        break;++      if ( char_code <= end )+      {+        result = (FT_UInt)( start_id + char_code - start );+        break;+      }+    }+    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap8_char_next( TT_CMap     cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_UInt32  result     = 0;+    FT_UInt32  char_code  = *pchar_code + 1;+    FT_UInt    gindex     = 0;+    FT_Byte*   table      = cmap->data;+    FT_Byte*   p          = table + 8204;+    FT_UInt32  num_groups = TT_NEXT_ULONG( p );+    FT_UInt32  start, end, start_id;+++    p = table + 8208;++    for ( ; num_groups > 0; num_groups-- )+    {+      start    = TT_NEXT_ULONG( p );+      end      = TT_NEXT_ULONG( p );+      start_id = TT_NEXT_ULONG( p );++      if ( char_code < start )+        char_code = start;++      if ( char_code <= end )+      {+        gindex = (FT_UInt)( char_code - start + start_id );+        if ( gindex != 0 )+        {+          result = char_code;+          goto Exit;+        }+      }+    }++  Exit:+    *pchar_code = result;+    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap8_get_info( TT_CMap       cmap,+                     TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 8;+++    cmap_info->format   = 8;+    cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap8_class_rec,+      sizeof ( TT_CMapRec ),++      (FT_CMap_InitFunc)     tt_cmap_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap8_char_index,+      (FT_CMap_CharNextFunc) tt_cmap8_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    8,+    (TT_CMap_ValidateFunc)   tt_cmap8_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap8_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_8 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 10                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME      OFFSET  TYPE               DESCRIPTION                    */+  /*                                                                       */+  /*   format     0      USHORT             must be 10                     */+  /*   reserved   2      USHORT             reserved                       */+  /*   length     4      ULONG              length in bytes                */+  /*   language   8      ULONG              Mac language code              */+  /*                                                                       */+  /*   start     12      ULONG              first char in range            */+  /*   count     16      ULONG              number of chars in range       */+  /*   glyphIds  20      USHORT[count]      glyph indices covered          */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_10++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap10_validate( FT_Byte*      table,+                      FT_Validator  valid )+  {+    FT_Byte*  p = table + 4;+    FT_ULong  length, count;+++    if ( table + 20 > valid->limit )+      FT_INVALID_TOO_SHORT;++    length = TT_NEXT_ULONG( p );+    p      = table + 16;+    count  = TT_NEXT_ULONG( p );++    if ( length > (FT_ULong)( valid->limit - table ) ||+         length < 20 + count * 2                     )+      FT_INVALID_TOO_SHORT;++    /* check glyph indices */+    if ( valid->level >= FT_VALIDATE_TIGHT )+    {+      FT_UInt  gindex;+++      for ( ; count > 0; count-- )+      {+        gindex = TT_NEXT_USHORT( p );+        if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )+          FT_INVALID_GLYPH_ID;+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap10_char_index( TT_CMap    cmap,+                        FT_UInt32  char_code )+  {+    FT_Byte*   table  = cmap->data;+    FT_UInt    result = 0;+    FT_Byte*   p      = table + 12;+    FT_UInt32  start  = TT_NEXT_ULONG( p );+    FT_UInt32  count  = TT_NEXT_ULONG( p );+    FT_UInt32  idx    = (FT_ULong)( char_code - start );+++    if ( idx < count )+    {+      p     += 2 * idx;+      result = TT_PEEK_USHORT( p );+    }+    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap10_char_next( TT_CMap     cmap,+                       FT_UInt32  *pchar_code )+  {+    FT_Byte*   table     = cmap->data;+    FT_UInt32  char_code = *pchar_code + 1;+    FT_UInt    gindex    = 0;+    FT_Byte*   p         = table + 12;+    FT_UInt32  start     = TT_NEXT_ULONG( p );+    FT_UInt32  count     = TT_NEXT_ULONG( p );+    FT_UInt32  idx;+++    if ( char_code < start )+      char_code = start;++    idx = (FT_UInt32)( char_code - start );+    p  += 2 * idx;++    for ( ; idx < count; idx++ )+    {+      gindex = TT_NEXT_USHORT( p );+      if ( gindex != 0 )+        break;+      char_code++;+    }++    *pchar_code = char_code;+    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap10_get_info( TT_CMap       cmap,+                      TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 8;+++    cmap_info->format   = 10;+    cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap10_class_rec,+      sizeof ( TT_CMapRec ),++      (FT_CMap_InitFunc)     tt_cmap_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap10_char_index,+      (FT_CMap_CharNextFunc) tt_cmap10_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    10,+    (TT_CMap_ValidateFunc)   tt_cmap10_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap10_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_10 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 12                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET     TYPE       DESCRIPTION                       */+  /*                                                                       */+  /*   format      0          USHORT     must be 12                        */+  /*   reserved    2          USHORT     reserved                          */+  /*   length      4          ULONG      length in bytes                   */+  /*   language    8          ULONG      Mac language code                 */+  /*   count       12         ULONG      number of groups                  */+  /*               16                                                      */+  /*                                                                       */+  /* This header is followed by `count' groups of the following format:    */+  /*                                                                       */+  /*   start       0          ULONG      first charcode                    */+  /*   end         4          ULONG      last charcode                     */+  /*   startId     8          ULONG      start glyph ID for the group      */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_12++  typedef struct  TT_CMap12Rec_+  {+    TT_CMapRec  cmap;+    FT_Bool     valid;+    FT_ULong    cur_charcode;+    FT_UInt     cur_gindex;+    FT_ULong    cur_group;+    FT_ULong    num_groups;++  } TT_CMap12Rec, *TT_CMap12;+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap12_init( TT_CMap12  cmap,+                  FT_Byte*   table )+  {+    cmap->cmap.data  = table;++    table           += 12;+    cmap->num_groups = FT_PEEK_ULONG( table );++    cmap->valid      = 0;++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap12_validate( FT_Byte*      table,+                      FT_Validator  valid )+  {+    FT_Byte*   p;+    FT_ULong   length;+    FT_ULong   num_groups;+++    if ( table + 16 > valid->limit )+      FT_INVALID_TOO_SHORT;++    p      = table + 4;+    length = TT_NEXT_ULONG( p );++    p          = table + 12;+    num_groups = TT_NEXT_ULONG( p );++    if ( length > (FT_ULong)( valid->limit - table ) ||+         length < 16 + 12 * num_groups               )+      FT_INVALID_TOO_SHORT;++    /* check groups, they must be in increasing order */+    {+      FT_ULong  n, start, end, start_id, last = 0;+++      for ( n = 0; n < num_groups; n++ )+      {+        start    = TT_NEXT_ULONG( p );+        end      = TT_NEXT_ULONG( p );+        start_id = TT_NEXT_ULONG( p );++        if ( start > end )+          FT_INVALID_DATA;++        if ( n > 0 && start <= last )+          FT_INVALID_DATA;++        if ( valid->level >= FT_VALIDATE_TIGHT )+        {+          if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )+            FT_INVALID_GLYPH_ID;+        }++        last = end;+      }+    }++    return SFNT_Err_Ok;+  }+++  /* search the index of the charcode next to cmap->cur_charcode */+  /* cmap->cur_group should be set up properly by caller         */+  /*                                                             */+  static void+  tt_cmap12_next( TT_CMap12  cmap )+  {+    FT_Byte*  p;+    FT_ULong  start, end, start_id, char_code;+    FT_ULong  n;+    FT_UInt   gindex;+++    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )+      goto Fail;++    char_code = cmap->cur_charcode + 1;++    n = cmap->cur_group;++    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )+    {+      p        = cmap->cmap.data + 16 + 12 * n;+      start    = TT_NEXT_ULONG( p );+      end      = TT_NEXT_ULONG( p );+      start_id = TT_PEEK_ULONG( p );++      if ( char_code < start )+        char_code = start;++      for ( ; char_code <= end; char_code++ )+      {+        gindex = (FT_UInt)( start_id + char_code - start );++        if ( gindex )+        {+          cmap->cur_charcode = char_code;;+          cmap->cur_gindex   = gindex;+          cmap->cur_group    = n;++          return;+        }+      }+    }++  Fail:+    cmap->valid = 0;+  }+++  static FT_UInt+  tt_cmap12_char_map_binary( TT_CMap     cmap,+                             FT_UInt32*  pchar_code,+                             FT_Bool     next )+  {+    FT_UInt    gindex     = 0;+    FT_Byte*   p          = cmap->data + 12;+    FT_UInt32  num_groups = TT_PEEK_ULONG( p );+    FT_UInt32  char_code  = *pchar_code;+    FT_UInt32  start, end, start_id;+    FT_UInt32  max, min, mid;+++    if ( !num_groups )+      return 0;++    /* make compiler happy */+    mid = num_groups;+    end = 0xFFFFFFFFUL;++    if ( next )+      char_code++;++    min = 0;+    max = num_groups;++    /* binary search */+    while ( min < max )+    {+      mid = ( min + max ) >> 1;+      p   = cmap->data + 16 + 12 * mid;++      start = TT_NEXT_ULONG( p );+      end   = TT_NEXT_ULONG( p );++      if ( char_code < start )+        max = mid;+      else if ( char_code > end )+        min = mid + 1;+      else+      {+        start_id = TT_PEEK_ULONG( p );+        gindex = (FT_UInt)( start_id + char_code - start );++        break;+      }+    }++    if ( next )+    {+      TT_CMap12  cmap12 = (TT_CMap12)cmap;+++      /* if `char_code' is not in any group, then `mid' is */+      /* the group nearest to `char_code'                  */+      /*                                                   */++      if ( char_code > end )+      {+        mid++;+        if ( mid == num_groups )+          return 0;+      }++      cmap12->valid        = 1;+      cmap12->cur_charcode = char_code;+      cmap12->cur_group    = mid;++      if ( !gindex )+      {+        tt_cmap12_next( cmap12 );++        if ( cmap12->valid )+          gindex = cmap12->cur_gindex;+      }+      else+        cmap12->cur_gindex = gindex;++      if ( gindex )+        *pchar_code = cmap12->cur_charcode;+    }++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap12_char_index( TT_CMap    cmap,+                        FT_UInt32  char_code )+  {+    return tt_cmap12_char_map_binary( cmap, &char_code, 0 );+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap12_char_next( TT_CMap     cmap,+                       FT_UInt32  *pchar_code )+  {+    TT_CMap12  cmap12 = (TT_CMap12)cmap;+    FT_ULong   gindex;+++    if ( cmap12->cur_charcode >= 0xFFFFFFFFUL )+      return 0;++    /* no need to search */+    if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )+    {+      tt_cmap12_next( cmap12 );+      if ( cmap12->valid )+      {+        gindex = cmap12->cur_gindex;++        /* XXX: check cur_charcode overflow is expected */+        if ( gindex )+          *pchar_code = (FT_UInt32)cmap12->cur_charcode;+      }+      else+        gindex = 0;+    }+    else+      gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );++    /* XXX: check gindex overflow is expected */+    return (FT_UInt32)gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap12_get_info( TT_CMap       cmap,+                      TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 8;+++    cmap_info->format   = 12;+    cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap12_class_rec,+      sizeof ( TT_CMap12Rec ),++      (FT_CMap_InitFunc)     tt_cmap12_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap12_char_index,+      (FT_CMap_CharNextFunc) tt_cmap12_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    12,+    (TT_CMap_ValidateFunc)   tt_cmap12_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap12_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_12 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                          FORMAT 13                            *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME        OFFSET     TYPE       DESCRIPTION                       */+  /*                                                                       */+  /*   format      0          USHORT     must be 13                        */+  /*   reserved    2          USHORT     reserved                          */+  /*   length      4          ULONG      length in bytes                   */+  /*   language    8          ULONG      Mac language code                 */+  /*   count       12         ULONG      number of groups                  */+  /*               16                                                      */+  /*                                                                       */+  /* This header is followed by `count' groups of the following format:    */+  /*                                                                       */+  /*   start       0          ULONG      first charcode                    */+  /*   end         4          ULONG      last charcode                     */+  /*   glyphId     8          ULONG      glyph ID for the whole group      */+  /*                                                                       */++#ifdef TT_CONFIG_CMAP_FORMAT_13++  typedef struct  TT_CMap13Rec_+  {+    TT_CMapRec  cmap;+    FT_Bool     valid;+    FT_ULong    cur_charcode;+    FT_UInt     cur_gindex;+    FT_ULong    cur_group;+    FT_ULong    num_groups;++  } TT_CMap13Rec, *TT_CMap13;+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap13_init( TT_CMap13  cmap,+                  FT_Byte*   table )+  {+    cmap->cmap.data  = table;++    table           += 12;+    cmap->num_groups = FT_PEEK_ULONG( table );++    cmap->valid      = 0;++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap13_validate( FT_Byte*      table,+                      FT_Validator  valid )+  {+    FT_Byte*   p;+    FT_ULong   length;+    FT_ULong   num_groups;+++    if ( table + 16 > valid->limit )+      FT_INVALID_TOO_SHORT;++    p      = table + 4;+    length = TT_NEXT_ULONG( p );++    p          = table + 12;+    num_groups = TT_NEXT_ULONG( p );++    if ( length > (FT_ULong)( valid->limit - table ) ||+         length < 16 + 12 * num_groups               )+      FT_INVALID_TOO_SHORT;++    /* check groups, they must be in increasing order */+    {+      FT_ULong  n, start, end, glyph_id, last = 0;+++      for ( n = 0; n < num_groups; n++ )+      {+        start    = TT_NEXT_ULONG( p );+        end      = TT_NEXT_ULONG( p );+        glyph_id = TT_NEXT_ULONG( p );++        if ( start > end )+          FT_INVALID_DATA;++        if ( n > 0 && start <= last )+          FT_INVALID_DATA;++        if ( valid->level >= FT_VALIDATE_TIGHT )+        {+          if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )+            FT_INVALID_GLYPH_ID;+        }++        last = end;+      }+    }++    return SFNT_Err_Ok;+  }+++  /* search the index of the charcode next to cmap->cur_charcode */+  /* cmap->cur_group should be set up properly by caller         */+  /*                                                             */+  static void+  tt_cmap13_next( TT_CMap13  cmap )+  {+    FT_Byte*  p;+    FT_ULong  start, end, glyph_id, char_code;+    FT_ULong  n;+    FT_UInt   gindex;+++    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )+      goto Fail;++    char_code = cmap->cur_charcode + 1;++    n = cmap->cur_group;++    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )+    {+      p        = cmap->cmap.data + 16 + 12 * n;+      start    = TT_NEXT_ULONG( p );+      end      = TT_NEXT_ULONG( p );+      glyph_id = TT_PEEK_ULONG( p );++      if ( char_code < start )+        char_code = start;++      if ( char_code <= end )+      {+        gindex = (FT_UInt)glyph_id;++        if ( gindex )+        {+          cmap->cur_charcode = char_code;;+          cmap->cur_gindex   = gindex;+          cmap->cur_group    = n;++          return;+        }+      }+    }++  Fail:+    cmap->valid = 0;+  }+++  static FT_UInt+  tt_cmap13_char_map_binary( TT_CMap     cmap,+                             FT_UInt32*  pchar_code,+                             FT_Bool     next )+  {+    FT_UInt    gindex     = 0;+    FT_Byte*   p          = cmap->data + 12;+    FT_UInt32  num_groups = TT_PEEK_ULONG( p );+    FT_UInt32  char_code  = *pchar_code;+    FT_UInt32  start, end;+    FT_UInt32  max, min, mid;+++    if ( !num_groups )+      return 0;++    /* make compiler happy */+    mid = num_groups;+    end = 0xFFFFFFFFUL;++    if ( next )+      char_code++;++    min = 0;+    max = num_groups;++    /* binary search */+    while ( min < max )+    {+      mid = ( min + max ) >> 1;+      p   = cmap->data + 16 + 12 * mid;++      start = TT_NEXT_ULONG( p );+      end   = TT_NEXT_ULONG( p );++      if ( char_code < start )+        max = mid;+      else if ( char_code > end )+        min = mid + 1;+      else+      {+        gindex = (FT_UInt)TT_PEEK_ULONG( p );++        break;+      }+    }++    if ( next )+    {+      TT_CMap13  cmap13 = (TT_CMap13)cmap;+++      /* if `char_code' is not in any group, then `mid' is */+      /* the group nearest to `char_code'                  */+      /*                                                   */++      if ( char_code > end )+      {+        mid++;+        if ( mid == num_groups )+          return 0;+      }++      cmap13->valid        = 1;+      cmap13->cur_charcode = char_code;+      cmap13->cur_group    = mid;++      if ( !gindex )+      {+        tt_cmap13_next( cmap13 );++        if ( cmap13->valid )+          gindex = cmap13->cur_gindex;+      }+      else+        cmap13->cur_gindex = gindex;++      if ( gindex )+        *pchar_code = cmap13->cur_charcode;+    }++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap13_char_index( TT_CMap    cmap,+                        FT_UInt32  char_code )+  {+    return tt_cmap13_char_map_binary( cmap, &char_code, 0 );+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap13_char_next( TT_CMap     cmap,+                       FT_UInt32  *pchar_code )+  {+    TT_CMap13  cmap13 = (TT_CMap13)cmap;+    FT_UInt    gindex;+++    if ( cmap13->cur_charcode >= 0xFFFFFFFFUL )+      return 0;++    /* no need to search */+    if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )+    {+      tt_cmap13_next( cmap13 );+      if ( cmap13->valid )+      {+        gindex = cmap13->cur_gindex;+        if ( gindex )+          *pchar_code = cmap13->cur_charcode;+      }+      else+        gindex = 0;+    }+    else+      gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );++    return gindex;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap13_get_info( TT_CMap       cmap,+                      TT_CMapInfo  *cmap_info )+  {+    FT_Byte*  p = cmap->data + 8;+++    cmap_info->format   = 13;+    cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );++    return SFNT_Err_Ok;+  }+++  FT_DEFINE_TT_CMAP(tt_cmap13_class_rec,+      sizeof ( TT_CMap13Rec ),++      (FT_CMap_InitFunc)     tt_cmap13_init,+      (FT_CMap_DoneFunc)     NULL,+      (FT_CMap_CharIndexFunc)tt_cmap13_char_index,+      (FT_CMap_CharNextFunc) tt_cmap13_char_next,++      NULL, NULL, NULL, NULL, NULL+    ,+    13,+    (TT_CMap_ValidateFunc)   tt_cmap13_validate,+    (TT_CMap_Info_GetFunc)   tt_cmap13_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_13 */+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                           FORMAT 14                           *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* TABLE OVERVIEW                                                        */+  /* --------------                                                        */+  /*                                                                       */+  /*   NAME         OFFSET  TYPE    DESCRIPTION                            */+  /*                                                                       */+  /*   format         0     USHORT  must be 14                             */+  /*   length         2     ULONG   table length in bytes                  */+  /*   numSelector    6     ULONG   number of variation sel. records       */+  /*                                                                       */+  /* Followed by numSelector records, each of which looks like             */+  /*                                                                       */+  /*   varSelector    0     UINT24  Unicode codepoint of sel.              */+  /*   defaultOff     3     ULONG   offset to a default UVS table          */+  /*                                describing any variants to be found in */+  /*                                the normal Unicode subtable.           */+  /*   nonDefOff      7     ULONG   offset to a non-default UVS table      */+  /*                                describing any variants not in the     */+  /*                                standard cmap, with GIDs here          */+  /* (either offset may be 0 NULL)                                         */+  /*                                                                       */+  /* Selectors are sorted by code point.                                   */+  /*                                                                       */+  /* A default Unicode Variation Selector (UVS) subtable is just a list of */+  /* ranges of code points which are to be found in the standard cmap.  No */+  /* glyph IDs (GIDs) here.                                                */+  /*                                                                       */+  /*   numRanges      0     ULONG   number of ranges following             */+  /*                                                                       */+  /* A range looks like                                                    */+  /*                                                                       */+  /*   uniStart       0     UINT24  code point of the first character in   */+  /*                                this range                             */+  /*   additionalCnt  3     UBYTE   count of additional characters in this */+  /*                                range (zero means a range of a single  */+  /*                                character)                             */+  /*                                                                       */+  /* Ranges are sorted by `uniStart'.                                      */+  /*                                                                       */+  /* A non-default Unicode Variation Selector (UVS) subtable is a list of  */+  /* mappings from codepoint to GID.                                       */+  /*                                                                       */+  /*   numMappings    0     ULONG   number of mappings                     */+  /*                                                                       */+  /* A range looks like                                                    */+  /*                                                                       */+  /*   uniStart       0     UINT24  code point of the first character in   */+  /*                                this range                             */+  /*   GID            3     USHORT  and its GID                            */+  /*                                                                       */+  /* Ranges are sorted by `uniStart'.                                      */++#ifdef TT_CONFIG_CMAP_FORMAT_14++  typedef struct  TT_CMap14Rec_+  {+    TT_CMapRec  cmap;+    FT_ULong    num_selectors;++    /* This array is used to store the results of various+     * cmap 14 query functions.  The data is overwritten+     * on each call to these functions.+     */+    FT_UInt32   max_results;+    FT_UInt32*  results;+    FT_Memory   memory;++  } TT_CMap14Rec, *TT_CMap14;+++  FT_CALLBACK_DEF( void )+  tt_cmap14_done( TT_CMap14  cmap )+  {+    FT_Memory  memory = cmap->memory;+++    cmap->max_results = 0;+    if ( memory != NULL && cmap->results != NULL )+      FT_FREE( cmap->results );+  }+++  static FT_Error+  tt_cmap14_ensure( TT_CMap14  cmap,+                    FT_UInt32  num_results,+                    FT_Memory  memory )+  {+    FT_UInt32 old_max = cmap->max_results;+    FT_Error  error   = SFNT_Err_Ok;+++    if ( num_results > cmap->max_results )+    {+       cmap->memory = memory;++       if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )+         return error;++       cmap->max_results = num_results;+    }++    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap14_init( TT_CMap14  cmap,+                  FT_Byte*   table )+  {+    cmap->cmap.data = table;++    table               += 6;+    cmap->num_selectors = FT_PEEK_ULONG( table );+    cmap->max_results   = 0;+    cmap->results       = NULL;++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap14_validate( FT_Byte*      table,+                      FT_Validator  valid )+  {+    FT_Byte*  p             = table + 2;+    FT_ULong  length        = TT_NEXT_ULONG( p );+    FT_ULong  num_selectors = TT_NEXT_ULONG( p );+++    if ( length > (FT_ULong)( valid->limit - table ) ||+         length < 10 + 11 * num_selectors            )+      FT_INVALID_TOO_SHORT;++    /* check selectors, they must be in increasing order */+    {+      /* we start lastVarSel at 1 because a variant selector value of 0+       * isn't valid.+       */+      FT_ULong  n, lastVarSel = 1;+++      for ( n = 0; n < num_selectors; n++ )+      {+        FT_ULong  varSel    = TT_NEXT_UINT24( p );+        FT_ULong  defOff    = TT_NEXT_ULONG( p );+        FT_ULong  nondefOff = TT_NEXT_ULONG( p );+++        if ( defOff >= length || nondefOff >= length )+          FT_INVALID_TOO_SHORT;++        if ( varSel < lastVarSel )+          FT_INVALID_DATA;++        lastVarSel = varSel + 1;++        /* check the default table (these glyphs should be reached     */+        /* through the normal Unicode cmap, no GIDs, just check order) */+        if ( defOff != 0 )+        {+          FT_Byte*  defp      = table + defOff;+          FT_ULong  numRanges = TT_NEXT_ULONG( defp );+          FT_ULong  i;+          FT_ULong  lastBase  = 0;+++          if ( defp + numRanges * 4 > valid->limit )+            FT_INVALID_TOO_SHORT;++          for ( i = 0; i < numRanges; ++i )+          {+            FT_ULong  base = TT_NEXT_UINT24( defp );+            FT_ULong  cnt  = FT_NEXT_BYTE( defp );+++            if ( base + cnt >= 0x110000UL )              /* end of Unicode */+              FT_INVALID_DATA;++            if ( base < lastBase )+              FT_INVALID_DATA;++            lastBase = base + cnt + 1U;+          }+        }++        /* and the non-default table (these glyphs are specified here) */+        if ( nondefOff != 0 )+        {+          FT_Byte*  ndp         = table + nondefOff;+          FT_ULong  numMappings = TT_NEXT_ULONG( ndp );+          FT_ULong  i, lastUni = 0;+++          if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )+            FT_INVALID_TOO_SHORT;++          for ( i = 0; i < numMappings; ++i )+          {+            FT_ULong  uni = TT_NEXT_UINT24( ndp );+            FT_ULong  gid = TT_NEXT_USHORT( ndp );+++            if ( uni >= 0x110000UL )                     /* end of Unicode */+              FT_INVALID_DATA;++            if ( uni < lastUni )+              FT_INVALID_DATA;++            lastUni = uni + 1U;++            if ( valid->level >= FT_VALIDATE_TIGHT    &&+                 gid >= TT_VALID_GLYPH_COUNT( valid ) )+              FT_INVALID_GLYPH_ID;+          }+        }+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap14_char_index( TT_CMap    cmap,+                        FT_UInt32  char_code )+  {+    FT_UNUSED( cmap );+    FT_UNUSED( char_code );++    /* This can't happen */+    return 0;+  }+++  FT_CALLBACK_DEF( FT_UInt32 )+  tt_cmap14_char_next( TT_CMap     cmap,+                       FT_UInt32  *pchar_code )+  {+    FT_UNUSED( cmap );++    /* This can't happen */+    *pchar_code = 0;+    return 0;+  }+++  FT_CALLBACK_DEF( FT_Error )+  tt_cmap14_get_info( TT_CMap       cmap,+                      TT_CMapInfo  *cmap_info )+  {+    FT_UNUSED( cmap );++    cmap_info->format   = 14;+    /* subtable 14 does not define a language field */+    cmap_info->language = 0xFFFFFFFFUL;++    return SFNT_Err_Ok;+  }+++  static FT_UInt+  tt_cmap14_char_map_def_binary( FT_Byte    *base,+                                 FT_UInt32   char_code )+  {+    FT_UInt32  numRanges = TT_PEEK_ULONG( base );+    FT_UInt32  max, min;+++    min = 0;+    max = numRanges;++    base += 4;++    /* binary search */+    while ( min < max )+    {+      FT_UInt32  mid   = ( min + max ) >> 1;+      FT_Byte*   p     = base + 4 * mid;+      FT_ULong   start = TT_NEXT_UINT24( p );+      FT_UInt    cnt   = FT_NEXT_BYTE( p );+++      if ( char_code < start )+        max = mid;+      else if ( char_code > start+cnt )+        min = mid + 1;+      else+        return TRUE;+    }++    return FALSE;+  }+++  static FT_UInt+  tt_cmap14_char_map_nondef_binary( FT_Byte    *base,+                                    FT_UInt32   char_code )+  {+    FT_UInt32  numMappings = TT_PEEK_ULONG( base );+    FT_UInt32  max, min;+++    min = 0;+    max = numMappings;++    base += 4;++    /* binary search */+    while ( min < max )+    {+      FT_UInt32  mid = ( min + max ) >> 1;+      FT_Byte*   p   = base + 5 * mid;+      FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );+++      if ( char_code < uni )+        max = mid;+      else if ( char_code > uni )+        min = mid + 1;+      else+        return TT_PEEK_USHORT( p );+    }++    return 0;+  }+++  static FT_Byte*+  tt_cmap14_find_variant( FT_Byte    *base,+                          FT_UInt32   variantCode )+  {+    FT_UInt32  numVar = TT_PEEK_ULONG( base );+    FT_UInt32  max, min;+++    min = 0;+    max = numVar;++    base += 4;++    /* binary search */+    while ( min < max )+    {+      FT_UInt32  mid    = ( min + max ) >> 1;+      FT_Byte*   p      = base + 11 * mid;+      FT_ULong   varSel = TT_NEXT_UINT24( p );+++      if ( variantCode < varSel )+        max = mid;+      else if ( variantCode > varSel )+        min = mid + 1;+      else+        return p;+    }++    return NULL;+  }+++  FT_CALLBACK_DEF( FT_UInt )+  tt_cmap14_char_var_index( TT_CMap    cmap,+                            TT_CMap    ucmap,+                            FT_UInt32  charcode,+                            FT_UInt32  variantSelector)+  {+    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );+    FT_ULong  defOff;+    FT_ULong  nondefOff;+++    if ( !p )+      return 0;++    defOff    = TT_NEXT_ULONG( p );+    nondefOff = TT_PEEK_ULONG( p );++    if ( defOff != 0                                                    &&+         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )+    {+      /* This is the default variant of this charcode.  GID not stored */+      /* here; stored in the normal Unicode charmap instead.           */+      return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );+    }++    if ( nondefOff != 0 )+      return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,+                                               charcode );++    return 0;+  }+++  FT_CALLBACK_DEF( FT_Int )+  tt_cmap14_char_var_isdefault( TT_CMap    cmap,+                                FT_UInt32  charcode,+                                FT_UInt32  variantSelector )+  {+    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );+    FT_ULong  defOff;+    FT_ULong  nondefOff;+++    if ( !p )+      return -1;++    defOff    = TT_NEXT_ULONG( p );+    nondefOff = TT_NEXT_ULONG( p );++    if ( defOff != 0                                                    &&+         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )+      return 1;++    if ( nondefOff != 0                                            &&+         tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,+                                           charcode ) != 0         )+      return 0;++    return -1;+  }+++  FT_CALLBACK_DEF( FT_UInt32* )+  tt_cmap14_variants( TT_CMap    cmap,+                      FT_Memory  memory )+  {+    TT_CMap14   cmap14 = (TT_CMap14)cmap;+    FT_UInt32   count  = cmap14->num_selectors;+    FT_Byte*    p      = cmap->data + 10;+    FT_UInt32*  result;+    FT_UInt32   i;+++    if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )+      return NULL;++    result = cmap14->results;+    for ( i = 0; i < count; ++i )+    {+      result[i] = (FT_UInt32)TT_NEXT_UINT24( p );+      p        += 8;+    }+    result[i] = 0;++    return result;+  }+++  FT_CALLBACK_DEF( FT_UInt32 * )+  tt_cmap14_char_variants( TT_CMap    cmap,+                           FT_Memory  memory,+                           FT_UInt32  charCode )+  {+    TT_CMap14   cmap14 = (TT_CMap14)  cmap;+    FT_UInt32   count  = cmap14->num_selectors;+    FT_Byte*    p      = cmap->data + 10;+    FT_UInt32*  q;+++    if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )+      return NULL;++    for ( q = cmap14->results; count > 0; --count )+    {+      FT_UInt32  varSel    = TT_NEXT_UINT24( p );+      FT_ULong   defOff    = TT_NEXT_ULONG( p );+      FT_ULong   nondefOff = TT_NEXT_ULONG( p );+++      if ( ( defOff != 0                                               &&+             tt_cmap14_char_map_def_binary( cmap->data + defOff,+                                            charCode )                 ) ||+           ( nondefOff != 0                                            &&+             tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,+                                               charCode ) != 0         ) )+      {+        q[0] = varSel;+        q++;+      }+    }+    q[0] = 0;++    return cmap14->results;+  }+++  static FT_UInt+  tt_cmap14_def_char_count( FT_Byte  *p )+  {+    FT_UInt32  numRanges = (FT_UInt32)TT_NEXT_ULONG( p );+    FT_UInt    tot       = 0;+++    p += 3;  /* point to the first `cnt' field */+    for ( ; numRanges > 0; numRanges-- )+    {+      tot += 1 + p[0];+      p   += 4;+    }++    return tot;+  }+++  static FT_UInt32*+  tt_cmap14_get_def_chars( TT_CMap     cmap,+                           FT_Byte*    p,+                           FT_Memory   memory )+  {+    TT_CMap14   cmap14 = (TT_CMap14) cmap;+    FT_UInt32   numRanges;+    FT_UInt     cnt;+    FT_UInt32*  q;+++    cnt       = tt_cmap14_def_char_count( p );+    numRanges = (FT_UInt32)TT_NEXT_ULONG( p );++    if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )+      return NULL;++    for ( q = cmap14->results; numRanges > 0; --numRanges )+    {+      FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );+++      cnt = FT_NEXT_BYTE( p ) + 1;+      do+      {+        q[0]  = uni;+        uni  += 1;+        q    += 1;+      } while ( --cnt != 0 );+    }+    q[0] = 0;++    return cmap14->results;+  }+++  static FT_UInt32*+  tt_cmap14_get_nondef_chars( TT_CMap     cmap,+                              FT_Byte    *p,+                              FT_Memory   memory )+  {+    TT_CMap14   cmap14 = (TT_CMap14) cmap;+    FT_UInt32   numMappings;+    FT_UInt     i;+    FT_UInt32  *ret;+++    numMappings = (FT_UInt32)TT_NEXT_ULONG( p );++    if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )+      return NULL;++    ret = cmap14->results;+    for ( i = 0; i < numMappings; ++i )+    {+      ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );+      p += 2;+    }+    ret[i] = 0;++    return ret;+  }+++  FT_CALLBACK_DEF( FT_UInt32 * )+  tt_cmap14_variant_chars( TT_CMap    cmap,+                           FT_Memory  memory,+                           FT_UInt32  variantSelector )+  {+    FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,+                                             variantSelector );+    FT_UInt32  *ret;+    FT_Int      i;+    FT_ULong    defOff;+    FT_ULong    nondefOff;+++    if ( !p )+      return NULL;++    defOff    = TT_NEXT_ULONG( p );+    nondefOff = TT_NEXT_ULONG( p );++    if ( defOff == 0 && nondefOff == 0 )+      return NULL;++    if ( defOff == 0 )+      return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,+                                         memory );+    else if ( nondefOff == 0 )+      return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,+                                      memory );+    else+    {+      /* Both a default and a non-default glyph set?  That's probably not */+      /* good font design, but the spec allows for it...                  */+      TT_CMap14  cmap14 = (TT_CMap14) cmap;+      FT_UInt32  numRanges;+      FT_UInt32  numMappings;+      FT_UInt32  duni;+      FT_UInt32  dcnt;+      FT_UInt32  nuni;+      FT_Byte*   dp;+      FT_UInt    di, ni, k;+++      p  = cmap->data + nondefOff;+      dp = cmap->data + defOff;++      numMappings = (FT_UInt32)TT_NEXT_ULONG( p );+      dcnt        = tt_cmap14_def_char_count( dp );+      numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );++      if ( numMappings == 0 )+        return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,+                                        memory );+      if ( dcnt == 0 )+        return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,+                                           memory );++      if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )+        return NULL;++      ret  = cmap14->results;+      duni = (FT_UInt32)TT_NEXT_UINT24( dp );+      dcnt = FT_NEXT_BYTE( dp );+      di   = 1;+      nuni = (FT_UInt32)TT_NEXT_UINT24( p );+      p   += 2;+      ni   = 1;+      i    = 0;++      for ( ;; )+      {+        if ( nuni > duni + dcnt )+        {+          for ( k = 0; k <= dcnt; ++k )+            ret[i++] = duni + k;++          ++di;++          if ( di > numRanges )+            break;++          duni = (FT_UInt32)TT_NEXT_UINT24( dp );+          dcnt = FT_NEXT_BYTE( dp );+        }+        else+        {+          if ( nuni < duni )+            ret[i++] = nuni;+          /* If it is within the default range then ignore it -- */+          /* that should not have happened                       */+          ++ni;+          if ( ni > numMappings )+            break;++          nuni = (FT_UInt32)TT_NEXT_UINT24( p );+          p += 2;+        }+      }++      if ( ni <= numMappings )+      {+        /* If we get here then we have run out of all default ranges.   */+        /* We have read one non-default mapping which we haven't stored */+        /* and there may be others that need to be read.                */+        ret[i++] = nuni;+        while ( ni < numMappings )+        {+          ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );+          p += 2;+          ++ni;+        }+      }+      else if ( di <= numRanges )+      {+        /* If we get here then we have run out of all non-default     */+        /* mappings.  We have read one default range which we haven't */+        /* stored and there may be others that need to be read.       */+        for ( k = 0; k <= dcnt; ++k )+          ret[i++] = duni + k;++        while ( di < numRanges )+        {+          duni = (FT_UInt32)TT_NEXT_UINT24( dp );+          dcnt = FT_NEXT_BYTE( dp );++          for ( k = 0; k <= dcnt; ++k )+            ret[i++] = duni + k;+          ++di;+        }+      }++      ret[i] = 0;++      return ret;+    }+  }+++  FT_DEFINE_TT_CMAP(tt_cmap14_class_rec,+      sizeof ( TT_CMap14Rec ),++      (FT_CMap_InitFunc)     tt_cmap14_init,+      (FT_CMap_DoneFunc)     tt_cmap14_done,+      (FT_CMap_CharIndexFunc)tt_cmap14_char_index,+      (FT_CMap_CharNextFunc) tt_cmap14_char_next,++      /* Format 14 extension functions */+      (FT_CMap_CharVarIndexFunc)    tt_cmap14_char_var_index,+      (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,+      (FT_CMap_VariantListFunc)     tt_cmap14_variants,+      (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,+      (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars+    ,+    14,+    (TT_CMap_ValidateFunc)tt_cmap14_validate,+    (TT_CMap_Info_GetFunc)tt_cmap14_get_info+  )++#endif /* TT_CONFIG_CMAP_FORMAT_14 */+++#ifndef FT_CONFIG_OPTION_PIC++  static const TT_CMap_Class  tt_cmap_classes[] =+  {+#define TTCMAPCITEM(a) &a,+#include "ttcmapc.h"+    NULL,+  };++#else /*FT_CONFIG_OPTION_PIC*/++  void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz)+  {+    FT_Memory memory = library->memory;+    if ( clazz )+      FT_FREE( clazz );+  }++  FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class)+  {+    TT_CMap_Class*  clazz;+    TT_CMap_ClassRec* recs;+    FT_Error          error;+    FT_Memory memory = library->memory;+    int i = 0;++#define TTCMAPCITEM(a) i++;+#include "ttcmapc.h"++    /* allocate enough space for both the pointers +terminator and the class instances */+    if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) )+      return error;++    /* the location of the class instances follows the array of pointers */+    recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); +    i=0;++#undef TTCMAPCITEM+#define TTCMAPCITEM(a)           \+    FT_Init_Class_##a(&recs[i]); \+    clazz[i] = &recs[i];         \+    i++;+#include "ttcmapc.h"++    clazz[i] = NULL;++    *output_class = clazz;+    return SFNT_Err_Ok;+  }++#endif /*FT_CONFIG_OPTION_PIC*/+++  /* parse the `cmap' table and build the corresponding TT_CMap objects */+  /* in the current face                                                */+  /*                                                                    */+  FT_LOCAL_DEF( FT_Error )+  tt_face_build_cmaps( TT_Face  face )+  {+    FT_Byte*           table = face->cmap_table;+    FT_Byte*           limit = table + face->cmap_size;+    FT_UInt volatile   num_cmaps;+    FT_Byte* volatile  p     = table;+    FT_Library         library = FT_FACE_LIBRARY( face );++    FT_UNUSED( library );+++    if ( !p || p + 4 > limit )+      return SFNT_Err_Invalid_Table;++    /* only recognize format 0 */+    if ( TT_NEXT_USHORT( p ) != 0 )+    {+      p -= 2;+      FT_ERROR(( "tt_face_build_cmaps:"+                 " unsupported `cmap' table format = %d\n",+                 TT_PEEK_USHORT( p ) ));+      return SFNT_Err_Invalid_Table;+    }++    num_cmaps = TT_NEXT_USHORT( p );+#ifdef FT_MAX_CHARMAP_CACHEABLE+    if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )+      FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables(%d) "+                 "subtable#%d and later are loaded but cannot be searched\n",+                 num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));+#endif++    for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )+    {+      FT_CharMapRec  charmap;+      FT_UInt32      offset;+++      charmap.platform_id = TT_NEXT_USHORT( p );+      charmap.encoding_id = TT_NEXT_USHORT( p );+      charmap.face        = FT_FACE( face );+      charmap.encoding    = FT_ENCODING_NONE;  /* will be filled later */+      offset              = TT_NEXT_ULONG( p );++      if ( offset && offset <= face->cmap_size - 2 )+      {+        FT_Byte* volatile              cmap   = table + offset;+        volatile FT_UInt               format = TT_PEEK_USHORT( cmap );+        const TT_CMap_Class* volatile  pclazz = FT_TT_CMAP_CLASSES_GET;+        TT_CMap_Class volatile         clazz;+++        for ( ; *pclazz; pclazz++ )+        {+          clazz = *pclazz;+          if ( clazz->format == format )+          {+            volatile TT_ValidatorRec  valid;+            volatile FT_Error         error = SFNT_Err_Ok;+++            ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,+                               FT_VALIDATE_DEFAULT );++            valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;++            if ( ft_setjmp(+              *((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 )+            {+              /* validate this cmap sub-table */+              error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );+            }++            if ( valid.validator.error == 0 )+            {+              FT_CMap  ttcmap;+++              /* It might make sense to store the single variation selector */+              /* cmap somewhere special.  But it would have to be in the    */+              /* public FT_FaceRec, and we can't change that.               */++              if ( !FT_CMap_New( (FT_CMap_Class)clazz,+                                 cmap, &charmap, &ttcmap ) )+              {+                /* it is simpler to directly set `flags' than adding */+                /* a parameter to FT_CMap_New                        */+                ((TT_CMap)ttcmap)->flags = (FT_Int)error;+              }+            }+            else+            {+              FT_TRACE0(( "tt_face_build_cmaps:"+                          " broken cmap sub-table ignored\n" ));+            }+            break;+          }+        }++        if ( *pclazz == NULL )+        {+          FT_TRACE0(( "tt_face_build_cmaps:"+                      " unsupported cmap sub-table ignored\n" ));+        }+      }+    }++    return SFNT_Err_Ok;+  }+++  FT_LOCAL( FT_Error )+  tt_get_cmap_info( FT_CharMap    charmap,+                    TT_CMapInfo  *cmap_info )+  {+    FT_CMap        cmap  = (FT_CMap)charmap;+    TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;+++    return clazz->get_cmap_info( charmap, cmap_info );+  }+++/* END */
+ src/sfnt/ttcmap.h view
@@ -0,0 +1,125 @@+/***************************************************************************/+/*                                                                         */+/*  ttcmap.h                                                               */+/*                                                                         */+/*    TrueType character mapping table (cmap) support (specification).     */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTCMAP_H__+#define __TTCMAP_H__+++#include <ft2build.h>+#include FT_INTERNAL_TRUETYPE_TYPES_H+#include FT_INTERNAL_VALIDATE_H+#include FT_SERVICE_TT_CMAP_H++FT_BEGIN_HEADER+++#define TT_CMAP_FLAG_UNSORTED     1+#define TT_CMAP_FLAG_OVERLAPPING  2++  typedef struct  TT_CMapRec_+  {+    FT_CMapRec  cmap;+    FT_Byte*    data;           /* pointer to in-memory cmap table */+    FT_Int      flags;          /* for format 4 only               */++  } TT_CMapRec, *TT_CMap;++  typedef const struct TT_CMap_ClassRec_*  TT_CMap_Class;+++  typedef FT_Error+  (*TT_CMap_ValidateFunc)( FT_Byte*      data,+                           FT_Validator  valid );++  typedef struct  TT_CMap_ClassRec_+  {+    FT_CMap_ClassRec      clazz;+    FT_UInt               format;+    TT_CMap_ValidateFunc  validate;+    TT_CMap_Info_GetFunc  get_cmap_info;++  } TT_CMap_ClassRec;++#ifndef FT_CONFIG_OPTION_PIC++#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_,          \+    char_next_, char_var_index_, char_var_default_, variant_list_,           \+    charvariant_list_,variantchar_list_,                                     \+    format_, validate_, get_cmap_info_)                                      \+  FT_CALLBACK_TABLE_DEF                                                      \+  const TT_CMap_ClassRec class_ =                                            \+  {                                                                          \+    {size_, init_, done_, char_index_,                                       \+     char_next_, char_var_index_, char_var_default_, variant_list_,          \+     charvariant_list_, variantchar_list_},                                  \+    format_, validate_, get_cmap_info_                                       \+  };++#else /* FT_CONFIG_OPTION_PIC */ ++#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_,          \+    char_next_, char_var_index_, char_var_default_, variant_list_,           \+    charvariant_list_,variantchar_list_,                                     \+    format_, validate_, get_cmap_info_)                                      \+  void                                                                       \+  FT_Init_Class_##class_( TT_CMap_ClassRec*  clazz )                         \+  {                                                                          \+    clazz->clazz.size = size_;                                               \+    clazz->clazz.init = init_;                                               \+    clazz->clazz.done = done_;                                               \+    clazz->clazz.char_index = char_index_;                                   \+    clazz->clazz.char_next = char_next_;                                     \+    clazz->clazz.char_var_index = char_var_index_;                           \+    clazz->clazz.char_var_default = char_var_default_;                       \+    clazz->clazz.variant_list = variant_list_;                               \+    clazz->clazz.charvariant_list = charvariant_list_;                       \+    clazz->clazz.variantchar_list = variantchar_list_;                       \+    clazz->format = format_;                                                 \+    clazz->validate = validate_;                                             \+    clazz->get_cmap_info = get_cmap_info_;                                   \+  } ++#endif /* FT_CONFIG_OPTION_PIC */ ++  typedef struct  TT_ValidatorRec_+  {+    FT_ValidatorRec  validator;+    FT_UInt          num_glyphs;++  } TT_ValidatorRec, *TT_Validator;+++#define TT_VALIDATOR( x )          ((TT_Validator)( x ))+#define TT_VALID_GLYPH_COUNT( x )  TT_VALIDATOR( x )->num_glyphs+++  FT_LOCAL( FT_Error )+  tt_face_build_cmaps( TT_Face  face );++  /* used in tt-cmaps service */+  FT_LOCAL( FT_Error )+  tt_get_cmap_info( FT_CharMap    charmap,+                    TT_CMapInfo  *cmap_info );+++FT_END_HEADER++#endif /* __TTCMAP_H__ */+++/* END */
+ src/sfnt/ttcmapc.h view
@@ -0,0 +1,55 @@+/***************************************************************************/+/*                                                                         */+/*  ttcmapc.h                                                              */+/*                                                                         */+/*    TT CMAP classes definitions (specification only).                    */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifdef TT_CONFIG_CMAP_FORMAT_0+    TTCMAPCITEM(tt_cmap0_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_2+    TTCMAPCITEM(tt_cmap2_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_4+    TTCMAPCITEM(tt_cmap4_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_6+    TTCMAPCITEM(tt_cmap6_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_8+    TTCMAPCITEM(tt_cmap8_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_10+    TTCMAPCITEM(tt_cmap10_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_12+    TTCMAPCITEM(tt_cmap12_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_13+    TTCMAPCITEM(tt_cmap13_class_rec)+#endif++#ifdef TT_CONFIG_CMAP_FORMAT_14+    TTCMAPCITEM(tt_cmap14_class_rec)+#endif++  /* END */
+ src/sfnt/ttkern.c view
@@ -0,0 +1,306 @@+/***************************************************************************/+/*                                                                         */+/*  ttkern.c                                                               */+/*                                                                         */+/*    Load the basic TrueType kerning table.  This doesn't handle          */+/*    kerning data within the GPOS table at the moment.                    */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttkern.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttkern+++#undef  TT_KERN_INDEX+#define TT_KERN_INDEX( g1, g2 )  ( ( (FT_ULong)(g1) << 16 ) | (g2) )+++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_kern( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error   error;+    FT_ULong   table_size;+    FT_Byte*   p;+    FT_Byte*   p_limit;+    FT_UInt    nn, num_tables;+    FT_UInt32  avail = 0, ordered = 0;+++    /* the kern table is optional; exit silently if it is missing */+    error = face->goto_table( face, TTAG_kern, stream, &table_size );+    if ( error )+      goto Exit;++    if ( table_size < 4 )  /* the case of a malformed table */+    {+      FT_ERROR(( "tt_face_load_kern:"+                 " kerning table is too small - ignored\n" ));+      error = SFNT_Err_Table_Missing;+      goto Exit;+    }++    if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) )+    {+      FT_ERROR(( "tt_face_load_kern:"+                 " could not extract kerning table\n" ));+      goto Exit;+    }++    face->kern_table_size = table_size;++    p       = face->kern_table;+    p_limit = p + table_size;++    p         += 2; /* skip version */+    num_tables = FT_NEXT_USHORT( p );++    if ( num_tables > 32 ) /* we only support up to 32 sub-tables */+      num_tables = 32;++    for ( nn = 0; nn < num_tables; nn++ )+    {+      FT_UInt    num_pairs, length, coverage;+      FT_Byte*   p_next;+      FT_UInt32  mask = (FT_UInt32)1UL << nn;+++      if ( p + 6 > p_limit )+        break;++      p_next = p;++      p += 2; /* skip version */+      length   = FT_NEXT_USHORT( p );+      coverage = FT_NEXT_USHORT( p );++      if ( length <= 6 )+        break;++      p_next += length;++      if ( p_next > p_limit )  /* handle broken table */+        p_next = p_limit;++      /* only use horizontal kerning tables */+      if ( ( coverage & ~8 ) != 0x0001 ||+           p + 8 > p_limit             )+        goto NextTable;++      num_pairs = FT_NEXT_USHORT( p );+      p        += 6;++      if ( ( p_next - p ) < 6 * (int)num_pairs ) /* handle broken count */+        num_pairs = (FT_UInt)( ( p_next - p ) / 6 );++      avail |= mask;++      /*+       *  Now check whether the pairs in this table are ordered.+       *  We then can use binary search.+       */+      if ( num_pairs > 0 )+      {+        FT_ULong  count;+        FT_ULong  old_pair;+++        old_pair = FT_NEXT_ULONG( p );+        p       += 2;++        for ( count = num_pairs - 1; count > 0; count-- )+        {+          FT_UInt32  cur_pair;+++          cur_pair = FT_NEXT_ULONG( p );+          if ( cur_pair <= old_pair )+            break;++          p += 2;+          old_pair = cur_pair;+        }++        if ( count == 0 )+          ordered |= mask;+      }++    NextTable:+      p = p_next;+    }++    face->num_kern_tables = nn;+    face->kern_avail_bits = avail;+    face->kern_order_bits = ordered;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  tt_face_done_kern( TT_Face  face )+  {+    FT_Stream  stream = face->root.stream;+++    FT_FRAME_RELEASE( face->kern_table );+    face->kern_table_size = 0;+    face->num_kern_tables = 0;+    face->kern_avail_bits = 0;+    face->kern_order_bits = 0;+  }+++  FT_LOCAL_DEF( FT_Int )+  tt_face_get_kerning( TT_Face  face,+                       FT_UInt  left_glyph,+                       FT_UInt  right_glyph )+  {+    FT_Int    result = 0;+    FT_UInt   count, mask = 1;+    FT_Byte*  p       = face->kern_table;+    FT_Byte*  p_limit = p + face->kern_table_size;+++    p   += 4;+    mask = 0x0001;++    for ( count = face->num_kern_tables;+          count > 0 && p + 6 <= p_limit;+          count--, mask <<= 1 )+    {+      FT_Byte* base     = p;+      FT_Byte* next     = base;+      FT_UInt  version  = FT_NEXT_USHORT( p );+      FT_UInt  length   = FT_NEXT_USHORT( p );+      FT_UInt  coverage = FT_NEXT_USHORT( p );+      FT_UInt  num_pairs;+      FT_Int   value    = 0;++      FT_UNUSED( version );+++      next = base + length;++      if ( next > p_limit )  /* handle broken table */+        next = p_limit;++      if ( ( face->kern_avail_bits & mask ) == 0 )+        goto NextTable;++      if ( p + 8 > next )+        goto NextTable;++      num_pairs = FT_NEXT_USHORT( p );+      p        += 6;++      if ( ( next - p ) < 6 * (int)num_pairs )  /* handle broken count  */+        num_pairs = (FT_UInt)( ( next - p ) / 6 );++      switch ( coverage >> 8 )+      {+      case 0:+        {+          FT_ULong  key0 = TT_KERN_INDEX( left_glyph, right_glyph );+++          if ( face->kern_order_bits & mask )   /* binary search */+          {+            FT_UInt   min = 0;+            FT_UInt   max = num_pairs;+++            while ( min < max )+            {+              FT_UInt   mid = ( min + max ) >> 1;+              FT_Byte*  q   = p + 6 * mid;+              FT_ULong  key;+++              key = FT_NEXT_ULONG( q );++              if ( key == key0 )+              {+                value = FT_PEEK_SHORT( q );+                goto Found;+              }+              if ( key < key0 )+                min = mid + 1;+              else+                max = mid;+            }+          }+          else /* linear search */+          {+            FT_UInt  count2;+++            for ( count2 = num_pairs; count2 > 0; count2-- )+            {+              FT_ULong  key = FT_NEXT_ULONG( p );+++              if ( key == key0 )+              {+                value = FT_PEEK_SHORT( p );+                goto Found;+              }+              p += 2;+            }+          }+        }+        break;++       /*+        *  We don't support format 2 because we haven't seen a single font+        *  using it in real life...+        */++      default:+        ;+      }++      goto NextTable;++    Found:+      if ( coverage & 8 ) /* override or add */+        result = value;+      else+        result += value;++    NextTable:+      p = next;+    }++    return result;+  }++#undef TT_KERN_INDEX++/* END */
+ src/sfnt/ttkern.h view
@@ -0,0 +1,52 @@+/***************************************************************************/+/*                                                                         */+/*  ttkern.h                                                               */+/*                                                                         */+/*    Load the basic TrueType kerning table.  This doesn't handle          */+/*    kerning data within the GPOS table at the moment.                    */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2005, 2007 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTKERN_H__+#define __TTKERN_H__+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error  )+  tt_face_load_kern( TT_Face    face,+                     FT_Stream  stream );++  FT_LOCAL( void )+  tt_face_done_kern( TT_Face  face );++  FT_LOCAL( FT_Int )+  tt_face_get_kerning( TT_Face     face,+                       FT_UInt     left_glyph,+                       FT_UInt     right_glyph );++#define TT_FACE_HAS_KERNING( face )  ( (face)->kern_avail_bits != 0 )+++FT_END_HEADER++#endif /* __TTKERN_H__ */+++/* END */
+ src/sfnt/ttload.c view
@@ -0,0 +1,1267 @@+/***************************************************************************/+/*                                                                         */+/*  ttload.c                                                               */+/*                                                                         */+/*    Load the basic TrueType tables, i.e., tables that can be either in   */+/*    TTF or OTF fonts (body).                                             */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttload.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttload+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_lookup_table                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Looks for a TrueType table by name.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A face object handle.                                      */+  /*                                                                       */+  /*    tag  :: The searched tag.                                          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A pointer to the table directory entry.  0 if not found.           */+  /*                                                                       */+  FT_LOCAL_DEF( TT_Table  )+  tt_face_lookup_table( TT_Face   face,+                        FT_ULong  tag  )+  {+    TT_Table  entry;+    TT_Table  limit;+#ifdef FT_DEBUG_LEVEL_TRACE+    FT_Bool   zero_length = FALSE;+#endif+++    FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",+                face,+                (FT_Char)( tag >> 24 ),+                (FT_Char)( tag >> 16 ),+                (FT_Char)( tag >> 8  ),+                (FT_Char)( tag       ) ));++    entry = face->dir_tables;+    limit = entry + face->num_tables;++    for ( ; entry < limit; entry++ )+    {+      /* For compatibility with Windows, we consider    */+      /* zero-length tables the same as missing tables. */+      if ( entry->Tag == tag )+      {+        if ( entry->Length != 0 )+        {+          FT_TRACE4(( "found table.\n" ));+          return entry;+        }+#ifdef FT_DEBUG_LEVEL_TRACE+        zero_length = TRUE;+#endif+      }+    }++#ifdef FT_DEBUG_LEVEL_TRACE+    if ( zero_length )+      FT_TRACE4(( "ignoring empty table\n" ));+    else+      FT_TRACE4(( "could not find table\n" ));+#endif++    return NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_goto_table                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Looks for a TrueType table by name, then seek a stream to it.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A face object handle.                                    */+  /*                                                                       */+  /*    tag    :: The searched tag.                                        */+  /*                                                                       */+  /*    stream :: The stream to seek when the table is found.              */+  /*                                                                       */+  /* <Output>                                                              */+  /*    length :: The length of the table if found, undefined otherwise.   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_goto_table( TT_Face    face,+                      FT_ULong   tag,+                      FT_Stream  stream,+                      FT_ULong*  length )+  {+    TT_Table  table;+    FT_Error  error;+++    table = tt_face_lookup_table( face, tag );+    if ( table )+    {+      if ( length )+        *length = table->Length;++      if ( FT_STREAM_SEEK( table->Offset ) )+        goto Exit;+    }+    else+      error = SFNT_Err_Table_Missing;++  Exit:+    return error;+  }+++  /* Here, we                                                         */+  /*                                                                  */+  /* - check that `num_tables' is valid (and adjust it if necessary)  */+  /*                                                                  */+  /* - look for a `head' table, check its size, and parse it to check */+  /*   whether its `magic' field is correctly set                     */+  /*                                                                  */+  /* - errors (except errors returned by stream handling)             */+  /*                                                                  */+  /*     SFNT_Err_Unknown_File_Format:                                */+  /*       no table is defined in directory, it is not sfnt-wrapped   */+  /*       data                                                       */+  /*     SFNT_Err_Table_Missing:                                      */+  /*       table directory is valid, but essential tables             */+  /*       (head/bhed/SING) are missing                               */+  /*                                                                  */+  static FT_Error+  check_table_dir( SFNT_Header  sfnt,+                   FT_Stream    stream )+  {+    FT_Error   error;+    FT_UShort  nn, valid_entries = 0;+    FT_UInt    has_head = 0, has_sing = 0, has_meta = 0;+    FT_ULong   offset = sfnt->offset + 12;++    static const FT_Frame_Field  table_dir_entry_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_TableRec++      FT_FRAME_START( 16 ),+        FT_FRAME_ULONG( Tag ),+        FT_FRAME_ULONG( CheckSum ),+        FT_FRAME_ULONG( Offset ),+        FT_FRAME_ULONG( Length ),+      FT_FRAME_END+    };+++    if ( FT_STREAM_SEEK( offset ) )+      goto Exit;++    for ( nn = 0; nn < sfnt->num_tables; nn++ )+    {+      TT_TableRec  table;+++      if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )+      {+        nn--;+        FT_TRACE2(( "check_table_dir:"+                    " can read only %d table%s in font (instead of %d)\n",+                    nn, nn == 1 ? "" : "s", sfnt->num_tables ));+        sfnt->num_tables = nn;+        break;+      }++      /* we ignore invalid tables */+      if ( table.Offset + table.Length > stream->size )+      {+        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));+        continue;+      }+      else+        valid_entries++;++      if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )+      {+        FT_UInt32  magic;+++#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+        if ( table.Tag == TTAG_head )+#endif+          has_head = 1;++        /*+         * The table length should be 0x36, but certain font tools make it+         * 0x38, so we will just check that it is greater.+         *+         * Note that according to the specification, the table must be+         * padded to 32-bit lengths, but this doesn't apply to the value of+         * its `Length' field!+         *+         */+        if ( table.Length < 0x36 )+        {+          FT_TRACE2(( "check_table_dir: `head' table too small\n" ));+          error = SFNT_Err_Table_Missing;+          goto Exit;+        }++        if ( FT_STREAM_SEEK( table.Offset + 12 ) ||+             FT_READ_ULONG( magic )              )+          goto Exit;++        if ( magic != 0x5F0F3CF5UL )+        {+          FT_TRACE2(( "check_table_dir:"+                      " no magic number found in `head' table\n"));+          error = SFNT_Err_Table_Missing;+          goto Exit;+        }++        if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )+          goto Exit;+      }+      else if ( table.Tag == TTAG_SING )+        has_sing = 1;+      else if ( table.Tag == TTAG_META )+        has_meta = 1;+    }++    sfnt->num_tables = valid_entries;++    if ( sfnt->num_tables == 0 )+    {+      FT_TRACE2(( "check_table_dir: no tables found\n" ));+      error = SFNT_Err_Unknown_File_Format;+      goto Exit;+    }++    /* if `sing' and `meta' tables are present, there is no `head' table */+    if ( has_head || ( has_sing && has_meta ) )+    {+      error = SFNT_Err_Ok;+      goto Exit;+    }+    else+    {+      FT_TRACE2(( "check_table_dir:" ));+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+      FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));+#else+      FT_TRACE2(( " neither `head' nor `sing' table found\n" ));+#endif+      error = SFNT_Err_Table_Missing;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_font_dir                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the header of a SFNT font file.                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face       :: A handle to the target face object.                  */+  /*                                                                       */+  /*    stream     :: The input stream.                                    */+  /*                                                                       */+  /* <Output>                                                              */+  /*    sfnt       :: The SFNT header.                                     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be at the beginning of the font directory.  */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_font_dir( TT_Face    face,+                         FT_Stream  stream )+  {+    SFNT_HeaderRec  sfnt;+    FT_Error        error;+    FT_Memory       memory = stream->memory;+    TT_TableRec*    entry;+    FT_Int          nn;++    static const FT_Frame_Field  offset_table_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  SFNT_HeaderRec++      FT_FRAME_START( 8 ),+        FT_FRAME_USHORT( num_tables ),+        FT_FRAME_USHORT( search_range ),+        FT_FRAME_USHORT( entry_selector ),+        FT_FRAME_USHORT( range_shift ),+      FT_FRAME_END+    };+++    FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));++    /* read the offset table */++    sfnt.offset = FT_STREAM_POS();++    if ( FT_READ_ULONG( sfnt.format_tag )                    ||+         FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )+      goto Exit;++    /* many fonts don't have these fields set correctly */+#if 0+    if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )        ||+         sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )+      return SFNT_Err_Unknown_File_Format;+#endif++    /* load the table directory */++    FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));+    FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));++    /* check first */+    error = check_table_dir( &sfnt, stream );+    if ( error )+    {+      FT_TRACE2(( "tt_face_load_font_dir:"+                  " invalid table directory for TrueType\n" ));++      goto Exit;+    }++    face->num_tables = sfnt.num_tables;+    face->format_tag = sfnt.format_tag;++    if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )+      goto Exit;++    if ( FT_STREAM_SEEK( sfnt.offset + 12 )       ||+         FT_FRAME_ENTER( face->num_tables * 16L ) )+      goto Exit;++    entry = face->dir_tables;++    FT_TRACE2(( "\n"+                "  tag    offset    length   checksum\n"+                "  ----------------------------------\n" ));++    for ( nn = 0; nn < sfnt.num_tables; nn++ )+    {+      entry->Tag      = FT_GET_TAG4();+      entry->CheckSum = FT_GET_ULONG();+      entry->Offset   = FT_GET_LONG();+      entry->Length   = FT_GET_LONG();++      /* ignore invalid tables */+      if ( entry->Offset + entry->Length > stream->size )+        continue;+      else+      {+        FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx\n",+                    (FT_Char)( entry->Tag >> 24 ),+                    (FT_Char)( entry->Tag >> 16 ),+                    (FT_Char)( entry->Tag >> 8  ),+                    (FT_Char)( entry->Tag       ),+                    entry->Offset,+                    entry->Length,+                    entry->CheckSum ));+        entry++;+      }+    }++    FT_FRAME_EXIT();++    FT_TRACE2(( "table directory loaded\n\n" ));++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_any                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads any font table into client memory.                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: The face object to look for.                             */+  /*                                                                       */+  /*    tag    :: The tag of table to load.  Use the value 0 if you want   */+  /*              to access the whole font file, else set this parameter   */+  /*              to a valid TrueType table tag that you can forge with    */+  /*              the MAKE_TT_TAG macro.                                   */+  /*                                                                       */+  /*    offset :: The starting offset in the table (or the file if         */+  /*              tag == 0).                                               */+  /*                                                                       */+  /*    length :: The address of the decision variable:                    */+  /*                                                                       */+  /*                If length == NULL:                                     */+  /*                  Loads the whole table.  Returns an error if          */+  /*                  `offset' == 0!                                       */+  /*                                                                       */+  /*                If *length == 0:                                       */+  /*                  Exits immediately; returning the length of the given */+  /*                  table or of the font file, depending on the value of */+  /*                  `tag'.                                               */+  /*                                                                       */+  /*                If *length != 0:                                       */+  /*                  Loads the next `length' bytes of table or font,      */+  /*                  starting at offset `offset' (in table or font too).  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    buffer :: The address of target buffer.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_any( TT_Face    face,+                    FT_ULong   tag,+                    FT_Long    offset,+                    FT_Byte*   buffer,+                    FT_ULong*  length )+  {+    FT_Error   error;+    FT_Stream  stream;+    TT_Table   table;+    FT_ULong   size;+++    if ( tag != 0 )+    {+      /* look for tag in font directory */+      table = tt_face_lookup_table( face, tag );+      if ( !table )+      {+        error = SFNT_Err_Table_Missing;+        goto Exit;+      }++      offset += table->Offset;+      size    = table->Length;+    }+    else+      /* tag == 0 -- the user wants to access the font file directly */+      size = face->root.stream->size;++    if ( length && *length == 0 )+    {+      *length = size;++      return SFNT_Err_Ok;+    }++    if ( length )+      size = *length;++    stream = face->root.stream;+    /* the `if' is syntactic sugar for picky compilers */+    if ( FT_STREAM_READ_AT( offset, buffer, size ) )+      goto Exit;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_generic_header                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the TrueType table `head' or `bhed'.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  tt_face_load_generic_header( TT_Face    face,+                               FT_Stream  stream,+                               FT_ULong   tag )+  {+    FT_Error    error;+    TT_Header*  header;++    static const FT_Frame_Field  header_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_Header++      FT_FRAME_START( 54 ),+        FT_FRAME_ULONG ( Table_Version ),+        FT_FRAME_ULONG ( Font_Revision ),+        FT_FRAME_LONG  ( CheckSum_Adjust ),+        FT_FRAME_LONG  ( Magic_Number ),+        FT_FRAME_USHORT( Flags ),+        FT_FRAME_USHORT( Units_Per_EM ),+        FT_FRAME_LONG  ( Created[0] ),+        FT_FRAME_LONG  ( Created[1] ),+        FT_FRAME_LONG  ( Modified[0] ),+        FT_FRAME_LONG  ( Modified[1] ),+        FT_FRAME_SHORT ( xMin ),+        FT_FRAME_SHORT ( yMin ),+        FT_FRAME_SHORT ( xMax ),+        FT_FRAME_SHORT ( yMax ),+        FT_FRAME_USHORT( Mac_Style ),+        FT_FRAME_USHORT( Lowest_Rec_PPEM ),+        FT_FRAME_SHORT ( Font_Direction ),+        FT_FRAME_SHORT ( Index_To_Loc_Format ),+        FT_FRAME_SHORT ( Glyph_Data_Format ),+      FT_FRAME_END+    };+++    error = face->goto_table( face, tag, stream, 0 );+    if ( error )+      goto Exit;++    header = &face->header;++    if ( FT_STREAM_READ_FIELDS( header_fields, header ) )+      goto Exit;++    FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));+    FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_head( TT_Face    face,+                     FT_Stream  stream )+  {+    return tt_face_load_generic_header( face, stream, TTAG_head );+  }+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_bhed( TT_Face    face,+                     FT_Stream  stream )+  {+    return tt_face_load_generic_header( face, stream, TTAG_bhed );+  }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_max_profile                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the maximum profile into a face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_maxp( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error        error;+    TT_MaxProfile*  maxProfile = &face->max_profile;++    const FT_Frame_Field  maxp_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_MaxProfile++      FT_FRAME_START( 6 ),+        FT_FRAME_LONG  ( version ),+        FT_FRAME_USHORT( numGlyphs ),+      FT_FRAME_END+    };++    const FT_Frame_Field  maxp_fields_extra[] =+    {+      FT_FRAME_START( 26 ),+        FT_FRAME_USHORT( maxPoints ),+        FT_FRAME_USHORT( maxContours ),+        FT_FRAME_USHORT( maxCompositePoints ),+        FT_FRAME_USHORT( maxCompositeContours ),+        FT_FRAME_USHORT( maxZones ),+        FT_FRAME_USHORT( maxTwilightPoints ),+        FT_FRAME_USHORT( maxStorage ),+        FT_FRAME_USHORT( maxFunctionDefs ),+        FT_FRAME_USHORT( maxInstructionDefs ),+        FT_FRAME_USHORT( maxStackElements ),+        FT_FRAME_USHORT( maxSizeOfInstructions ),+        FT_FRAME_USHORT( maxComponentElements ),+        FT_FRAME_USHORT( maxComponentDepth ),+      FT_FRAME_END+    };+++    error = face->goto_table( face, TTAG_maxp, stream, 0 );+    if ( error )+      goto Exit;++    if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )+      goto Exit;++    maxProfile->maxPoints             = 0;+    maxProfile->maxContours           = 0;+    maxProfile->maxCompositePoints    = 0;+    maxProfile->maxCompositeContours  = 0;+    maxProfile->maxZones              = 0;+    maxProfile->maxTwilightPoints     = 0;+    maxProfile->maxStorage            = 0;+    maxProfile->maxFunctionDefs       = 0;+    maxProfile->maxInstructionDefs    = 0;+    maxProfile->maxStackElements      = 0;+    maxProfile->maxSizeOfInstructions = 0;+    maxProfile->maxComponentElements  = 0;+    maxProfile->maxComponentDepth     = 0;++    if ( maxProfile->version >= 0x10000L )+    {+      if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )+        goto Exit;++      /* XXX: an adjustment that is necessary to load certain */+      /*      broken fonts like `Keystrokes MT' :-(           */+      /*                                                      */+      /*   We allocate 64 function entries by default when    */+      /*   the maxFunctionDefs value is smaller.              */++      if ( maxProfile->maxFunctionDefs < 64 )+        maxProfile->maxFunctionDefs = 64;++      /* we add 4 phantom points later */+      if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )+      {+        FT_TRACE0(( "tt_face_load_maxp:"+                    " too much twilight points in `maxp' table;\n"+                    "                  "+                    " some glyphs might be rendered incorrectly\n" ));++        maxProfile->maxTwilightPoints = 0xFFFFU - 4;+      }++      /* we arbitrarily limit recursion to avoid stack exhaustion */+      if ( maxProfile->maxComponentDepth > 100 )+      {+        FT_TRACE0(( "tt_face_load_maxp:"+                    " abnormally large component depth (%d) set to 100\n",+                    maxProfile->maxComponentDepth ));+        maxProfile->maxComponentDepth = 100;+      }+    }++    FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_names                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the name records.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_name( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error      error;+    FT_Memory     memory = stream->memory;+    FT_ULong      table_pos, table_len;+    FT_ULong      storage_start, storage_limit;+    FT_UInt       count;+    TT_NameTable  table;++    static const FT_Frame_Field  name_table_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_NameTableRec++      FT_FRAME_START( 6 ),+        FT_FRAME_USHORT( format ),+        FT_FRAME_USHORT( numNameRecords ),+        FT_FRAME_USHORT( storageOffset ),+      FT_FRAME_END+    };++    static const FT_Frame_Field  name_record_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_NameEntryRec++      /* no FT_FRAME_START */+        FT_FRAME_USHORT( platformID ),+        FT_FRAME_USHORT( encodingID ),+        FT_FRAME_USHORT( languageID ),+        FT_FRAME_USHORT( nameID ),+        FT_FRAME_USHORT( stringLength ),+        FT_FRAME_USHORT( stringOffset ),+      FT_FRAME_END+    };+++    table         = &face->name_table;+    table->stream = stream;++    error = face->goto_table( face, TTAG_name, stream, &table_len );+    if ( error )+      goto Exit;++    table_pos = FT_STREAM_POS();+++    if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )+      goto Exit;++    /* Some popular Asian fonts have an invalid `storageOffset' value   */+    /* (it should be at least "6 + 12*num_names").  However, the string */+    /* offsets, computed as "storageOffset + entry->stringOffset", are  */+    /* valid pointers within the name table...                          */+    /*                                                                  */+    /* We thus can't check `storageOffset' right now.                   */+    /*                                                                  */+    storage_start = table_pos + 6 + 12*table->numNameRecords;+    storage_limit = table_pos + table_len;++    if ( storage_start > storage_limit )+    {+      FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));+      error = SFNT_Err_Name_Table_Missing;+      goto Exit;+    }++    /* Allocate the array of name records. */+    count                 = table->numNameRecords;+    table->numNameRecords = 0;++    if ( FT_NEW_ARRAY( table->names, count ) ||+         FT_FRAME_ENTER( count * 12 )        )+      goto Exit;++    /* Load the name records and determine how much storage is needed */+    /* to hold the strings themselves.                                */+    {+      TT_NameEntryRec*  entry = table->names;+++      for ( ; count > 0; count-- )+      {+        if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )+          continue;++        /* check that the name is not empty */+        if ( entry->stringLength == 0 )+          continue;++        /* check that the name string is within the table */+        entry->stringOffset += table_pos + table->storageOffset;+        if ( entry->stringOffset                       < storage_start ||+             entry->stringOffset + entry->stringLength > storage_limit )+        {+          /* invalid entry - ignore it */+          entry->stringOffset = 0;+          entry->stringLength = 0;+          continue;+        }++        entry++;+      }++      table->numNameRecords = (FT_UInt)( entry - table->names );+    }++    FT_FRAME_EXIT();++    /* everything went well, update face->num_names */+    face->num_names = (FT_UShort) table->numNameRecords;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_free_names                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Frees the name records.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the target face object.                        */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_face_free_name( TT_Face  face )+  {+    FT_Memory     memory = face->root.driver->root.memory;+    TT_NameTable  table  = &face->name_table;+    TT_NameEntry  entry  = table->names;+    FT_UInt       count  = table->numNameRecords;+++    if ( table->names )+    {+      for ( ; count > 0; count--, entry++ )+      {+        FT_FREE( entry->string );+        entry->stringLength = 0;+      }++      /* free strings table */+      FT_FREE( table->names );+    }++    table->numNameRecords = 0;+    table->format         = 0;+    table->storageOffset  = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_cmap                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the cmap directory in a face object.  The cmaps themselves   */+  /*    are loaded on demand in the `ttcmap.c' module.                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_cmap( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error  error;+++    error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );+    if ( error )+      goto Exit;++    if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )+      face->cmap_size = 0;++  Exit:+    return error;+  }++++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_os2                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the OS2 table.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_os2( TT_Face    face,+                    FT_Stream  stream )+  {+    FT_Error  error;+    TT_OS2*   os2;++    const FT_Frame_Field  os2_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_OS2++      FT_FRAME_START( 78 ),+        FT_FRAME_USHORT( version ),+        FT_FRAME_SHORT ( xAvgCharWidth ),+        FT_FRAME_USHORT( usWeightClass ),+        FT_FRAME_USHORT( usWidthClass ),+        FT_FRAME_SHORT ( fsType ),+        FT_FRAME_SHORT ( ySubscriptXSize ),+        FT_FRAME_SHORT ( ySubscriptYSize ),+        FT_FRAME_SHORT ( ySubscriptXOffset ),+        FT_FRAME_SHORT ( ySubscriptYOffset ),+        FT_FRAME_SHORT ( ySuperscriptXSize ),+        FT_FRAME_SHORT ( ySuperscriptYSize ),+        FT_FRAME_SHORT ( ySuperscriptXOffset ),+        FT_FRAME_SHORT ( ySuperscriptYOffset ),+        FT_FRAME_SHORT ( yStrikeoutSize ),+        FT_FRAME_SHORT ( yStrikeoutPosition ),+        FT_FRAME_SHORT ( sFamilyClass ),+        FT_FRAME_BYTE  ( panose[0] ),+        FT_FRAME_BYTE  ( panose[1] ),+        FT_FRAME_BYTE  ( panose[2] ),+        FT_FRAME_BYTE  ( panose[3] ),+        FT_FRAME_BYTE  ( panose[4] ),+        FT_FRAME_BYTE  ( panose[5] ),+        FT_FRAME_BYTE  ( panose[6] ),+        FT_FRAME_BYTE  ( panose[7] ),+        FT_FRAME_BYTE  ( panose[8] ),+        FT_FRAME_BYTE  ( panose[9] ),+        FT_FRAME_ULONG ( ulUnicodeRange1 ),+        FT_FRAME_ULONG ( ulUnicodeRange2 ),+        FT_FRAME_ULONG ( ulUnicodeRange3 ),+        FT_FRAME_ULONG ( ulUnicodeRange4 ),+        FT_FRAME_BYTE  ( achVendID[0] ),+        FT_FRAME_BYTE  ( achVendID[1] ),+        FT_FRAME_BYTE  ( achVendID[2] ),+        FT_FRAME_BYTE  ( achVendID[3] ),++        FT_FRAME_USHORT( fsSelection ),+        FT_FRAME_USHORT( usFirstCharIndex ),+        FT_FRAME_USHORT( usLastCharIndex ),+        FT_FRAME_SHORT ( sTypoAscender ),+        FT_FRAME_SHORT ( sTypoDescender ),+        FT_FRAME_SHORT ( sTypoLineGap ),+        FT_FRAME_USHORT( usWinAscent ),+        FT_FRAME_USHORT( usWinDescent ),+      FT_FRAME_END+    };++    const FT_Frame_Field  os2_fields_extra[] =+    {+      FT_FRAME_START( 8 ),+        FT_FRAME_ULONG( ulCodePageRange1 ),+        FT_FRAME_ULONG( ulCodePageRange2 ),+      FT_FRAME_END+    };++    const FT_Frame_Field  os2_fields_extra2[] =+    {+      FT_FRAME_START( 10 ),+        FT_FRAME_SHORT ( sxHeight ),+        FT_FRAME_SHORT ( sCapHeight ),+        FT_FRAME_USHORT( usDefaultChar ),+        FT_FRAME_USHORT( usBreakChar ),+        FT_FRAME_USHORT( usMaxContext ),+      FT_FRAME_END+    };+++    /* We now support old Mac fonts where the OS/2 table doesn't  */+    /* exist.  Simply put, we set the `version' field to 0xFFFF   */+    /* and test this value each time we need to access the table. */+    error = face->goto_table( face, TTAG_OS2, stream, 0 );+    if ( error )+      goto Exit;++    os2 = &face->os2;++    if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )+      goto Exit;++    os2->ulCodePageRange1 = 0;+    os2->ulCodePageRange2 = 0;+    os2->sxHeight         = 0;+    os2->sCapHeight       = 0;+    os2->usDefaultChar    = 0;+    os2->usBreakChar      = 0;+    os2->usMaxContext     = 0;++    if ( os2->version >= 0x0001 )+    {+      /* only version 1 tables */+      if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )+        goto Exit;++      if ( os2->version >= 0x0002 )+      {+        /* only version 2 tables */+        if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )+          goto Exit;+      }+    }++    FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));+    FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));+    FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));+    FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));+    FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_postscript                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the Postscript table.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_post( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error        error;+    TT_Postscript*  post = &face->postscript;++    static const FT_Frame_Field  post_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_Postscript++      FT_FRAME_START( 32 ),+        FT_FRAME_ULONG( FormatType ),+        FT_FRAME_ULONG( italicAngle ),+        FT_FRAME_SHORT( underlinePosition ),+        FT_FRAME_SHORT( underlineThickness ),+        FT_FRAME_ULONG( isFixedPitch ),+        FT_FRAME_ULONG( minMemType42 ),+        FT_FRAME_ULONG( maxMemType42 ),+        FT_FRAME_ULONG( minMemType1 ),+        FT_FRAME_ULONG( maxMemType1 ),+      FT_FRAME_END+    };+++    error = face->goto_table( face, TTAG_post, stream, 0 );+    if ( error )+      return error;++    if ( FT_STREAM_READ_FIELDS( post_fields, post ) )+      return error;++    /* we don't load the glyph names, we do that in another */+    /* module (ttpost).                                     */++    FT_TRACE3(( "FormatType:   0x%x\n", post->FormatType ));+    FT_TRACE3(( "isFixedPitch:   %s\n", post->isFixedPitch+                                        ? "  yes" : "   no" ));++    return SFNT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_pclt                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the PCL 5 Table.                                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_pclt( TT_Face    face,+                     FT_Stream  stream )+  {+    static const FT_Frame_Field  pclt_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_PCLT++      FT_FRAME_START( 54 ),+        FT_FRAME_ULONG ( Version ),+        FT_FRAME_ULONG ( FontNumber ),+        FT_FRAME_USHORT( Pitch ),+        FT_FRAME_USHORT( xHeight ),+        FT_FRAME_USHORT( Style ),+        FT_FRAME_USHORT( TypeFamily ),+        FT_FRAME_USHORT( CapHeight ),+        FT_FRAME_BYTES ( TypeFace, 16 ),+        FT_FRAME_BYTES ( CharacterComplement, 8 ),+        FT_FRAME_BYTES ( FileName, 6 ),+        FT_FRAME_CHAR  ( StrokeWeight ),+        FT_FRAME_CHAR  ( WidthType ),+        FT_FRAME_BYTE  ( SerifStyle ),+        FT_FRAME_BYTE  ( Reserved ),+      FT_FRAME_END+    };++    FT_Error  error;+    TT_PCLT*  pclt = &face->pclt;+++    /* optional table */+    error = face->goto_table( face, TTAG_PCLT, stream, 0 );+    if ( error )+      goto Exit;++    if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )+      goto Exit;++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_gasp                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the `gasp' table into a face object.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_gasp( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;++    FT_UInt        j,num_ranges;+    TT_GaspRange   gaspranges;+++    /* the gasp table is optional */+    error = face->goto_table( face, TTAG_gasp, stream, 0 );+    if ( error )+      goto Exit;++    if ( FT_FRAME_ENTER( 4L ) )+      goto Exit;++    face->gasp.version   = FT_GET_USHORT();+    face->gasp.numRanges = FT_GET_USHORT();++    FT_FRAME_EXIT();++    /* only support versions 0 and 1 of the table */+    if ( face->gasp.version >= 2 )+    {+      face->gasp.numRanges = 0;+      error = SFNT_Err_Invalid_Table;+      goto Exit;+    }++    num_ranges = face->gasp.numRanges;+    FT_TRACE3(( "numRanges: %u\n", num_ranges ));++    if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||+         FT_FRAME_ENTER( num_ranges * 4L )      )+      goto Exit;++    face->gasp.gaspRanges = gaspranges;++    for ( j = 0; j < num_ranges; j++ )+    {+      gaspranges[j].maxPPEM  = FT_GET_USHORT();+      gaspranges[j].gaspFlag = FT_GET_USHORT();++      FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",+                  j,+                  gaspranges[j].maxPPEM,+                  gaspranges[j].gaspFlag ));+    }++    FT_FRAME_EXIT();++  Exit:+    return error;+  }+++/* END */
+ src/sfnt/ttload.h view
@@ -0,0 +1,112 @@+/***************************************************************************/+/*                                                                         */+/*  ttload.h                                                               */+/*                                                                         */+/*    Load the basic TrueType tables, i.e., tables that can be either in   */+/*    TTF or OTF fonts (specification).                                    */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2005, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTLOAD_H__+#define __TTLOAD_H__+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  FT_LOCAL( TT_Table  )+  tt_face_lookup_table( TT_Face   face,+                        FT_ULong  tag );++  FT_LOCAL( FT_Error )+  tt_face_goto_table( TT_Face    face,+                      FT_ULong   tag,+                      FT_Stream  stream,+                      FT_ULong*  length );+++  FT_LOCAL( FT_Error )+  tt_face_load_font_dir( TT_Face    face,+                         FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_any( TT_Face    face,+                    FT_ULong   tag,+                    FT_Long    offset,+                    FT_Byte*   buffer,+                    FT_ULong*  length );+++  FT_LOCAL( FT_Error )+  tt_face_load_head( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_cmap( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_maxp( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_name( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_os2( TT_Face    face,+                    FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_post( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_pclt( TT_Face    face,+                     FT_Stream  stream );++  FT_LOCAL( void )+  tt_face_free_name( TT_Face  face );+++  FT_LOCAL( FT_Error )+  tt_face_load_gasp( TT_Face    face,+                     FT_Stream  stream );++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  FT_LOCAL( FT_Error )+  tt_face_load_bhed( TT_Face    face,+                     FT_Stream  stream );++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */+++FT_END_HEADER++#endif /* __TTLOAD_H__ */+++/* END */
+ src/sfnt/ttmtx.c view
@@ -0,0 +1,468 @@+/***************************************************************************/+/*                                                                         */+/*  ttmtx.c                                                                */+/*                                                                         */+/*    Load the metrics tables common to TTF and OTF fonts (body).          */+/*                                                                         */+/*  Copyright 2006, 2007, 2008, 2009 by                                    */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttmtx.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttmtx+++  /*+   *  Unfortunately, we can't enable our memory optimizations if+   *  FT_CONFIG_OPTION_OLD_INTERNALS is defined.  This is because at least+   *  one rogue client (libXfont in the X.Org XServer) is directly accessing+   *  the metrics.+   */++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_hmtx                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the `hmtx' or `vmtx' table into a face object.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: A handle to the target face object.                    */+  /*                                                                       */+  /*    stream   :: The input stream.                                      */+  /*                                                                       */+  /*    vertical :: A boolean flag.  If set, load `vmtx'.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_hmtx( TT_Face    face,+                     FT_Stream  stream,+                     FT_Bool    vertical )+  {+    FT_Error   error;+    FT_ULong   tag, table_size;+    FT_ULong*  ptable_offset;+    FT_ULong*  ptable_size;+++    if ( vertical )+    {+      tag           = TTAG_vmtx;+      ptable_offset = &face->vert_metrics_offset;+      ptable_size   = &face->vert_metrics_size;+    }+    else+    {+      tag           = TTAG_hmtx;+      ptable_offset = &face->horz_metrics_offset;+      ptable_size   = &face->horz_metrics_size;+    }++    error = face->goto_table( face, tag, stream, &table_size );+    if ( error )+      goto Fail;++    *ptable_size   = table_size;+    *ptable_offset = FT_STREAM_POS();++  Fail:+    return error;+  }++#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_hmtx( TT_Face    face,+                     FT_Stream  stream,+                     FT_Bool    vertical )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;++    FT_ULong   table_len;+    FT_Long    num_shorts, num_longs, num_shorts_checked;++    TT_LongMetrics*    longs;+    TT_ShortMetrics**  shorts;+    FT_Byte*           p;+++    if ( vertical )+    {+      void*   lm = &face->vertical.long_metrics;+      void**  sm = &face->vertical.short_metrics;+++      error = face->goto_table( face, TTAG_vmtx, stream, &table_len );+      if ( error )+        goto Fail;++      num_longs = face->vertical.number_Of_VMetrics;+      if ( (FT_ULong)num_longs > table_len / 4 )+        num_longs = (FT_Long)( table_len / 4 );++      face->vertical.number_Of_VMetrics = 0;++      longs  = (TT_LongMetrics*)lm;+      shorts = (TT_ShortMetrics**)sm;+    }+    else+    {+      void*   lm = &face->horizontal.long_metrics;+      void**  sm = &face->horizontal.short_metrics;+++      error = face->goto_table( face, TTAG_hmtx, stream, &table_len );+      if ( error )+        goto Fail;++      num_longs = face->horizontal.number_Of_HMetrics;+      if ( (FT_ULong)num_longs > table_len / 4 )+        num_longs = (FT_Long)( table_len / 4 );++      face->horizontal.number_Of_HMetrics = 0;++      longs  = (TT_LongMetrics*)lm;+      shorts = (TT_ShortMetrics**)sm;+    }++    /* never trust derived values */++    num_shorts         = face->max_profile.numGlyphs - num_longs;+    num_shorts_checked = ( table_len - num_longs * 4L ) / 2;++    if ( num_shorts < 0 )+    {+      FT_TRACE0(( "tt_face_load_hmtx:"+                  " %cmtx has more metrics than glyphs.\n",+                  vertical ? "v" : "h" ));++      /* Adobe simply ignores this problem.  So we shall do the same. */+#if 0+      error = vertical ? SFNT_Err_Invalid_Vert_Metrics+                       : SFNT_Err_Invalid_Horiz_Metrics;+      goto Exit;+#else+      num_shorts = 0;+#endif+    }++    if ( FT_QNEW_ARRAY( *longs,  num_longs  ) ||+         FT_QNEW_ARRAY( *shorts, num_shorts ) )+      goto Fail;++    if ( FT_FRAME_ENTER( table_len ) )+      goto Fail;++    p = stream->cursor;++    {+      TT_LongMetrics  cur   = *longs;+      TT_LongMetrics  limit = cur + num_longs;+++      for ( ; cur < limit; cur++ )+      {+        cur->advance = FT_NEXT_USHORT( p );+        cur->bearing = FT_NEXT_SHORT( p );+      }+    }++    /* do we have an inconsistent number of metric values? */+    {+      TT_ShortMetrics*  cur   = *shorts;+      TT_ShortMetrics*  limit = cur ++                                FT_MIN( num_shorts, num_shorts_checked );+++      for ( ; cur < limit; cur++ )+        *cur = FT_NEXT_SHORT( p );++      /* We fill up the missing left side bearings with the     */+      /* last valid value.  Since this will occur for buggy CJK */+      /* fonts usually only, nothing serious will happen.       */+      if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )+      {+        FT_Short  val = (*shorts)[num_shorts_checked - 1];+++        limit = *shorts + num_shorts;+        for ( ; cur < limit; cur++ )+          *cur = val;+      }+    }++    FT_FRAME_EXIT();++    if ( vertical )+      face->vertical.number_Of_VMetrics = (FT_UShort)num_longs;+    else+      face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs;++  Fail:+    return error;+  }++#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_hhea                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the `hhea' or 'vhea' table into a face object.                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face     :: A handle to the target face object.                    */+  /*                                                                       */+  /*    stream   :: The input stream.                                      */+  /*                                                                       */+  /*    vertical :: A boolean flag.  If set, load `vhea'.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_hhea( TT_Face    face,+                     FT_Stream  stream,+                     FT_Bool    vertical )+  {+    FT_Error        error;+    TT_HoriHeader*  header;++    const FT_Frame_Field  metrics_header_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_HoriHeader++      FT_FRAME_START( 36 ),+        FT_FRAME_ULONG ( Version ),+        FT_FRAME_SHORT ( Ascender ),+        FT_FRAME_SHORT ( Descender ),+        FT_FRAME_SHORT ( Line_Gap ),+        FT_FRAME_USHORT( advance_Width_Max ),+        FT_FRAME_SHORT ( min_Left_Side_Bearing ),+        FT_FRAME_SHORT ( min_Right_Side_Bearing ),+        FT_FRAME_SHORT ( xMax_Extent ),+        FT_FRAME_SHORT ( caret_Slope_Rise ),+        FT_FRAME_SHORT ( caret_Slope_Run ),+        FT_FRAME_SHORT ( caret_Offset ),+        FT_FRAME_SHORT ( Reserved[0] ),+        FT_FRAME_SHORT ( Reserved[1] ),+        FT_FRAME_SHORT ( Reserved[2] ),+        FT_FRAME_SHORT ( Reserved[3] ),+        FT_FRAME_SHORT ( metric_Data_Format ),+        FT_FRAME_USHORT( number_Of_HMetrics ),+      FT_FRAME_END+    };+++    if ( vertical )+    {+      void  *v = &face->vertical;+++      error = face->goto_table( face, TTAG_vhea, stream, 0 );+      if ( error )+        goto Fail;++      header = (TT_HoriHeader*)v;+    }+    else+    {+      error = face->goto_table( face, TTAG_hhea, stream, 0 );+      if ( error )+        goto Fail;++      header = &face->horizontal;+    }++    if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )+      goto Fail;++    FT_TRACE3(( "Ascender:          %5d\n", header->Ascender ));+    FT_TRACE3(( "Descender:         %5d\n", header->Descender ));+    FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));++    header->long_metrics  = NULL;+    header->short_metrics = NULL;++  Fail:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_get_metrics                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Returns the horizontal or vertical metrics in font units for a     */+  /*    given glyph.  The metrics are the left side bearing (resp. top     */+  /*    side bearing) and advance width (resp. advance height).            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    header  :: A pointer to either the horizontal or vertical metrics  */+  /*               structure.                                              */+  /*                                                                       */+  /*    idx     :: The glyph index.                                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    bearing :: The bearing, either left side or top side.              */+  /*                                                                       */+  /*    advance :: The advance width resp. advance height.                 */+  /*                                                                       */+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS++  FT_LOCAL_DEF( FT_Error )+  tt_face_get_metrics( TT_Face     face,+                       FT_Bool     vertical,+                       FT_UInt     gindex,+                       FT_Short   *abearing,+                       FT_UShort  *aadvance )+  {+    FT_Error        error;+    FT_Stream       stream = face->root.stream;+    TT_HoriHeader*  header;+    FT_ULong        table_pos, table_size, table_end;+    FT_UShort       k;+++    if ( vertical )+    {+      void*  v = &face->vertical;+++      header     = (TT_HoriHeader*)v;+      table_pos  = face->vert_metrics_offset;+      table_size = face->vert_metrics_size;+    }+    else+    {+      header     = &face->horizontal;+      table_pos  = face->horz_metrics_offset;+      table_size = face->horz_metrics_size;+    }++    table_end = table_pos + table_size;++    k = header->number_Of_HMetrics;++    if ( k > 0 )+    {+      if ( gindex < (FT_UInt)k )+      {+        table_pos += 4 * gindex;+        if ( table_pos + 4 > table_end )+          goto NoData;++        if ( FT_STREAM_SEEK( table_pos ) ||+             FT_READ_USHORT( *aadvance ) ||+             FT_READ_SHORT( *abearing )  )+          goto NoData;+      }+      else+      {+        table_pos += 4 * ( k - 1 );+        if ( table_pos + 4 > table_end )+          goto NoData;++        if ( FT_STREAM_SEEK( table_pos ) ||+             FT_READ_USHORT( *aadvance ) )+          goto NoData;++        table_pos += 4 + 2 * ( gindex - k );+        if ( table_pos + 2 > table_end )+          *abearing = 0;+        else+        {+          if ( !FT_STREAM_SEEK( table_pos ) )+            (void)FT_READ_SHORT( *abearing );+        }+      }+    }+    else+    {+    NoData:+      *abearing = 0;+      *aadvance = 0;+    }++    return SFNT_Err_Ok;+  }++#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */++  FT_LOCAL_DEF( FT_Error )+  tt_face_get_metrics( TT_Face     face,+                       FT_Bool     vertical,+                       FT_UInt     gindex,+                       FT_Short*   abearing,+                       FT_UShort*  aadvance )+  {+    void*           v = &face->vertical;+    void*           h = &face->horizontal;+    TT_HoriHeader*  header = vertical ? (TT_HoriHeader*)v+                                      : (TT_HoriHeader*)h;+    TT_LongMetrics  longs_m;+    FT_UShort       k = header->number_Of_HMetrics;+++    if ( k == 0                                         ||+         !header->long_metrics                          ||+         gindex >= (FT_UInt)face->max_profile.numGlyphs )+    {+      *abearing = *aadvance = 0;+      return SFNT_Err_Ok;+    }++    if ( gindex < (FT_UInt)k )+    {+      longs_m   = (TT_LongMetrics)header->long_metrics + gindex;+      *abearing = longs_m->bearing;+      *aadvance = longs_m->advance;+    }+    else+    {+      *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k];+      *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;+    }++    return SFNT_Err_Ok;+  }++#endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */+++/* END */
+ src/sfnt/ttmtx.h view
@@ -0,0 +1,55 @@+/***************************************************************************/+/*                                                                         */+/*  ttmtx.h                                                                */+/*                                                                         */+/*    Load the metrics tables common to TTF and OTF fonts (specification). */+/*                                                                         */+/*  Copyright 2006 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTMTX_H__+#define __TTMTX_H__+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  tt_face_load_hhea( TT_Face    face,+                     FT_Stream  stream,+                     FT_Bool    vertical );+++  FT_LOCAL( FT_Error )+  tt_face_load_hmtx( TT_Face    face,+                     FT_Stream  stream,+                     FT_Bool    vertical );+++  FT_LOCAL( FT_Error )+  tt_face_get_metrics( TT_Face     face,+                       FT_Bool     vertical,+                       FT_UInt     gindex,+                       FT_Short*   abearing,+                       FT_UShort*  aadvance );++FT_END_HEADER++#endif /* __TTMTX_H__ */+++/* END */
+ src/sfnt/ttpost.c view
@@ -0,0 +1,563 @@+/***************************************************************************/+/*                                                                         */+/*  ttpost.c                                                               */+/*                                                                         */+/*    Postcript name table processing for TrueType and OpenType fonts      */+/*    (body).                                                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* The post table is not completely loaded by the core engine.  This     */+  /* file loads the missing PS glyph names and implements an API to access */+  /* them.                                                                 */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttpost.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttpost+++  /* If this configuration macro is defined, we rely on the `PSNames' */+  /* module to grab the glyph names.                                  */++#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES+++#include FT_SERVICE_POSTSCRIPT_CMAPS_H++#define MAC_NAME( x )  ( (FT_String*)psnames->macintosh_name( x ) )+++#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */+++   /* Otherwise, we ignore the `PSNames' module, and provide our own  */+   /* table of Mac names.  Thus, it is possible to build a version of */+   /* FreeType without the Type 1 driver & PSNames module.            */++#define MAC_NAME( x )  ( (FT_String*)tt_post_default_names[x] )++  /* the 258 default Mac PS glyph names */++  static const FT_String* const  tt_post_default_names[258] =+  {+    /*   0 */+    ".notdef", ".null", "CR", "space", "exclam",+    "quotedbl", "numbersign", "dollar", "percent", "ampersand",+    /*  10 */+    "quotesingle", "parenleft", "parenright", "asterisk", "plus",+    "comma", "hyphen", "period", "slash", "zero",+    /*  20 */+    "one", "two", "three", "four", "five",+    "six", "seven", "eight", "nine", "colon",+    /*  30 */+    "semicolon", "less", "equal", "greater", "question",+    "at", "A", "B", "C", "D",+    /*  40 */+    "E", "F", "G", "H", "I",+    "J", "K", "L", "M", "N",+    /*  50 */+    "O", "P", "Q", "R", "S",+    "T", "U", "V", "W", "X",+    /*  60 */+    "Y", "Z", "bracketleft", "backslash", "bracketright",+    "asciicircum", "underscore", "grave", "a", "b",+    /*  70 */+    "c", "d", "e", "f", "g",+    "h", "i", "j", "k", "l",+    /*  80 */+    "m", "n", "o", "p", "q",+    "r", "s", "t", "u", "v",+    /*  90 */+    "w", "x", "y", "z", "braceleft",+    "bar", "braceright", "asciitilde", "Adieresis", "Aring",+    /* 100 */+    "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",+    "aacute", "agrave", "acircumflex", "adieresis", "atilde",+    /* 110 */+    "aring", "ccedilla", "eacute", "egrave", "ecircumflex",+    "edieresis", "iacute", "igrave", "icircumflex", "idieresis",+    /* 120 */+    "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",+    "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",+    /* 130 */+    "dagger", "degree", "cent", "sterling", "section",+    "bullet", "paragraph", "germandbls", "registered", "copyright",+    /* 140 */+    "trademark", "acute", "dieresis", "notequal", "AE",+    "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",+    /* 150 */+    "yen", "mu", "partialdiff", "summation", "product",+    "pi", "integral", "ordfeminine", "ordmasculine", "Omega",+    /* 160 */+    "ae", "oslash", "questiondown", "exclamdown", "logicalnot",+    "radical", "florin", "approxequal", "Delta", "guillemotleft",+    /* 170 */+    "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",+    "Otilde", "OE", "oe", "endash", "emdash",+    /* 180 */+    "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",+    "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",+    /* 190 */+    "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",+    "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",+    /* 200 */+    "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",+    "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",+    /* 210 */+    "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",+    "dotlessi", "circumflex", "tilde", "macron", "breve",+    /* 220 */+    "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",+    "caron", "Lslash", "lslash", "Scaron", "scaron",+    /* 230 */+    "Zcaron", "zcaron", "brokenbar", "Eth", "eth",+    "Yacute", "yacute", "Thorn", "thorn", "minus",+    /* 240 */+    "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",+    "onequarter", "threequarters", "franc", "Gbreve", "gbreve",+    /* 250 */+    "Idot", "Scedilla", "scedilla", "Cacute", "cacute",+    "Ccaron", "ccaron", "dmacron",+  };+++#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */+++  static FT_Error+  load_format_20( TT_Face    face,+                  FT_Stream  stream,+                  FT_Long    post_limit )+  {+    FT_Memory   memory = stream->memory;+    FT_Error    error;++    FT_Int      num_glyphs;+    FT_UShort   num_names;++    FT_UShort*  glyph_indices = 0;+    FT_Char**   name_strings  = 0;+++    if ( FT_READ_USHORT( num_glyphs ) )+      goto Exit;++    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */+    /* than the value in the maxp table (cf. cyberbit.ttf).             */++    /* There already exist fonts which have more than 32768 glyph names */+    /* in this table, so the test for this threshold has been dropped.  */++    if ( num_glyphs > face->max_profile.numGlyphs )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    /* load the indices */+    {+      FT_Int  n;+++      if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) ||+           FT_FRAME_ENTER( num_glyphs * 2L )          )+        goto Fail;++      for ( n = 0; n < num_glyphs; n++ )+        glyph_indices[n] = FT_GET_USHORT();++      FT_FRAME_EXIT();+    }++    /* compute number of names stored in table */+    {+      FT_Int  n;+++      num_names = 0;++      for ( n = 0; n < num_glyphs; n++ )+      {+        FT_Int  idx;+++        idx = glyph_indices[n];+        if ( idx >= 258 )+        {+          idx -= 257;+          if ( idx > num_names )+            num_names = (FT_UShort)idx;+        }+      }+    }++    /* now load the name strings */+    {+      FT_UShort  n;+++      if ( FT_NEW_ARRAY( name_strings, num_names ) )+        goto Fail;++      for ( n = 0; n < num_names; n++ )+      {+        FT_UInt  len;+++        if ( FT_STREAM_POS() >= post_limit )+          break;+        else+        {+          FT_TRACE6(( "load_format_20: %d byte left in post table\n",+                      post_limit - FT_STREAM_POS() ));++          if ( FT_READ_BYTE( len ) )+            goto Fail1;+        }++        if ( (FT_Int)len > post_limit                   ||+             FT_STREAM_POS() > post_limit - (FT_Int)len )+        {+          FT_ERROR(( "load_format_20:"+                     " exceeding string length (%d),"+                     " truncating at end of post table (%d byte left)\n",+                     len, post_limit - FT_STREAM_POS() ));+          len = FT_MAX( 0, post_limit - FT_STREAM_POS() );+        }++        if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) ||+             FT_STREAM_READ( name_strings[n], len   ) )+          goto Fail1;++        name_strings[n][len] = '\0';+      }++      if ( n < num_names )+      {+        FT_ERROR(( "load_format_20:"+                   " all entries in post table are already parsed,"+                   " using NULL names for gid %d - %d\n",+                    n, num_names - 1 ));+        for ( ; n < num_names; n++ )+          if ( FT_NEW_ARRAY( name_strings[n], 1 ) )+            goto Fail1;+          else+            name_strings[n][0] = '\0';+      }+    }++    /* all right, set table fields and exit successfully */+    {+      TT_Post_20  table = &face->postscript_names.names.format_20;+++      table->num_glyphs    = (FT_UShort)num_glyphs;+      table->num_names     = (FT_UShort)num_names;+      table->glyph_indices = glyph_indices;+      table->glyph_names   = name_strings;+    }+    return SFNT_Err_Ok;++  Fail1:+    {+      FT_UShort  n;+++      for ( n = 0; n < num_names; n++ )+        FT_FREE( name_strings[n] );+    }++  Fail:+    FT_FREE( name_strings );+    FT_FREE( glyph_indices );++  Exit:+    return error;+  }+++  static FT_Error+  load_format_25( TT_Face    face,+                  FT_Stream  stream,+                  FT_Long    post_limit )+  {+    FT_Memory  memory = stream->memory;+    FT_Error   error;++    FT_Int     num_glyphs;+    FT_Char*   offset_table = 0;++    FT_UNUSED( post_limit );+++    /* UNDOCUMENTED!  This value appears only in the Apple TT specs. */+    if ( FT_READ_USHORT( num_glyphs ) )+      goto Exit;++    /* check the number of glyphs */+    if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    if ( FT_NEW_ARRAY( offset_table, num_glyphs )   ||+         FT_STREAM_READ( offset_table, num_glyphs ) )+      goto Fail;++    /* now check the offset table */+    {+      FT_Int  n;+++      for ( n = 0; n < num_glyphs; n++ )+      {+        FT_Long  idx = (FT_Long)n + offset_table[n];+++        if ( idx < 0 || idx > num_glyphs )+        {+          error = SFNT_Err_Invalid_File_Format;+          goto Fail;+        }+      }+    }++    /* OK, set table fields and exit successfully */+    {+      TT_Post_25  table = &face->postscript_names.names.format_25;+++      table->num_glyphs = (FT_UShort)num_glyphs;+      table->offsets    = offset_table;+    }++    return SFNT_Err_Ok;++  Fail:+    FT_FREE( offset_table );++  Exit:+    return error;+  }+++  static FT_Error+  load_post_names( TT_Face  face )+  {+    FT_Stream  stream;+    FT_Error   error;+    FT_Fixed   format;+    FT_ULong   post_len;+    FT_Long    post_limit;+++    /* get a stream for the face's resource */+    stream = face->root.stream;++    /* seek to the beginning of the PS names table */+    error = face->goto_table( face, TTAG_post, stream, &post_len );+    if ( error )+      goto Exit;++    post_limit = FT_STREAM_POS() + post_len;++    format = face->postscript.FormatType;++    /* go to beginning of subtable */+    if ( FT_STREAM_SKIP( 32 ) )+      goto Exit;++    /* now read postscript table */+    if ( format == 0x00020000L )+      error = load_format_20( face, stream, post_limit );+    else if ( format == 0x00028000L )+      error = load_format_25( face, stream, post_limit );+    else+      error = SFNT_Err_Invalid_File_Format;++    face->postscript_names.loaded = 1;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  tt_face_free_ps_names( TT_Face  face )+  {+    FT_Memory      memory = face->root.memory;+    TT_Post_Names  names  = &face->postscript_names;+    FT_Fixed       format;+++    if ( names->loaded )+    {+      format = face->postscript.FormatType;++      if ( format == 0x00020000L )+      {+        TT_Post_20  table = &names->names.format_20;+        FT_UShort   n;+++        FT_FREE( table->glyph_indices );+        table->num_glyphs = 0;++        for ( n = 0; n < table->num_names; n++ )+          FT_FREE( table->glyph_names[n] );++        FT_FREE( table->glyph_names );+        table->num_names = 0;+      }+      else if ( format == 0x00028000L )+      {+        TT_Post_25  table = &names->names.format_25;+++        FT_FREE( table->offsets );+        table->num_glyphs = 0;+      }+    }+    names->loaded = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_get_ps_name                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Get the PostScript glyph name of a glyph.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the parent face.                             */+  /*                                                                       */+  /*    idx    :: The glyph index.                                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */+  /*              of error, otherwise it is a pointer to the glyph name.   */+  /*                                                                       */+  /*              You must not modify the returned string!                 */+  /*                                                                       */+  /* <Output>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_get_ps_name( TT_Face      face,+                       FT_UInt      idx,+                       FT_String**  PSname )+  {+    FT_Error       error;+    TT_Post_Names  names;+    FT_Fixed       format;++#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES+    FT_Service_PsCMaps  psnames;+#endif+++    if ( !face )+      return SFNT_Err_Invalid_Face_Handle;++    if ( idx >= (FT_UInt)face->max_profile.numGlyphs )+      return SFNT_Err_Invalid_Glyph_Index;++#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES+    psnames = (FT_Service_PsCMaps)face->psnames;+    if ( !psnames )+      return SFNT_Err_Unimplemented_Feature;+#endif++    names = &face->postscript_names;++    /* `.notdef' by default */+    *PSname = MAC_NAME( 0 );++    format = face->postscript.FormatType;++    if ( format == 0x00010000L )+    {+      if ( idx < 258 )                    /* paranoid checking */+        *PSname = MAC_NAME( idx );+    }+    else if ( format == 0x00020000L )+    {+      TT_Post_20  table = &names->names.format_20;+++      if ( !names->loaded )+      {+        error = load_post_names( face );+        if ( error )+          goto End;+      }++      if ( idx < (FT_UInt)table->num_glyphs )+      {+        FT_UShort  name_index = table->glyph_indices[idx];+++        if ( name_index < 258 )+          *PSname = MAC_NAME( name_index );+        else+          *PSname = (FT_String*)table->glyph_names[name_index - 258];+      }+    }+    else if ( format == 0x00028000L )+    {+      TT_Post_25  table = &names->names.format_25;+++      if ( !names->loaded )+      {+        error = load_post_names( face );+        if ( error )+          goto End;+      }++      if ( idx < (FT_UInt)table->num_glyphs )    /* paranoid checking */+      {+        idx    += table->offsets[idx];+        *PSname = MAC_NAME( idx );+      }+    }++    /* nothing to do for format == 0x00030000L */++  End:+    return SFNT_Err_Ok;+  }+++/* END */
+ src/sfnt/ttpost.h view
@@ -0,0 +1,46 @@+/***************************************************************************/+/*                                                                         */+/*  ttpost.h                                                               */+/*                                                                         */+/*    Postcript name table processing for TrueType and OpenType fonts      */+/*    (specification).                                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTPOST_H__+#define __TTPOST_H__+++#include <ft2build.h>+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  tt_face_get_ps_name( TT_Face      face,+                       FT_UInt      idx,+                       FT_String**  PSname );++  FT_LOCAL( void )+  tt_face_free_ps_names( TT_Face  face );+++FT_END_HEADER++#endif /* __TTPOST_H__ */+++/* END */
+ src/sfnt/ttsbit.c view
@@ -0,0 +1,1508 @@+/***************************************************************************/+/*                                                                         */+/*  ttsbit.c                                                               */+/*                                                                         */+/*    TrueType and OpenType embedded bitmap support (body).                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H++  /*+   *  Alas, the memory-optimized sbit loader can't be used when implementing+   *  the `old internals' hack+   */+#ifndef FT_CONFIG_OPTION_OLD_INTERNALS++#include "ttsbit0.c"++#else /* FT_CONFIG_OPTION_OLD_INTERNALS */++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttsbit.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttsbit+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    blit_sbit                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Blits a bitmap from an input stream into a given target.  Supports */+  /*    x and y offsets as well as byte padded lines.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    target      :: The target bitmap/pixmap.                           */+  /*                                                                       */+  /*    source      :: The input packed bitmap data.                       */+  /*                                                                       */+  /*    line_bits   :: The number of bits per line.                        */+  /*                                                                       */+  /*    byte_padded :: A flag which is true if lines are byte-padded.      */+  /*                                                                       */+  /*    x_offset    :: The horizontal offset.                              */+  /*                                                                       */+  /*    y_offset    :: The vertical offset.                                */+  /*                                                                       */+  /* <Note>                                                                */+  /*    IMPORTANT: The x and y offsets are relative to the top corner of   */+  /*               the target bitmap (unlike the normal TrueType           */+  /*               convention).  A positive y offset indicates a downwards */+  /*               direction!                                              */+  /*                                                                       */+  static void+  blit_sbit( FT_Bitmap*  target,+             FT_Byte*    source,+             FT_Int      line_bits,+             FT_Bool     byte_padded,+             FT_Int      x_offset,+             FT_Int      y_offset,+             FT_Int      source_height )+  {+    FT_Byte*   line_buff;+    FT_Int     line_incr;+    FT_Int     height;++    FT_UShort  acc;+    FT_UInt    loaded;+++    /* first of all, compute starting write position */+    line_incr = target->pitch;+    line_buff = target->buffer;++    if ( line_incr < 0 )+      line_buff -= line_incr * ( target->rows - 1 );++    line_buff += ( x_offset >> 3 ) + y_offset * line_incr;++    /***********************************************************************/+    /*                                                                     */+    /* We use the extra-classic `accumulator' trick to extract the bits    */+    /* from the source byte stream.                                        */+    /*                                                                     */+    /* Namely, the variable `acc' is a 16-bit accumulator containing the   */+    /* last `loaded' bits from the input stream.  The bits are shifted to  */+    /* the upmost position in `acc'.                                       */+    /*                                                                     */+    /***********************************************************************/++    acc    = 0;  /* clear accumulator   */+    loaded = 0;  /* no bits were loaded */++    for ( height = source_height; height > 0; height-- )+    {+      FT_Byte*  cur   = line_buff;        /* current write cursor          */+      FT_Int    count = line_bits;        /* # of bits to extract per line */+      FT_Byte   shift = (FT_Byte)( x_offset & 7 ); /* current write shift  */+      FT_Byte   space = (FT_Byte)( 8 - shift );+++      /* first of all, read individual source bytes */+      if ( count >= 8 )+      {+        count -= 8;+        {+          do+          {+            FT_Byte  val;+++            /* ensure that there are at least 8 bits in the accumulator */+            if ( loaded < 8 )+            {+              acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));+              loaded += 8;+            }++            /* now write one byte */+            val = (FT_Byte)( acc >> 8 );+            if ( shift )+            {+              cur[0] |= (FT_Byte)( val >> shift );+              cur[1] |= (FT_Byte)( val << space );+            }+            else+              cur[0] |= val;++            cur++;+            acc   <<= 8;  /* remove bits from accumulator */+            loaded -= 8;+            count  -= 8;++          } while ( count >= 0 );+        }++        /* restore `count' to correct value */+        count += 8;+      }++      /* now write remaining bits (count < 8) */+      if ( count > 0 )+      {+        FT_Byte  val;+++        /* ensure that there are at least `count' bits in the accumulator */+        if ( (FT_Int)loaded < count )+        {+          acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));+          loaded += 8;+        }++        /* now write remaining bits */+        val     = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );+        cur[0] |= (FT_Byte)( val >> shift );++        if ( count > space )+          cur[1] |= (FT_Byte)( val << space );++        acc   <<= count;+        loaded -= count;+      }++      /* now, skip to next line */+      if ( byte_padded )+      {+        acc    = 0;+        loaded = 0;   /* clear accumulator on byte-padded lines */+      }++      line_buff += line_incr;+    }+  }+++  static const FT_Frame_Field  sbit_metrics_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_SBit_MetricsRec++    FT_FRAME_START( 8 ),+      FT_FRAME_BYTE( height ),+      FT_FRAME_BYTE( width ),++      FT_FRAME_CHAR( horiBearingX ),+      FT_FRAME_CHAR( horiBearingY ),+      FT_FRAME_BYTE( horiAdvance ),++      FT_FRAME_CHAR( vertBearingX ),+      FT_FRAME_CHAR( vertBearingY ),+      FT_FRAME_BYTE( vertAdvance ),+    FT_FRAME_END+  };+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Load_SBit_Const_Metrics                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range  :: The target range.                                        */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  Load_SBit_Const_Metrics( TT_SBit_Range  range,+                           FT_Stream      stream )+  {+    FT_Error  error;+++    if ( FT_READ_ULONG( range->image_size ) )+      return error;++    return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Load_SBit_Range_Codes                                              */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range        :: The target range.                                  */+  /*                                                                       */+  /*    stream       :: The input stream.                                  */+  /*                                                                       */+  /*    load_offsets :: A flag whether to load the glyph offset table.     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  Load_SBit_Range_Codes( TT_SBit_Range  range,+                         FT_Stream      stream,+                         FT_Bool        load_offsets )+  {+    FT_Error   error;+    FT_ULong   count, n, size;+    FT_Memory  memory = stream->memory;+++    if ( FT_READ_ULONG( count ) )+      goto Exit;++    range->num_glyphs = count;++    /* Allocate glyph offsets table if needed */+    if ( load_offsets )+    {+      if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )+        goto Exit;++      size = count * 4L;+    }+    else+      size = count * 2L;++    /* Allocate glyph codes table and access frame */+    if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||+         FT_FRAME_ENTER( size )                     )+      goto Exit;++    for ( n = 0; n < count; n++ )+    {+      range->glyph_codes[n] = FT_GET_USHORT();++      if ( load_offsets )+        range->glyph_offsets[n] = (FT_ULong)range->image_offset ++                                  FT_GET_USHORT();+    }++    FT_FRAME_EXIT();++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Load_SBit_Range                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads a given `EBLC' index/range table.                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range  :: The target range.                                        */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  Load_SBit_Range( TT_SBit_Range  range,+                   FT_Stream      stream )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;+++    switch( range->index_format )+    {+    case 1:   /* variable metrics with 4-byte offsets */+    case 3:   /* variable metrics with 2-byte offsets */+      {+        FT_ULong  num_glyphs, n;+        FT_Int    size_elem;+        FT_Bool   large = FT_BOOL( range->index_format == 1 );++++        if ( range->last_glyph < range->first_glyph )+        {+          error = SFNT_Err_Invalid_File_Format;+          goto Exit;+        }++        num_glyphs        = range->last_glyph - range->first_glyph + 1L;+        range->num_glyphs = num_glyphs;+        num_glyphs++;                       /* XXX: BEWARE - see spec */++        size_elem = large ? 4 : 2;++        if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||+             FT_FRAME_ENTER( num_glyphs * size_elem )         )+          goto Exit;++        for ( n = 0; n < num_glyphs; n++ )+          range->glyph_offsets[n] = (FT_ULong)( range->image_offset ++                                                ( large ? FT_GET_ULONG()+                                                        : FT_GET_USHORT() ) );+        FT_FRAME_EXIT();+      }+      break;++    case 2:   /* all glyphs have identical metrics */+      error = Load_SBit_Const_Metrics( range, stream );+      break;++    case 4:+      error = Load_SBit_Range_Codes( range, stream, 1 );+      break;++    case 5:+      error = Load_SBit_Const_Metrics( range, stream );+      if ( !error )+        error = Load_SBit_Range_Codes( range, stream, 0 );+      break;++    default:+      error = SFNT_Err_Invalid_File_Format;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_eblc                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads the table of embedded bitmap sizes for this face.            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: The target face object.                                  */+  /*                                                                       */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_eblc( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error   error  = SFNT_Err_Ok;+    FT_Memory  memory = stream->memory;+    FT_Fixed   version;+    FT_ULong   num_strikes;+    FT_ULong   table_base;++    static const FT_Frame_Field  sbit_line_metrics_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_SBit_LineMetricsRec++      /* no FT_FRAME_START */+        FT_FRAME_CHAR( ascender ),+        FT_FRAME_CHAR( descender ),+        FT_FRAME_BYTE( max_width ),++        FT_FRAME_CHAR( caret_slope_numerator ),+        FT_FRAME_CHAR( caret_slope_denominator ),+        FT_FRAME_CHAR( caret_offset ),++        FT_FRAME_CHAR( min_origin_SB ),+        FT_FRAME_CHAR( min_advance_SB ),+        FT_FRAME_CHAR( max_before_BL ),+        FT_FRAME_CHAR( min_after_BL ),+        FT_FRAME_CHAR( pads[0] ),+        FT_FRAME_CHAR( pads[1] ),+      FT_FRAME_END+    };++    static const FT_Frame_Field  strike_start_fields[] =+    {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_SBit_StrikeRec++      /* no FT_FRAME_START */+        FT_FRAME_ULONG( ranges_offset ),+        FT_FRAME_SKIP_LONG,+        FT_FRAME_ULONG( num_ranges ),+        FT_FRAME_ULONG( color_ref ),+      FT_FRAME_END+    };++    static const FT_Frame_Field  strike_end_fields[] =+    {+      /* no FT_FRAME_START */+        FT_FRAME_USHORT( start_glyph ),+        FT_FRAME_USHORT( end_glyph ),+        FT_FRAME_BYTE  ( x_ppem ),+        FT_FRAME_BYTE  ( y_ppem ),+        FT_FRAME_BYTE  ( bit_depth ),+        FT_FRAME_CHAR  ( flags ),+      FT_FRAME_END+    };+++    face->num_sbit_strikes = 0;++    /* this table is optional */+    error = face->goto_table( face, TTAG_EBLC, stream, 0 );+    if ( error )+      error = face->goto_table( face, TTAG_bloc, stream, 0 );+    if ( error )+      goto Exit;++    table_base = FT_STREAM_POS();+    if ( FT_FRAME_ENTER( 8L ) )+      goto Exit;++    version     = FT_GET_LONG();+    num_strikes = FT_GET_ULONG();++    FT_FRAME_EXIT();++    /* check version number and strike count */+    if ( version     != 0x00020000L ||+         num_strikes >= 0x10000L    )+    {+      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));+      error = SFNT_Err_Invalid_File_Format;++      goto Exit;+    }++    /* allocate the strikes table */+    if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )+      goto Exit;++    face->num_sbit_strikes = num_strikes;++    /* now read each strike table separately */+    {+      TT_SBit_Strike  strike = face->sbit_strikes;+      FT_ULong        count  = num_strikes;+++      if ( FT_FRAME_ENTER( 48L * num_strikes ) )+        goto Exit;++      while ( count > 0 )+      {+        if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike )             ||+             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||+             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||+             FT_STREAM_READ_FIELDS( strike_end_fields, strike )               )+          break;++        count--;+        strike++;+      }++      FT_FRAME_EXIT();+    }++    /* allocate the index ranges for each strike table */+    {+      TT_SBit_Strike  strike = face->sbit_strikes;+      FT_ULong        count  = num_strikes;+++      while ( count > 0 )+      {+        TT_SBit_Range  range;+        FT_ULong       count2 = strike->num_ranges;+++        /* read each range */+        if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||+             FT_FRAME_ENTER( strike->num_ranges * 8L )            )+          goto Exit;++        if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )+          goto Exit;++        range = strike->sbit_ranges;+        while ( count2 > 0 )+        {+          range->first_glyph  = FT_GET_USHORT();+          range->last_glyph   = FT_GET_USHORT();+          range->table_offset = table_base + strike->ranges_offset ++                                  FT_GET_ULONG();+          count2--;+          range++;+        }++        FT_FRAME_EXIT();++        /* Now, read each index table */+        count2 = strike->num_ranges;+        range  = strike->sbit_ranges;+        while ( count2 > 0 )+        {+          /* Read the header */+          if ( FT_STREAM_SEEK( range->table_offset ) ||+               FT_FRAME_ENTER( 8L )                  )+            goto Exit;++          range->index_format = FT_GET_USHORT();+          range->image_format = FT_GET_USHORT();+          range->image_offset = FT_GET_ULONG();++          FT_FRAME_EXIT();++          error = Load_SBit_Range( range, stream );+          if ( error )+            goto Exit;++          count2--;+          range++;+        }++        count--;+        strike++;+      }+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_free_eblc                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Releases the embedded bitmap tables.                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: The target face object.                                    */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_face_free_eblc( TT_Face  face )+  {+    FT_Memory       memory       = face->root.memory;+    TT_SBit_Strike  strike       = face->sbit_strikes;+    TT_SBit_Strike  strike_limit = strike + face->num_sbit_strikes;+++    if ( strike )+    {+      for ( ; strike < strike_limit; strike++ )+      {+        TT_SBit_Range  range       = strike->sbit_ranges;+        TT_SBit_Range  range_limit = range + strike->num_ranges;+++        if ( range )+        {+          for ( ; range < range_limit; range++ )+          {+            /* release the glyph offsets and codes tables */+            /* where appropriate                          */+            FT_FREE( range->glyph_offsets );+            FT_FREE( range->glyph_codes );+          }+        }+        FT_FREE( strike->sbit_ranges );+        strike->num_ranges = 0;+      }+      FT_FREE( face->sbit_strikes );+    }+    face->num_sbit_strikes = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_set_sbit_strike( TT_Face          face,+                           FT_Size_Request  req,+                           FT_ULong*        astrike_index )+  {+    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_strike_metrics( TT_Face           face,+                               FT_ULong          strike_index,+                               FT_Size_Metrics*  metrics )+  {+    TT_SBit_Strike  strike;+++    if ( strike_index >= face->num_sbit_strikes )+      return SFNT_Err_Invalid_Argument;++    strike = face->sbit_strikes + strike_index;++    metrics->x_ppem = strike->x_ppem;+    metrics->y_ppem = strike->y_ppem;++    metrics->ascender  = strike->hori.ascender << 6;+    metrics->descender = strike->hori.descender << 6;++    /* XXX: Is this correct? */+    metrics->max_advance = ( strike->hori.min_origin_SB  ++                             strike->hori.max_width      ++                             strike->hori.min_advance_SB ) << 6;++    metrics->height = metrics->ascender - metrics->descender;++    return SFNT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    find_sbit_range                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Scans a given strike's ranges and return, for a given glyph        */+  /*    index, the corresponding sbit range, and `EBDT' offset.            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    glyph_index   :: The glyph index.                                  */+  /*                                                                       */+  /*    strike        :: The source/current sbit strike.                   */+  /*                                                                       */+  /* <Output>                                                              */+  /*    arange        :: The sbit range containing the glyph index.        */+  /*                                                                       */+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means the glyph index was found.           */+  /*                                                                       */+  static FT_Error+  find_sbit_range( FT_UInt          glyph_index,+                   TT_SBit_Strike   strike,+                   TT_SBit_Range   *arange,+                   FT_ULong        *aglyph_offset )+  {+    TT_SBit_RangeRec  *range, *range_limit;+++    /* check whether the glyph index is within this strike's */+    /* glyph range                                           */+    if ( glyph_index < (FT_UInt)strike->start_glyph ||+         glyph_index > (FT_UInt)strike->end_glyph   )+      goto Fail;++    /* scan all ranges in strike */+    range       = strike->sbit_ranges;+    range_limit = range + strike->num_ranges;+    if ( !range )+      goto Fail;++    for ( ; range < range_limit; range++ )+    {+      if ( glyph_index >= (FT_UInt)range->first_glyph &&+           glyph_index <= (FT_UInt)range->last_glyph  )+      {+        FT_UShort  delta = (FT_UShort)( glyph_index - range->first_glyph );+++        switch ( range->index_format )+        {+        case 1:+        case 3:+          *aglyph_offset = range->glyph_offsets[delta];+          break;++        case 2:+          *aglyph_offset = range->image_offset ++                           range->image_size * delta;+          break;++        case 4:+        case 5:+          {+            FT_ULong  n;+++            for ( n = 0; n < range->num_glyphs; n++ )+            {+              if ( (FT_UInt)range->glyph_codes[n] == glyph_index )+              {+                if ( range->index_format == 4 )+                  *aglyph_offset = range->glyph_offsets[n];+                else+                  *aglyph_offset = range->image_offset ++                                   n * range->image_size;+                goto Found;+              }+            }+          }++        /* fall-through */+        default:+          goto Fail;+        }++      Found:+        /* return successfully! */+        *arange  = range;+        return SFNT_Err_Ok;+      }+    }++  Fail:+    *arange        = 0;+    *aglyph_offset = 0;++    return SFNT_Err_Invalid_Argument;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_find_sbit_image                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */+  /*    glyph, at a given strike.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face          :: The target face object.                           */+  /*                                                                       */+  /*    glyph_index   :: The glyph index.                                  */+  /*                                                                       */+  /*    strike_index  :: The current strike index.                         */+  /*                                                                       */+  /* <Output>                                                              */+  /*    arange        :: The SBit range containing the glyph index.        */+  /*                                                                       */+  /*    astrike       :: The SBit strike containing the glyph index.       */+  /*                                                                       */+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns                    */+  /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */+  /*    glyph.                                                             */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_find_sbit_image( TT_Face          face,+                      FT_UInt          glyph_index,+                      FT_ULong         strike_index,+                      TT_SBit_Range   *arange,+                      TT_SBit_Strike  *astrike,+                      FT_ULong        *aglyph_offset )+  {+    FT_Error        error;+    TT_SBit_Strike  strike;+++    if ( !face->sbit_strikes                        ||+         ( face->num_sbit_strikes <= strike_index ) )+      goto Fail;++    strike = &face->sbit_strikes[strike_index];++    error = find_sbit_range( glyph_index, strike,+                             arange, aglyph_offset );+    if ( error )+      goto Fail;++    *astrike = strike;++    return SFNT_Err_Ok;++  Fail:+    /* no embedded bitmap for this glyph in face */+    *arange        = 0;+    *astrike       = 0;+    *aglyph_offset = 0;++    return SFNT_Err_Invalid_Argument;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_load_sbit_metrics                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Gets the big metrics for a given SBit.                             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream      :: The input stream.                                   */+  /*                                                                       */+  /*    range       :: The SBit range containing the glyph.                */+  /*                                                                       */+  /* <Output>                                                              */+  /*    big_metrics :: A big SBit metrics structure for the glyph.         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The stream cursor must be positioned at the glyph's offset within  */+  /*    the `EBDT' table before the call.                                  */+  /*                                                                       */+  /*    If the image format uses variable metrics, the stream cursor is    */+  /*    positioned just after the metrics header in the `EBDT' table on    */+  /*    function exit.                                                     */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_load_sbit_metrics( FT_Stream        stream,+                        TT_SBit_Range    range,+                        TT_SBit_Metrics  metrics )+  {+    FT_Error  error = SFNT_Err_Ok;+++    switch ( range->image_format )+    {+    case 1:+    case 2:+    case 8:+      /* variable small metrics */+      {+        TT_SBit_SmallMetricsRec  smetrics;++        static const FT_Frame_Field  sbit_small_metrics_fields[] =+        {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  TT_SBit_SmallMetricsRec++          FT_FRAME_START( 5 ),+            FT_FRAME_BYTE( height ),+            FT_FRAME_BYTE( width ),+            FT_FRAME_CHAR( bearingX ),+            FT_FRAME_CHAR( bearingY ),+            FT_FRAME_BYTE( advance ),+          FT_FRAME_END+        };+++        /* read small metrics */+        if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )+          goto Exit;++        /* convert it to a big metrics */+        metrics->height       = smetrics.height;+        metrics->width        = smetrics.width;+        metrics->horiBearingX = smetrics.bearingX;+        metrics->horiBearingY = smetrics.bearingY;+        metrics->horiAdvance  = smetrics.advance;++        /* these metrics are made up at a higher level when */+        /* needed.                                          */+        metrics->vertBearingX = 0;+        metrics->vertBearingY = 0;+        metrics->vertAdvance  = 0;+      }+      break;++    case 6:+    case 7:+    case 9:+      /* variable big metrics */+      if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )+        goto Exit;+      break;++    case 5:+    default:  /* constant metrics */+      if ( range->index_format == 2 || range->index_format == 5 )+        *metrics = range->metrics;+      else+        return SFNT_Err_Invalid_File_Format;+   }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    crop_bitmap                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Crops a bitmap to its tightest bounding box, and adjusts its       */+  /*    metrics.                                                           */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    map     :: The bitmap.                                             */+  /*                                                                       */+  /*    metrics :: The corresponding metrics structure.                    */+  /*                                                                       */+  static void+  crop_bitmap( FT_Bitmap*       map,+               TT_SBit_Metrics  metrics )+  {+    /***********************************************************************/+    /*                                                                     */+    /* In this situation, some bounding boxes of embedded bitmaps are too  */+    /* large.  We need to crop it to a reasonable size.                    */+    /*                                                                     */+    /*      ---------                                                      */+    /*      |       |                -----                                 */+    /*      |  ***  |                |***|                                 */+    /*      |   *   |                | * |                                 */+    /*      |   *   |    ------>     | * |                                 */+    /*      |   *   |                | * |                                 */+    /*      |   *   |                | * |                                 */+    /*      |  ***  |                |***|                                 */+    /*      ---------                -----                                 */+    /*                                                                     */+    /***********************************************************************/++    FT_Int    rows, count;+    FT_Long   line_len;+    FT_Byte*  line;+++    /***********************************************************************/+    /*                                                                     */+    /* first of all, check the top-most lines of the bitmap, and remove    */+    /* them if they're empty.                                              */+    /*                                                                     */+    {+      line     = (FT_Byte*)map->buffer;+      rows     = map->rows;+      line_len = map->pitch;+++      for ( count = 0; count < rows; count++ )+      {+        FT_Byte*  cur   = line;+        FT_Byte*  limit = line + line_len;+++        for ( ; cur < limit; cur++ )+          if ( cur[0] )+            goto Found_Top;++        /* the current line was empty - skip to next one */+        line  = limit;+      }++    Found_Top:+      /* check that we have at least one filled line */+      if ( count >= rows )+        goto Empty_Bitmap;++      /* now, crop the empty upper lines */+      if ( count > 0 )+      {+        line = (FT_Byte*)map->buffer;++        FT_MEM_MOVE( line, line + count * line_len,+                     ( rows - count ) * line_len );++        metrics->height       = (FT_Byte)( metrics->height - count );+        metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );+        metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );++        map->rows -= count;+        rows      -= count;+      }+    }++    /***********************************************************************/+    /*                                                                     */+    /* second, crop the lower lines                                        */+    /*                                                                     */+    {+      line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;++      for ( count = 0; count < rows; count++ )+      {+        FT_Byte*  cur   = line;+        FT_Byte*  limit = line + line_len;+++        for ( ; cur < limit; cur++ )+          if ( cur[0] )+            goto Found_Bottom;++        /* the current line was empty - skip to previous one */+        line -= line_len;+      }++    Found_Bottom:+      if ( count > 0 )+      {+        metrics->height  = (FT_Byte)( metrics->height - count );+        rows            -= count;+        map->rows       -= count;+      }+    }++    /***********************************************************************/+    /*                                                                     */+    /* third, get rid of the space on the left side of the glyph           */+    /*                                                                     */+    do+    {+      FT_Byte*  limit;+++      line  = (FT_Byte*)map->buffer;+      limit = line + rows * line_len;++      for ( ; line < limit; line += line_len )+        if ( line[0] & 0x80 )+          goto Found_Left;++      /* shift the whole glyph one pixel to the left */+      line  = (FT_Byte*)map->buffer;+      limit = line + rows * line_len;++      for ( ; line < limit; line += line_len )+      {+        FT_Int    n, width = map->width;+        FT_Byte   old;+        FT_Byte*  cur = line;+++        old = (FT_Byte)(cur[0] << 1);+        for ( n = 8; n < width; n += 8 )+        {+          FT_Byte  val;+++          val    = cur[1];+          cur[0] = (FT_Byte)( old | ( val >> 7 ) );+          old    = (FT_Byte)( val << 1 );+          cur++;+        }+        cur[0] = old;+      }++      map->width--;+      metrics->horiBearingX++;+      metrics->vertBearingX++;+      metrics->width--;++    } while ( map->width > 0 );++  Found_Left:++    /***********************************************************************/+    /*                                                                     */+    /* finally, crop the bitmap width to get rid of the space on the right */+    /* side of the glyph.                                                  */+    /*                                                                     */+    do+    {+      FT_Int    right = map->width - 1;+      FT_Byte*  limit;+      FT_Byte   mask;+++      line  = (FT_Byte*)map->buffer + ( right >> 3 );+      limit = line + rows * line_len;+      mask  = (FT_Byte)( 0x80 >> ( right & 7 ) );++      for ( ; line < limit; line += line_len )+        if ( line[0] & mask )+          goto Found_Right;++      /* crop the whole glyph to the right */+      map->width--;+      metrics->width--;++    } while ( map->width > 0 );++  Found_Right:+    /* all right, the bitmap was cropped */+    return;++  Empty_Bitmap:+    map->width      = 0;+    map->rows       = 0;+    map->pitch      = 0;+    map->pixel_mode = FT_PIXEL_MODE_MONO;+  }+++  static FT_Error+  Load_SBit_Single( FT_Bitmap*       map,+                    FT_Int           x_offset,+                    FT_Int           y_offset,+                    FT_Int           pix_bits,+                    FT_UShort        image_format,+                    TT_SBit_Metrics  metrics,+                    FT_Stream        stream )+  {+    FT_Error  error;+++    /* check that the source bitmap fits into the target pixmap */+    if ( x_offset < 0 || x_offset + metrics->width  > map->width ||+         y_offset < 0 || y_offset + metrics->height > map->rows  )+    {+      error = SFNT_Err_Invalid_Argument;++      goto Exit;+    }++    {+      FT_Int   glyph_width  = metrics->width;+      FT_Int   glyph_height = metrics->height;+      FT_Int   glyph_size;+      FT_Int   line_bits    = pix_bits * glyph_width;+      FT_Bool  pad_bytes    = 0;+++      /* compute size of glyph image */+      switch ( image_format )+      {+      case 1:  /* byte-padded formats */+      case 6:+        {+          FT_Int  line_length;+++          switch ( pix_bits )+          {+          case 1:+            line_length = ( glyph_width + 7 ) >> 3;+            break;+          case 2:+            line_length = ( glyph_width + 3 ) >> 2;+            break;+          case 4:+            line_length = ( glyph_width + 1 ) >> 1;+            break;+          default:+            line_length =   glyph_width;+          }++          glyph_size = glyph_height * line_length;+          pad_bytes  = 1;+        }+        break;++      case 2:+      case 5:+      case 7:+        line_bits  =   glyph_width  * pix_bits;+        glyph_size = ( glyph_height * line_bits + 7 ) >> 3;+        break;++      default:  /* invalid format */+        return SFNT_Err_Invalid_File_Format;+      }++      /* Now read data and draw glyph into target pixmap       */+      if ( FT_FRAME_ENTER( glyph_size ) )+        goto Exit;++      /* don't forget to multiply `x_offset' by `map->pix_bits' as */+      /* the sbit blitter doesn't make a difference between pixmap */+      /* depths.                                                   */+      blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,+                 x_offset * pix_bits, y_offset, metrics->height );++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }+++  static FT_Error+  Load_SBit_Image( TT_SBit_Strike   strike,+                   TT_SBit_Range    range,+                   FT_ULong         ebdt_pos,+                   FT_ULong         glyph_offset,+                   FT_GlyphSlot     slot,+                   FT_Int           x_offset,+                   FT_Int           y_offset,+                   FT_Stream        stream,+                   TT_SBit_Metrics  metrics,+                   FT_Int           depth )+  {+    FT_Memory   memory = stream->memory;+    FT_Bitmap*  map    = &slot->bitmap;+    FT_Error    error;+++    /* place stream at beginning of glyph data and read metrics */+    if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )+      goto Exit;++    error = tt_load_sbit_metrics( stream, range, metrics );+    if ( error )+      goto Exit;++    /* This function is recursive.  At the top-level call, we  */+    /* compute the dimensions of the higher-level glyph to     */+    /* allocate the final pixmap buffer.                       */+    if ( depth == 0 )+    {+      FT_Long  size;+++      map->width = metrics->width;+      map->rows  = metrics->height;++      switch ( strike->bit_depth )+      {+      case 1:+        map->pixel_mode = FT_PIXEL_MODE_MONO;+        map->pitch      = ( map->width + 7 ) >> 3;+        break;++      case 2:+        map->pixel_mode = FT_PIXEL_MODE_GRAY2;+        map->pitch      = ( map->width + 3 ) >> 2;+        break;++      case 4:+        map->pixel_mode = FT_PIXEL_MODE_GRAY4;+        map->pitch      = ( map->width + 1 ) >> 1;+        break;++      case 8:+        map->pixel_mode = FT_PIXEL_MODE_GRAY;+        map->pitch      = map->width;+        break;++      default:+        return SFNT_Err_Invalid_File_Format;+      }++      size = map->rows * map->pitch;++      /* check that there is no empty image */+      if ( size == 0 )+        goto Exit;     /* exit successfully! */++      error = ft_glyphslot_alloc_bitmap( slot, size );+      if (error)+        goto Exit;+    }++    switch ( range->image_format )+    {+    case 1:  /* single sbit image - load it */+    case 2:+    case 5:+    case 6:+    case 7:+      return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,+                               range->image_format, metrics, stream );++    case 8:  /* compound format */+      if ( FT_STREAM_SKIP( 1L ) )+      {+        error = SFNT_Err_Invalid_Stream_Skip;+        goto Exit;+      }+      /* fallthrough */++    case 9:+      break;++    default: /* invalid image format */+      return SFNT_Err_Invalid_File_Format;+    }++    /* All right, we have a compound format.  First of all, read */+    /* the array of elements.                                    */+    {+      TT_SBit_Component  components;+      TT_SBit_Component  comp;+      FT_UShort          num_components, count;+++      if ( FT_READ_USHORT( num_components )           ||+           FT_NEW_ARRAY( components, num_components ) )+        goto Exit;++      count = num_components;++      if ( FT_FRAME_ENTER( 4L * num_components ) )+        goto Fail_Memory;++      for ( comp = components; count > 0; count--, comp++ )+      {+        comp->glyph_code = FT_GET_USHORT();+        comp->x_offset   = FT_GET_CHAR();+        comp->y_offset   = FT_GET_CHAR();+      }++      FT_FRAME_EXIT();++      /* Now recursively load each element glyph */+      count = num_components;+      comp  = components;+      for ( ; count > 0; count--, comp++ )+      {+        TT_SBit_Range       elem_range;+        TT_SBit_MetricsRec  elem_metrics;+        FT_ULong            elem_offset;+++        /* find the range for this element */+        error = find_sbit_range( comp->glyph_code,+                                 strike,+                                 &elem_range,+                                 &elem_offset );+        if ( error )+          goto Fail_Memory;++        /* now load the element, recursively */+        error = Load_SBit_Image( strike,+                                 elem_range,+                                 ebdt_pos,+                                 elem_offset,+                                 slot,+                                 x_offset + comp->x_offset,+                                 y_offset + comp->y_offset,+                                 stream,+                                 &elem_metrics,+                                 depth + 1 );+        if ( error )+          goto Fail_Memory;+      }++    Fail_Memory:+      FT_FREE( components );+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_sbit_image                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads a given glyph sbit image from the font resource.  This also  */+  /*    returns its metrics.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face         :: The target face object.                            */+  /*                                                                       */+  /*    strike_index :: The current strike index.                          */+  /*                                                                       */+  /*    glyph_index  :: The current glyph index.                           */+  /*                                                                       */+  /*    load_flags   :: The glyph load flags (the code checks for the flag */+  /*                    FT_LOAD_CROP_BITMAP).                              */+  /*                                                                       */+  /*    stream       :: The input stream.                                  */+  /*                                                                       */+  /* <Output>                                                              */+  /*    map          :: The target pixmap.                                 */+  /*                                                                       */+  /*    metrics      :: A big sbit metrics structure for the glyph image.  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.  Returns an error if no     */+  /*    glyph sbit exists for the index.                                   */+  /*                                                                       */+  /*  <Note>                                                               */+  /*    The `map.buffer' field is always freed before the glyph is loaded. */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_sbit_image( TT_Face              face,+                           FT_ULong             strike_index,+                           FT_UInt              glyph_index,+                           FT_UInt              load_flags,+                           FT_Stream            stream,+                           FT_Bitmap           *map,+                           TT_SBit_MetricsRec  *metrics )+  {+    FT_Error        error;+    FT_ULong        ebdt_pos, glyph_offset;++    TT_SBit_Strike  strike;+    TT_SBit_Range   range;+++    /* Check whether there is a glyph sbit for the current index */+    error = tt_find_sbit_image( face, glyph_index, strike_index,+                                &range, &strike, &glyph_offset );+    if ( error )+      goto Exit;++    /* now, find the location of the `EBDT' table in */+    /* the font file                                 */+    error = face->goto_table( face, TTAG_EBDT, stream, 0 );+    if ( error )+      error = face->goto_table( face, TTAG_bdat, stream, 0 );+    if ( error )+      goto Exit;++    ebdt_pos = FT_STREAM_POS();++    error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,+                             face->root.glyph, 0, 0, stream, metrics, 0 );+    if ( error )+      goto Exit;++    /* setup vertical metrics if needed */+    if ( strike->flags & 1 )+    {+      /* in case of a horizontal strike only */+      FT_Int  advance;+++      advance = strike->hori.ascender - strike->hori.descender;++      /* some heuristic values */++      metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );+      metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );+      metrics->vertAdvance  = (FT_Char)( advance * 12 / 10 );+    }++    /* Crop the bitmap now, unless specified otherwise */+    if ( load_flags & FT_LOAD_CROP_BITMAP )+      crop_bitmap( map, metrics );++  Exit:+    return error;+  }++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */+++/* END */
+ src/sfnt/ttsbit.h view
@@ -0,0 +1,79 @@+/***************************************************************************/+/*                                                                         */+/*  ttsbit.h                                                               */+/*                                                                         */+/*    TrueType and OpenType embedded bitmap support (specification).       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTSBIT_H__+#define __TTSBIT_H__+++#include <ft2build.h>+#include "ttload.h"+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  tt_face_load_eblc( TT_Face    face,+                     FT_Stream  stream );++  FT_LOCAL( void )+  tt_face_free_eblc( TT_Face  face );+++  FT_LOCAL( FT_Error )+  tt_face_set_sbit_strike( TT_Face          face,+                           FT_Size_Request  req,+                           FT_ULong*        astrike_index );++  FT_LOCAL( FT_Error )+  tt_face_load_strike_metrics( TT_Face           face,+                               FT_ULong          strike_index,+                               FT_Size_Metrics*  metrics );++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+  FT_LOCAL( FT_Error )+  tt_find_sbit_image( TT_Face          face,+                      FT_UInt          glyph_index,+                      FT_ULong         strike_index,+                      TT_SBit_Range   *arange,+                      TT_SBit_Strike  *astrike,+                      FT_ULong        *aglyph_offset );++  FT_LOCAL( FT_Error )+  tt_load_sbit_metrics( FT_Stream        stream,+                        TT_SBit_Range    range,+                        TT_SBit_Metrics  metrics );++#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */++  FT_LOCAL( FT_Error )+  tt_face_load_sbit_image( TT_Face              face,+                           FT_ULong             strike_index,+                           FT_UInt              glyph_index,+                           FT_UInt              load_flags,+                           FT_Stream            stream,+                           FT_Bitmap           *map,+                           TT_SBit_MetricsRec  *metrics );+++FT_END_HEADER++#endif /* __TTSBIT_H__ */+++/* END */
+ src/sfnt/ttsbit0.c view
@@ -0,0 +1,1011 @@+/***************************************************************************/+/*                                                                         */+/*  ttsbit0.c                                                              */+/*                                                                         */+/*    TrueType and OpenType embedded bitmap support (body).                */+/*    This is a heap-optimized version.                                    */+/*                                                                         */+/*  Copyright 2005, 2006, 2007, 2008, 2009 by                              */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++/* This file is included by ttsbit.c */+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include "ttsbit.h"++#include "sferrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttsbit+++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_eblc( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error  error = SFNT_Err_Ok;+    FT_Fixed  version;+    FT_ULong  num_strikes, table_size;+    FT_Byte*  p;+    FT_Byte*  p_limit;+    FT_UInt   count;+++    face->sbit_num_strikes = 0;++    /* this table is optional */+    error = face->goto_table( face, TTAG_EBLC, stream, &table_size );+    if ( error )+      error = face->goto_table( face, TTAG_bloc, stream, &table_size );+    if ( error )+      goto Exit;++    if ( table_size < 8 )+    {+      FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )+      goto Exit;++    face->sbit_table_size = table_size;++    p       = face->sbit_table;+    p_limit = p + table_size;++    version     = FT_NEXT_ULONG( p );+    num_strikes = FT_NEXT_ULONG( p );++    if ( version != 0x00020000UL || num_strikes >= 0x10000UL )+    {+      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));+      error = SFNT_Err_Invalid_File_Format;+      goto Fail;+    }++    /*+     *  Count the number of strikes available in the table.  We are a bit+     *  paranoid there and don't trust the data.+     */+    count = (FT_UInt)num_strikes;+    if ( 8 + 48UL * count > table_size )+      count = (FT_UInt)( ( p_limit - p ) / 48 );++    face->sbit_num_strikes = count;++    FT_TRACE3(( "sbit_num_strikes: %u\n", count ));+  Exit:+    return error;++  Fail:+    FT_FRAME_RELEASE( face->sbit_table );+    face->sbit_table_size = 0;+    goto Exit;+  }+++  FT_LOCAL_DEF( void )+  tt_face_free_eblc( TT_Face  face )+  {+    FT_Stream  stream = face->root.stream;+++    FT_FRAME_RELEASE( face->sbit_table );+    face->sbit_table_size  = 0;+    face->sbit_num_strikes = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_set_sbit_strike( TT_Face          face,+                           FT_Size_Request  req,+                           FT_ULong*        astrike_index )+  {+    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_strike_metrics( TT_Face           face,+                               FT_ULong          strike_index,+                               FT_Size_Metrics*  metrics )+  {+    FT_Byte*  strike;+++    if ( strike_index >= (FT_ULong)face->sbit_num_strikes )+      return SFNT_Err_Invalid_Argument;++    strike = face->sbit_table + 8 + strike_index * 48;++    metrics->x_ppem = (FT_UShort)strike[44];+    metrics->y_ppem = (FT_UShort)strike[45];++    metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */+    metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */+    metrics->height    = metrics->ascender - metrics->descender;++    /* XXX: Is this correct? */+    metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */+                                      strike[18] + /* max_width      */+                             (FT_Char)strike[23]   /* min_advance_SB */+                                                 ) << 6;++    return SFNT_Err_Ok;+  }+++  typedef struct  TT_SBitDecoderRec_+  {+    TT_Face          face;+    FT_Stream        stream;+    FT_Bitmap*       bitmap;+    TT_SBit_Metrics  metrics;+    FT_Bool          metrics_loaded;+    FT_Bool          bitmap_allocated;+    FT_Byte          bit_depth;++    FT_ULong         ebdt_start;+    FT_ULong         ebdt_size;++    FT_ULong         strike_index_array;+    FT_ULong         strike_index_count;+    FT_Byte*         eblc_base;+    FT_Byte*         eblc_limit;++  } TT_SBitDecoderRec, *TT_SBitDecoder;+++  static FT_Error+  tt_sbit_decoder_init( TT_SBitDecoder       decoder,+                        TT_Face              face,+                        FT_ULong             strike_index,+                        TT_SBit_MetricsRec*  metrics )+  {+    FT_Error   error;+    FT_Stream  stream = face->root.stream;+    FT_ULong   ebdt_size;+++    error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );+    if ( error )+      error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );+    if ( error )+      goto Exit;++    decoder->face    = face;+    decoder->stream  = stream;+    decoder->bitmap  = &face->root.glyph->bitmap;+    decoder->metrics = metrics;++    decoder->metrics_loaded   = 0;+    decoder->bitmap_allocated = 0;++    decoder->ebdt_start = FT_STREAM_POS();+    decoder->ebdt_size  = ebdt_size;++    decoder->eblc_base  = face->sbit_table;+    decoder->eblc_limit = face->sbit_table + face->sbit_table_size;++    /* now find the strike corresponding to the index */+    {+      FT_Byte*  p;+++      if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )+      {+        error = SFNT_Err_Invalid_File_Format;+        goto Exit;+      }++      p = decoder->eblc_base + 8 + 48 * strike_index;++      decoder->strike_index_array = FT_NEXT_ULONG( p );+      p                          += 4;+      decoder->strike_index_count = FT_NEXT_ULONG( p );+      p                          += 34;+      decoder->bit_depth          = *p;++      if ( decoder->strike_index_array > face->sbit_table_size             ||+           decoder->strike_index_array + 8 * decoder->strike_index_count >+             face->sbit_table_size                                         )+        error = SFNT_Err_Invalid_File_Format;+    }++  Exit:+    return error;+  }+++  static void+  tt_sbit_decoder_done( TT_SBitDecoder  decoder )+  {+    FT_UNUSED( decoder );+  }+++  static FT_Error+  tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )+  {+    FT_Error    error = SFNT_Err_Ok;+    FT_UInt     width, height;+    FT_Bitmap*  map = decoder->bitmap;+    FT_Long     size;+++    if ( !decoder->metrics_loaded )+    {+      error = SFNT_Err_Invalid_Argument;+      goto Exit;+    }++    width  = decoder->metrics->width;+    height = decoder->metrics->height;++    map->width = (int)width;+    map->rows  = (int)height;++    switch ( decoder->bit_depth )+    {+    case 1:+      map->pixel_mode = FT_PIXEL_MODE_MONO;+      map->pitch      = ( map->width + 7 ) >> 3;+      break;++    case 2:+      map->pixel_mode = FT_PIXEL_MODE_GRAY2;+      map->pitch      = ( map->width + 3 ) >> 2;+      break;++    case 4:+      map->pixel_mode = FT_PIXEL_MODE_GRAY4;+      map->pitch      = ( map->width + 1 ) >> 1;+      break;++    case 8:+      map->pixel_mode = FT_PIXEL_MODE_GRAY;+      map->pitch      = map->width;+      break;++    default:+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    size = map->rows * map->pitch;++    /* check that there is no empty image */+    if ( size == 0 )+      goto Exit;     /* exit successfully! */++    error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );+    if ( error )+      goto Exit;++    decoder->bitmap_allocated = 1;++  Exit:+    return error;+  }+++  static FT_Error+  tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,+                                FT_Byte*       *pp,+                                FT_Byte*        limit,+                                FT_Bool         big )+  {+    FT_Byte*         p       = *pp;+    TT_SBit_Metrics  metrics = decoder->metrics;+++    if ( p + 5 > limit )+      goto Fail;++    metrics->height       = p[0];+    metrics->width        = p[1];+    metrics->horiBearingX = (FT_Char)p[2];+    metrics->horiBearingY = (FT_Char)p[3];+    metrics->horiAdvance  = p[4];++    p += 5;+    if ( big )+    {+      if ( p + 3 > limit )+        goto Fail;++      metrics->vertBearingX = (FT_Char)p[0];+      metrics->vertBearingY = (FT_Char)p[1];+      metrics->vertAdvance  = p[2];++      p += 3;+    }++    decoder->metrics_loaded = 1;+    *pp = p;+    return SFNT_Err_Ok;++  Fail:+    return SFNT_Err_Invalid_Argument;+  }+++  /* forward declaration */+  static FT_Error+  tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,+                              FT_UInt         glyph_index,+                              FT_Int          x_pos,+                              FT_Int          y_pos );++  typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,+                                                FT_Byte*        p,+                                                FT_Byte*        plimit,+                                                FT_Int          x_pos,+                                                FT_Int          y_pos );+++  static FT_Error+  tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,+                                     FT_Byte*        p,+                                     FT_Byte*        limit,+                                     FT_Int          x_pos,+                                     FT_Int          y_pos )+  {+    FT_Error    error = SFNT_Err_Ok;+    FT_Byte*    line;+    FT_Int      bit_height, bit_width, pitch, width, height, h;+    FT_Bitmap*  bitmap;+++    if ( !decoder->bitmap_allocated )+    {+      error = tt_sbit_decoder_alloc_bitmap( decoder );+      if ( error )+        goto Exit;+    }++    /* check that we can write the glyph into the bitmap */+    bitmap     = decoder->bitmap;+    bit_width  = bitmap->width;+    bit_height = bitmap->rows;+    pitch      = bitmap->pitch;+    line       = bitmap->buffer;++    width  = decoder->metrics->width;+    height = decoder->metrics->height;++    if ( x_pos < 0 || x_pos + width > bit_width   ||+         y_pos < 0 || y_pos + height > bit_height )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    if ( p + ( ( width + 7 ) >> 3 ) * height > limit )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    /* now do the blit */+    line  += y_pos * pitch + ( x_pos >> 3 );+    x_pos &= 7;++    if ( x_pos == 0 )  /* the easy one */+    {+      for ( h = height; h > 0; h--, line += pitch )+      {+        FT_Byte*  write = line;+        FT_Int    w;+++        for ( w = width; w >= 8; w -= 8 )+        {+          write[0] = (FT_Byte)( write[0] | *p++ );+          write   += 1;+        }++        if ( w > 0 )+          write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );+      }+    }+    else  /* x_pos > 0 */+    {+      for ( h = height; h > 0; h--, line += pitch )+      {+        FT_Byte*  write = line;+        FT_Int    w;+        FT_UInt   wval = 0;+++        for ( w = width; w >= 8; w -= 8 )+        {+          wval      = (FT_UInt)( wval | *p++ );+          write[0]  = (FT_Byte)( write[0] | ( wval >> x_pos ) );+          write    += 1;+          wval    <<= 8;+        }++        if ( w > 0 )+          wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );++        /* all bits read and there are `x_pos + w' bits to be written */++        write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );++        if ( x_pos + w > 8 )+        {+          write++;+          wval   <<= 8;+          write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );+        }+      }+    }++  Exit:+    return error;+  }+++  /*+   * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap+   * (with pointer `write').  In the example below, the width is 3 pixel,+   * and `x_pos' is 1 pixel.+   *+   *       p                               p+1+   *     |                               |                               |+   *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...+   *     |                               |                               |+   *       +-------+   +-------+   +-------+ ...+   *           .           .           .+   *           .           .           .+   *           v           .           .+   *       +-------+       .           .+   * |                               | .+   * | 7   6   5   4   3   2   1   0 | .+   * |                               | .+   *   write               .           .+   *                       .           .+   *                       v           .+   *                   +-------+       .+   *             |                               |+   *             | 7   6   5   4   3   2   1   0 |+   *             |                               |+   *               write+1             .+   *                                   .+   *                                   v+   *                               +-------++   *                         |                               |+   *                         | 7   6   5   4   3   2   1   0 |+   *                         |                               |+   *                           write+2+   *+   */++  static FT_Error+  tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,+                                    FT_Byte*        p,+                                    FT_Byte*        limit,+                                    FT_Int          x_pos,+                                    FT_Int          y_pos )+  {+    FT_Error    error = SFNT_Err_Ok;+    FT_Byte*    line;+    FT_Int      bit_height, bit_width, pitch, width, height, h, nbits;+    FT_Bitmap*  bitmap;+    FT_UShort   rval;+++    if ( !decoder->bitmap_allocated )+    {+      error = tt_sbit_decoder_alloc_bitmap( decoder );+      if ( error )+        goto Exit;+    }++    /* check that we can write the glyph into the bitmap */+    bitmap     = decoder->bitmap;+    bit_width  = bitmap->width;+    bit_height = bitmap->rows;+    pitch      = bitmap->pitch;+    line       = bitmap->buffer;++    width  = decoder->metrics->width;+    height = decoder->metrics->height;++    if ( x_pos < 0 || x_pos + width  > bit_width  ||+         y_pos < 0 || y_pos + height > bit_height )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    if ( p + ( ( width * height + 7 ) >> 3 ) > limit )+    {+      error = SFNT_Err_Invalid_File_Format;+      goto Exit;+    }++    /* now do the blit */++    /* adjust `line' to point to the first byte of the bitmap */+    line  += y_pos * pitch + ( x_pos >> 3 );+    x_pos &= 7;++    /* the higher byte of `rval' is used as a buffer */+    rval  = 0;+    nbits = 0;++    for ( h = height; h > 0; h--, line += pitch )+    {+      FT_Byte*  write = line;+      FT_Int    w     = width;+++      /* handle initial byte (in target bitmap) specially if necessary */+      if ( x_pos )+      {+        w = ( width < 8 - x_pos ) ? width : 8 - x_pos;++        if ( h == height )+        {+          rval  = *p++;+          nbits = x_pos;+        }+        else if ( nbits < w )+        {+          if ( p < limit )+            rval |= *p++;+          nbits += 8 - w;+        }+        else+        {+          rval  >>= 8;+          nbits  -= w;+        }++        *write++ |= ( ( rval >> nbits ) & 0xFF ) &+                    ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );+        rval    <<= 8;++        w = width - w;+      }++      /* handle medial bytes */+      for ( ; w >= 8; w -= 8 )+      {+        rval     |= *p++;+        *write++ |= ( rval >> nbits ) & 0xFF;++        rval <<= 8;+      }++      /* handle final byte if necessary */+      if ( w > 0 )+      {+        if ( nbits < w )+        {+          if ( p < limit )+            rval |= *p++;+          *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );+          nbits  += 8 - w;++          rval <<= 8;+        }+        else+        {+          *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );+          nbits  -= w;+        }+      }+    }++  Exit:+    return error;+  }+++  static FT_Error+  tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,+                                 FT_Byte*        p,+                                 FT_Byte*        limit,+                                 FT_Int          x_pos,+                                 FT_Int          y_pos )+  {+    FT_Error  error = SFNT_Err_Ok;+    FT_UInt   num_components, nn;++    FT_Char  horiBearingX = decoder->metrics->horiBearingX;+    FT_Char  horiBearingY = decoder->metrics->horiBearingY;+    FT_Byte  horiAdvance  = decoder->metrics->horiAdvance;+    FT_Char  vertBearingX = decoder->metrics->vertBearingX;+    FT_Char  vertBearingY = decoder->metrics->vertBearingY;+    FT_Byte  vertAdvance  = decoder->metrics->vertAdvance;+++    if ( p + 2 > limit )+      goto Fail;++    num_components = FT_NEXT_USHORT( p );+    if ( p + 4 * num_components > limit )+      goto Fail;++    if ( !decoder->bitmap_allocated )+    {+      error = tt_sbit_decoder_alloc_bitmap( decoder );+      if ( error )+        goto Exit;+    }++    for ( nn = 0; nn < num_components; nn++ )+    {+      FT_UInt  gindex = FT_NEXT_USHORT( p );+      FT_Byte  dx     = FT_NEXT_BYTE( p );+      FT_Byte  dy     = FT_NEXT_BYTE( p );+++      /* NB: a recursive call */+      error = tt_sbit_decoder_load_image( decoder, gindex,+                                          x_pos + dx, y_pos + dy );+      if ( error )+        break;+    }++    decoder->metrics->horiBearingX = horiBearingX;+    decoder->metrics->horiBearingY = horiBearingY;+    decoder->metrics->horiAdvance  = horiAdvance;+    decoder->metrics->vertBearingX = vertBearingX;+    decoder->metrics->vertBearingY = vertBearingY;+    decoder->metrics->vertAdvance  = vertAdvance;+    decoder->metrics->width        = (FT_UInt)decoder->bitmap->width;+    decoder->metrics->height       = (FT_UInt)decoder->bitmap->rows;++  Exit:+    return error;++  Fail:+    error = SFNT_Err_Invalid_File_Format;+    goto Exit;+  }+++  static FT_Error+  tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,+                               FT_UInt         glyph_format,+                               FT_ULong        glyph_start,+                               FT_ULong        glyph_size,+                               FT_Int          x_pos,+                               FT_Int          y_pos )+  {+    FT_Error   error;+    FT_Stream  stream = decoder->stream;+    FT_Byte*   p;+    FT_Byte*   p_limit;+    FT_Byte*   data;+++    /* seek into the EBDT table now */+    if ( glyph_start + glyph_size > decoder->ebdt_size )+    {+      error = SFNT_Err_Invalid_Argument;+      goto Exit;+    }++    if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||+         FT_FRAME_EXTRACT( glyph_size, data )                )+      goto Exit;++    p       = data;+    p_limit = p + glyph_size;++    /* read the data, depending on the glyph format */+    switch ( glyph_format )+    {+    case 1:+    case 2:+    case 8:+      error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );+      break;++    case 6:+    case 7:+    case 9:+      error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );+      break;++    default:+      error = SFNT_Err_Ok;+    }++    if ( error )+      goto Fail;++    {+      TT_SBitDecoder_LoadFunc  loader;+++      switch ( glyph_format )+      {+      case 1:+      case 6:+        loader = tt_sbit_decoder_load_byte_aligned;+        break;++      case 2:+      case 5:+      case 7:+        loader = tt_sbit_decoder_load_bit_aligned;+        break;++      case 8:+        if ( p + 1 > p_limit )+          goto Fail;++        p += 1;  /* skip padding */+        /* fall-through */++      case 9:+        loader = tt_sbit_decoder_load_compound;+        break;++      default:+        goto Fail;+      }++      error = loader( decoder, p, p_limit, x_pos, y_pos );+    }++  Fail:+    FT_FRAME_RELEASE( data );++  Exit:+    return error;+  }+++  static FT_Error+  tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,+                              FT_UInt         glyph_index,+                              FT_Int          x_pos,+                              FT_Int          y_pos )+  {+    /*+     *  First, we find the correct strike range that applies to this+     *  glyph index.+     */++    FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;+    FT_Byte*  p_limit    = decoder->eblc_limit;+    FT_ULong  num_ranges = decoder->strike_index_count;+    FT_UInt   start, end, index_format, image_format;+    FT_ULong  image_start = 0, image_end = 0, image_offset;+++    for ( ; num_ranges > 0; num_ranges-- )+    {+      start = FT_NEXT_USHORT( p );+      end   = FT_NEXT_USHORT( p );++      if ( glyph_index >= start && glyph_index <= end )+        goto FoundRange;++      p += 4;  /* ignore index offset */+    }+    goto NoBitmap;++  FoundRange:+    image_offset = FT_NEXT_ULONG( p );++    /* overflow check */+    if ( decoder->eblc_base + decoder->strike_index_array + image_offset <+           decoder->eblc_base )+      goto Failure;++    p = decoder->eblc_base + decoder->strike_index_array + image_offset;+    if ( p + 8 > p_limit )+      goto NoBitmap;++    /* now find the glyph's location and extend within the ebdt table */+    index_format = FT_NEXT_USHORT( p );+    image_format = FT_NEXT_USHORT( p );+    image_offset = FT_NEXT_ULONG ( p );++    switch ( index_format )+    {+    case 1: /* 4-byte offsets relative to `image_offset' */+      {+        p += 4 * ( glyph_index - start );+        if ( p + 8 > p_limit )+          goto NoBitmap;++        image_start = FT_NEXT_ULONG( p );+        image_end   = FT_NEXT_ULONG( p );++        if ( image_start == image_end )  /* missing glyph */+          goto NoBitmap;+      }+      break;++    case 2: /* big metrics, constant image size */+      {+        FT_ULong  image_size;+++        if ( p + 12 > p_limit )+          goto NoBitmap;++        image_size = FT_NEXT_ULONG( p );++        if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )+          goto NoBitmap;++        image_start = image_size * ( glyph_index - start );+        image_end   = image_start + image_size;+      }+      break;++    case 3: /* 2-byte offsets relative to 'image_offset' */+      {+        p += 2 * ( glyph_index - start );+        if ( p + 4 > p_limit )+          goto NoBitmap;++        image_start = FT_NEXT_USHORT( p );+        image_end   = FT_NEXT_USHORT( p );++        if ( image_start == image_end )  /* missing glyph */+          goto NoBitmap;+      }+      break;++    case 4: /* sparse glyph array with (glyph,offset) pairs */+      {+        FT_ULong  mm, num_glyphs;+++        if ( p + 4 > p_limit )+          goto NoBitmap;++        num_glyphs = FT_NEXT_ULONG( p );++        /* overflow check */+        if ( p + ( num_glyphs + 1 ) * 4 < p )+          goto Failure;++        if ( p + ( num_glyphs + 1 ) * 4 > p_limit )+          goto NoBitmap;++        for ( mm = 0; mm < num_glyphs; mm++ )+        {+          FT_UInt  gindex = FT_NEXT_USHORT( p );+++          if ( gindex == glyph_index )+          {+            image_start = FT_NEXT_USHORT( p );+            p          += 2;+            image_end   = FT_PEEK_USHORT( p );+            break;+          }+          p += 2;+        }++        if ( mm >= num_glyphs )+          goto NoBitmap;+      }+      break;++    case 5: /* constant metrics with sparse glyph codes */+      {+        FT_ULong  image_size, mm, num_glyphs;+++        if ( p + 16 > p_limit )+          goto NoBitmap;++        image_size = FT_NEXT_ULONG( p );++        if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )+          goto NoBitmap;++        num_glyphs = FT_NEXT_ULONG( p );++        /* overflow check */+        if ( p + 2 * num_glyphs < p )+          goto Failure;++        if ( p + 2 * num_glyphs > p_limit )+          goto NoBitmap;++        for ( mm = 0; mm < num_glyphs; mm++ )+        {+          FT_UInt  gindex = FT_NEXT_USHORT( p );+++          if ( gindex == glyph_index )+            break;+        }++        if ( mm >= num_glyphs )+          goto NoBitmap;++        image_start = image_size * mm;+        image_end   = image_start + image_size;+      }+      break;++    default:+      goto NoBitmap;+    }++    if ( image_start > image_end )+      goto NoBitmap;++    image_end  -= image_start;+    image_start = image_offset + image_start;++    return tt_sbit_decoder_load_bitmap( decoder,+                                        image_format,+                                        image_start,+                                        image_end,+                                        x_pos,+                                        y_pos );++  Failure:+    return SFNT_Err_Invalid_Table;++  NoBitmap:+    return SFNT_Err_Invalid_Argument;+  }+++  FT_LOCAL( FT_Error )+  tt_face_load_sbit_image( TT_Face              face,+                           FT_ULong             strike_index,+                           FT_UInt              glyph_index,+                           FT_UInt              load_flags,+                           FT_Stream            stream,+                           FT_Bitmap           *map,+                           TT_SBit_MetricsRec  *metrics )+  {+    TT_SBitDecoderRec  decoder[1];+    FT_Error           error;++    FT_UNUSED( load_flags );+    FT_UNUSED( stream );+    FT_UNUSED( map );+++    error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );+    if ( !error )+    {+      error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );+      tt_sbit_decoder_done( decoder );+    }++    return error;+  }++/* EOF */
+ src/smooth/ftgrays.c view
@@ -0,0 +1,2062 @@+/***************************************************************************/+/*                                                                         */+/*  ftgrays.c                                                              */+/*                                                                         */+/*    A new `perfect' anti-aliasing renderer (body).                       */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* This file can be compiled without the rest of the FreeType engine, by */+  /* defining the _STANDALONE_ macro when compiling it.  You also need to  */+  /* put the files `ftgrays.h' and `ftimage.h' into the current            */+  /* compilation directory.  Typically, you could do something like        */+  /*                                                                       */+  /* - copy `src/smooth/ftgrays.c' (this file) to your current directory   */+  /*                                                                       */+  /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */+  /*   same directory                                                      */+  /*                                                                       */+  /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in        */+  /*                                                                       */+  /*     cc -c -D_STANDALONE_ ftgrays.c                                    */+  /*                                                                       */+  /* The renderer can be initialized with a call to                        */+  /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated  */+  /* with a call to `ft_gray_raster.raster_render'.                        */+  /*                                                                       */+  /* See the comments and documentation in the file `ftimage.h' for more   */+  /* details on how the raster works.                                      */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* This is a new anti-aliasing scan-converter for FreeType 2.  The       */+  /* algorithm used here is _very_ different from the one in the standard  */+  /* `ftraster' module.  Actually, `ftgrays' computes the _exact_          */+  /* coverage of the outline on each pixel cell.                           */+  /*                                                                       */+  /* It is based on ideas that I initially found in Raph Levien's          */+  /* excellent LibArt graphics library (see http://www.levien.com/libart   */+  /* for more information, though the web pages do not tell anything       */+  /* about the renderer; you'll have to dive into the source code to       */+  /* understand how it works).                                             */+  /*                                                                       */+  /* Note, however, that this is a _very_ different implementation         */+  /* compared to Raph's.  Coverage information is stored in a very         */+  /* different way, and I don't use sorted vector paths.  Also, it doesn't */+  /* use floating point values.                                            */+  /*                                                                       */+  /* This renderer has the following advantages:                           */+  /*                                                                       */+  /* - It doesn't need an intermediate bitmap.  Instead, one can supply a  */+  /*   callback function that will be called by the renderer to draw gray  */+  /*   spans on any target surface.  You can thus do direct composition on */+  /*   any kind of bitmap, provided that you give the renderer the right   */+  /*   callback.                                                           */+  /*                                                                       */+  /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on   */+  /*   each pixel cell.                                                    */+  /*                                                                       */+  /* - It performs a single pass on the outline (the `standard' FT2        */+  /*   renderer makes two passes).                                         */+  /*                                                                       */+  /* - It can easily be modified to render to _any_ number of gray levels  */+  /*   cheaply.                                                            */+  /*                                                                       */+  /* - For small (< 20) pixel sizes, it is faster than the standard        */+  /*   renderer.                                                           */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_smooth+++#ifdef _STANDALONE_+++  /* define this to dump debugging information */+/* #define FT_DEBUG_LEVEL_TRACE */+++#ifdef FT_DEBUG_LEVEL_TRACE+#include <stdio.h>+#include <stdarg.h>+#endif++#include <stddef.h>+#include <string.h>+#include <setjmp.h>+#include <limits.h>+#define FT_UINT_MAX  UINT_MAX+#define FT_INT_MAX   INT_MAX++#define ft_memset   memset++#define ft_setjmp   setjmp+#define ft_longjmp  longjmp+#define ft_jmp_buf  jmp_buf++typedef ptrdiff_t  FT_PtrDist;+++#define ErrRaster_Invalid_Mode      -2+#define ErrRaster_Invalid_Outline   -1+#define ErrRaster_Invalid_Argument  -3+#define ErrRaster_Memory_Overflow   -4++#define FT_BEGIN_HEADER+#define FT_END_HEADER++#include "ftimage.h"+#include "ftgrays.h"+++  /* This macro is used to indicate that a function parameter is unused. */+  /* Its purpose is simply to reduce compiler warnings.  Note also that  */+  /* simply defining it as `(void)x' doesn't avoid warnings with certain */+  /* ANSI compilers (e.g. LCC).                                          */+#define FT_UNUSED( x )  (x) = (x)+++  /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */++#ifdef FT_DEBUG_LEVEL_TRACE++  void+  FT_Message( const char*  fmt,+              ... )+  {+    va_list  ap;+++    va_start( ap, fmt );+    vfprintf( stderr, fmt, ap );+    va_end( ap );+  }++  /* we don't handle tracing levels in stand-alone mode; */+#ifndef FT_TRACE5+#define FT_TRACE5( varformat )  FT_Message varformat+#endif+#ifndef FT_TRACE7+#define FT_TRACE7( varformat )  FT_Message varformat+#endif+#ifndef FT_ERROR+#define FT_ERROR( varformat )   FT_Message varformat+#endif++#else /* !FT_DEBUG_LEVEL_TRACE */++#define FT_TRACE5( x )  do { } while ( 0 )     /* nothing */+#define FT_TRACE7( x )  do { } while ( 0 )     /* nothing */+#define FT_ERROR( x )   do { } while ( 0 )     /* nothing */++#endif /* !FT_DEBUG_LEVEL_TRACE */+++#define FT_DEFINE_OUTLINE_FUNCS( class_,               \+                                 move_to_, line_to_,   \+                                 conic_to_, cubic_to_, \+                                 shift_, delta_ )      \+          static const FT_Outline_Funcs class_ =       \+          {                                            \+            move_to_,                                  \+            line_to_,                                  \+            conic_to_,                                 \+            cubic_to_,                                 \+            shift_,                                    \+            delta_                                     \+         };++#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_,            \+                                raster_new_, raster_reset_,       \+                                raster_set_mode_, raster_render_, \+                                raster_done_ )                    \+          const FT_Raster_Funcs class_ =                          \+          {                                                       \+            glyph_format_,                                        \+            raster_new_,                                          \+            raster_reset_,                                        \+            raster_set_mode_,                                     \+            raster_render_,                                       \+            raster_done_                                          \+         };++#else /* !_STANDALONE_ */+++#include <ft2build.h>+#include "ftgrays.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_OUTLINE_H++#include "ftsmerrs.h"++#include "ftspic.h"++#define ErrRaster_Invalid_Mode      Smooth_Err_Cannot_Render_Glyph+#define ErrRaster_Invalid_Outline   Smooth_Err_Invalid_Outline+#define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory+#define ErrRaster_Invalid_Argument  Smooth_Err_Invalid_Argument++#endif /* !_STANDALONE_ */++#ifndef FT_MEM_SET+#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )+#endif++#ifndef FT_MEM_ZERO+#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )+#endif++  /* as usual, for the speed hungry :-) */++#ifndef FT_STATIC_RASTER++#define RAS_ARG   PWorker  worker+#define RAS_ARG_  PWorker  worker,++#define RAS_VAR   worker+#define RAS_VAR_  worker,++#else /* FT_STATIC_RASTER */++#define RAS_ARG   /* empty */+#define RAS_ARG_  /* empty */+#define RAS_VAR   /* empty */+#define RAS_VAR_  /* empty */++#endif /* FT_STATIC_RASTER */+++  /* must be at least 6 bits! */+#define PIXEL_BITS  8++#define ONE_PIXEL       ( 1L << PIXEL_BITS )+#define PIXEL_MASK      ( -1L << PIXEL_BITS )+#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )+#define SUBPIXELS( x )  ( (TPos)(x) << PIXEL_BITS )+#define FLOOR( x )      ( (x) & -ONE_PIXEL )+#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )+#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )++#if PIXEL_BITS >= 6+#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )+#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )+#else+#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )+#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )+#endif+++  /*************************************************************************/+  /*                                                                       */+  /*   TYPE DEFINITIONS                                                    */+  /*                                                                       */++  /* don't change the following types to FT_Int or FT_Pos, since we might */+  /* need to define them to "float" or "double" when experimenting with   */+  /* new algorithms                                                       */++  typedef long  TCoord;   /* integer scanline/pixel coordinate */+  typedef long  TPos;     /* sub-pixel coordinate              */++  /* determine the type used to store cell areas.  This normally takes at */+  /* least PIXEL_BITS*2 + 1 bits.  On 16-bit systems, we need to use      */+  /* `long' instead of `int', otherwise bad things happen                 */++#if PIXEL_BITS <= 7++  typedef int  TArea;++#else /* PIXEL_BITS >= 8 */++  /* approximately determine the size of integers using an ANSI-C header */+#if FT_UINT_MAX == 0xFFFFU+  typedef long  TArea;+#else+  typedef int   TArea;+#endif++#endif /* PIXEL_BITS >= 8 */+++  /* maximal number of gray spans in a call to the span callback */+#define FT_MAX_GRAY_SPANS  32+++  typedef struct TCell_*  PCell;++  typedef struct  TCell_+  {+    TPos   x;     /* same with TWorker.ex */+    TCoord cover; /* same with TWorker.cover */+    TArea  area;+    PCell  next;++  } TCell;+++  typedef struct  TWorker_+  {+    TCoord  ex, ey;+    TPos    min_ex, max_ex;+    TPos    min_ey, max_ey;+    TPos    count_ex, count_ey;++    TArea   area;+    TCoord  cover;+    int     invalid;++    PCell   cells;+    FT_PtrDist  max_cells;+    FT_PtrDist  num_cells;++    TCoord  cx, cy;+    TPos    x,  y;++    TPos    last_ey;++    FT_Vector   bez_stack[32 * 3 + 1];+    int         lev_stack[32];++    FT_Outline  outline;+    FT_Bitmap   target;+    FT_BBox     clip_box;++    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];+    int         num_gray_spans;++    FT_Raster_Span_Func  render_span;+    void*                render_span_data;+    int                  span_y;++    int  band_size;+    int  band_shoot;++    ft_jmp_buf  jump_buffer;++    void*       buffer;+    long        buffer_size;++    PCell*     ycells;+    TPos       ycount;++  } TWorker, *PWorker;+++#ifndef FT_STATIC_RASTER+#define ras  (*worker)+#else+  static TWorker  ras;+#endif+++  typedef struct TRaster_+  {+    void*    buffer;+    long     buffer_size;+    int      band_size;+    void*    memory;+    PWorker  worker;++  } TRaster, *PRaster;++++  /*************************************************************************/+  /*                                                                       */+  /* Initialize the cells table.                                           */+  /*                                                                       */+  static void+  gray_init_cells( RAS_ARG_ void*  buffer,+                   long            byte_size )+  {+    ras.buffer      = buffer;+    ras.buffer_size = byte_size;++    ras.ycells      = (PCell*) buffer;+    ras.cells       = NULL;+    ras.max_cells   = 0;+    ras.num_cells   = 0;+    ras.area        = 0;+    ras.cover       = 0;+    ras.invalid     = 1;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Compute the outline bounding box.                                     */+  /*                                                                       */+  static void+  gray_compute_cbox( RAS_ARG )+  {+    FT_Outline*  outline = &ras.outline;+    FT_Vector*   vec     = outline->points;+    FT_Vector*   limit   = vec + outline->n_points;+++    if ( outline->n_points <= 0 )+    {+      ras.min_ex = ras.max_ex = 0;+      ras.min_ey = ras.max_ey = 0;+      return;+    }++    ras.min_ex = ras.max_ex = vec->x;+    ras.min_ey = ras.max_ey = vec->y;++    vec++;++    for ( ; vec < limit; vec++ )+    {+      TPos  x = vec->x;+      TPos  y = vec->y;+++      if ( x < ras.min_ex ) ras.min_ex = x;+      if ( x > ras.max_ex ) ras.max_ex = x;+      if ( y < ras.min_ey ) ras.min_ey = y;+      if ( y > ras.max_ey ) ras.max_ey = y;+    }++    /* truncate the bounding box to integer pixels */+    ras.min_ex = ras.min_ex >> 6;+    ras.min_ey = ras.min_ey >> 6;+    ras.max_ex = ( ras.max_ex + 63 ) >> 6;+    ras.max_ey = ( ras.max_ey + 63 ) >> 6;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Record the current cell in the table.                                 */+  /*                                                                       */+  static PCell+  gray_find_cell( RAS_ARG )+  {+    PCell  *pcell, cell;+    TPos    x = ras.ex;+++    if ( x > ras.count_ex )+      x = ras.count_ex;++    pcell = &ras.ycells[ras.ey];+    for (;;)+    {+      cell = *pcell;+      if ( cell == NULL || cell->x > x )+        break;++      if ( cell->x == x )+        goto Exit;++      pcell = &cell->next;+    }++    if ( ras.num_cells >= ras.max_cells )+      ft_longjmp( ras.jump_buffer, 1 );++    cell        = ras.cells + ras.num_cells++;+    cell->x     = x;+    cell->area  = 0;+    cell->cover = 0;++    cell->next  = *pcell;+    *pcell      = cell;++  Exit:+    return cell;+  }+++  static void+  gray_record_cell( RAS_ARG )+  {+    if ( !ras.invalid && ( ras.area | ras.cover ) )+    {+      PCell  cell = gray_find_cell( RAS_VAR );+++      cell->area  += ras.area;+      cell->cover += ras.cover;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Set the current cell to a new position.                               */+  /*                                                                       */+  static void+  gray_set_cell( RAS_ARG_ TCoord  ex,+                          TCoord  ey )+  {+    /* Move the cell pointer to a new position.  We set the `invalid'      */+    /* flag to indicate that the cell isn't part of those we're interested */+    /* in during the render phase.  This means that:                       */+    /*                                                                     */+    /* . the new vertical position must be within min_ey..max_ey-1.        */+    /* . the new horizontal position must be strictly less than max_ex     */+    /*                                                                     */+    /* Note that if a cell is to the left of the clipping region, it is    */+    /* actually set to the (min_ex-1) horizontal position.                 */++    /* All cells that are on the left of the clipping region go to the */+    /* min_ex - 1 horizontal position.                                 */+    ey -= ras.min_ey;++    if ( ex > ras.max_ex )+      ex = ras.max_ex;++    ex -= ras.min_ex;+    if ( ex < 0 )+      ex = -1;++    /* are we moving to a different cell ? */+    if ( ex != ras.ex || ey != ras.ey )+    {+      /* record the current one if it is valid */+      if ( !ras.invalid )+        gray_record_cell( RAS_VAR );++      ras.area  = 0;+      ras.cover = 0;+    }++    ras.ex      = ex;+    ras.ey      = ey;+    ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||+                              ex >= ras.count_ex           );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Start a new contour at a given cell.                                  */+  /*                                                                       */+  static void+  gray_start_cell( RAS_ARG_ TCoord  ex,+                            TCoord  ey )+  {+    if ( ex > ras.max_ex )+      ex = (TCoord)( ras.max_ex );++    if ( ex < ras.min_ex )+      ex = (TCoord)( ras.min_ex - 1 );++    ras.area    = 0;+    ras.cover   = 0;+    ras.ex      = ex - ras.min_ex;+    ras.ey      = ey - ras.min_ey;+    ras.last_ey = SUBPIXELS( ey );+    ras.invalid = 0;++    gray_set_cell( RAS_VAR_ ex, ey );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Render a scanline as one or more cells.                               */+  /*                                                                       */+  static void+  gray_render_scanline( RAS_ARG_ TCoord  ey,+                                 TPos    x1,+                                 TCoord  y1,+                                 TPos    x2,+                                 TCoord  y2 )+  {+    TCoord  ex1, ex2, fx1, fx2, delta, mod, lift, rem;+    long    p, first, dx;+    int     incr;+++    dx = x2 - x1;++    ex1 = TRUNC( x1 );+    ex2 = TRUNC( x2 );+    fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );+    fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );++    /* trivial case.  Happens often */+    if ( y1 == y2 )+    {+      gray_set_cell( RAS_VAR_ ex2, ey );+      return;+    }++    /* everything is located in a single cell.  That is easy! */+    /*                                                        */+    if ( ex1 == ex2 )+    {+      delta      = y2 - y1;+      ras.area  += (TArea)(( fx1 + fx2 ) * delta);+      ras.cover += delta;+      return;+    }++    /* ok, we'll have to render a run of adjacent cells on the same */+    /* scanline...                                                  */+    /*                                                              */+    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );+    first = ONE_PIXEL;+    incr  = 1;++    if ( dx < 0 )+    {+      p     = fx1 * ( y2 - y1 );+      first = 0;+      incr  = -1;+      dx    = -dx;+    }++    delta = (TCoord)( p / dx );+    mod   = (TCoord)( p % dx );+    if ( mod < 0 )+    {+      delta--;+      mod += (TCoord)dx;+    }++    ras.area  += (TArea)(( fx1 + first ) * delta);+    ras.cover += delta;++    ex1 += incr;+    gray_set_cell( RAS_VAR_ ex1, ey );+    y1  += delta;++    if ( ex1 != ex2 )+    {+      p    = ONE_PIXEL * ( y2 - y1 + delta );+      lift = (TCoord)( p / dx );+      rem  = (TCoord)( p % dx );+      if ( rem < 0 )+      {+        lift--;+        rem += (TCoord)dx;+      }++      mod -= (int)dx;++      while ( ex1 != ex2 )+      {+        delta = lift;+        mod  += rem;+        if ( mod >= 0 )+        {+          mod -= (TCoord)dx;+          delta++;+        }++        ras.area  += (TArea)(ONE_PIXEL * delta);+        ras.cover += delta;+        y1        += delta;+        ex1       += incr;+        gray_set_cell( RAS_VAR_ ex1, ey );+      }+    }++    delta      = y2 - y1;+    ras.area  += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);+    ras.cover += delta;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Render a given line as a series of scanlines.                         */+  /*                                                                       */+  static void+  gray_render_line( RAS_ARG_ TPos  to_x,+                             TPos  to_y )+  {+    TCoord  ey1, ey2, fy1, fy2, mod;+    TPos    dx, dy, x, x2;+    long    p, first;+    int     delta, rem, lift, incr;+++    ey1 = TRUNC( ras.last_ey );+    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */+    fy1 = (TCoord)( ras.y - ras.last_ey );+    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );++    dx = to_x - ras.x;+    dy = to_y - ras.y;++    /* XXX: we should do something about the trivial case where dx == 0, */+    /*      as it happens very often!                                    */++    /* perform vertical clipping */+    {+      TCoord  min, max;+++      min = ey1;+      max = ey2;+      if ( ey1 > ey2 )+      {+        min = ey2;+        max = ey1;+      }+      if ( min >= ras.max_ey || max < ras.min_ey )+        goto End;+    }++    /* everything is on a single scanline */+    if ( ey1 == ey2 )+    {+      gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );+      goto End;+    }++    /* vertical line - avoid calling gray_render_scanline */+    incr = 1;++    if ( dx == 0 )+    {+      TCoord  ex     = TRUNC( ras.x );+      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );+      TArea   area;+++      first = ONE_PIXEL;+      if ( dy < 0 )+      {+        first = 0;+        incr  = -1;+      }++      delta      = (int)( first - fy1 );+      ras.area  += (TArea)two_fx * delta;+      ras.cover += delta;+      ey1       += incr;++      gray_set_cell( RAS_VAR_ ex, ey1 );++      delta = (int)( first + first - ONE_PIXEL );+      area  = (TArea)two_fx * delta;+      while ( ey1 != ey2 )+      {+        ras.area  += area;+        ras.cover += delta;+        ey1       += incr;++        gray_set_cell( RAS_VAR_ ex, ey1 );+      }++      delta      = (int)( fy2 - ONE_PIXEL + first );+      ras.area  += (TArea)two_fx * delta;+      ras.cover += delta;++      goto End;+    }++    /* ok, we have to render several scanlines */+    p     = ( ONE_PIXEL - fy1 ) * dx;+    first = ONE_PIXEL;+    incr  = 1;++    if ( dy < 0 )+    {+      p     = fy1 * dx;+      first = 0;+      incr  = -1;+      dy    = -dy;+    }++    delta = (int)( p / dy );+    mod   = (int)( p % dy );+    if ( mod < 0 )+    {+      delta--;+      mod += (TCoord)dy;+    }++    x = ras.x + delta;+    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );++    ey1 += incr;+    gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );++    if ( ey1 != ey2 )+    {+      p     = ONE_PIXEL * dx;+      lift  = (int)( p / dy );+      rem   = (int)( p % dy );+      if ( rem < 0 )+      {+        lift--;+        rem += (int)dy;+      }+      mod -= (int)dy;++      while ( ey1 != ey2 )+      {+        delta = lift;+        mod  += rem;+        if ( mod >= 0 )+        {+          mod -= (int)dy;+          delta++;+        }++        x2 = x + delta;+        gray_render_scanline( RAS_VAR_ ey1, x,+                                       (TCoord)( ONE_PIXEL - first ), x2,+                                       (TCoord)first );+        x = x2;++        ey1 += incr;+        gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );+      }+    }++    gray_render_scanline( RAS_VAR_ ey1, x,+                                   (TCoord)( ONE_PIXEL - first ), to_x,+                                   fy2 );++  End:+    ras.x       = to_x;+    ras.y       = to_y;+    ras.last_ey = SUBPIXELS( ey2 );+  }+++  static void+  gray_split_conic( FT_Vector*  base )+  {+    TPos  a, b;+++    base[4].x = base[2].x;+    b = base[1].x;+    a = base[3].x = ( base[2].x + b ) / 2;+    b = base[1].x = ( base[0].x + b ) / 2;+    base[2].x = ( a + b ) / 2;++    base[4].y = base[2].y;+    b = base[1].y;+    a = base[3].y = ( base[2].y + b ) / 2;+    b = base[1].y = ( base[0].y + b ) / 2;+    base[2].y = ( a + b ) / 2;+  }+++  static void+  gray_render_conic( RAS_ARG_ const FT_Vector*  control,+                              const FT_Vector*  to )+  {+    TPos        dx, dy;+    int         top, level;+    int*        levels;+    FT_Vector*  arc;+++    arc      = ras.bez_stack;+    arc[0].x = UPSCALE( to->x );+    arc[0].y = UPSCALE( to->y );+    arc[1].x = UPSCALE( control->x );+    arc[1].y = UPSCALE( control->y );+    arc[2].x = ras.x;+    arc[2].y = ras.y;++    dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );+    dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );+    if ( dx < dy )+      dx = dy;++    if ( dx <= ONE_PIXEL / 4 )+    {+      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );+      return;+    }++    level = 0;+    while ( dx > ONE_PIXEL / 4 )+    {+      dx >>= 2;+      level++;+    }++    levels    = ras.lev_stack;+    levels[0] = level;+    top       = 0;++    while ( top >= 0 )+    {+      level = levels[top];+      if ( level > 1 )+      {+        /* check that the arc crosses the current band */+        TPos  min, max, y;+++        min = max = arc[0].y;++        y = arc[1].y;+        if ( y < min ) min = y;+        if ( y > max ) max = y;++        y = arc[2].y;+        if ( y < min ) min = y;+        if ( y > max ) max = y;++        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )+          goto Draw;++        gray_split_conic( arc );+        arc += 2;+        top++;+        levels[top] = levels[top - 1] = level - 1;+        continue;+      }++    Draw:+      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );+      top--;+      arc -= 2;+    }++    return;+  }+++  static void+  gray_split_cubic( FT_Vector*  base )+  {+    TPos  a, b, c, d;+++    base[6].x = base[3].x;+    c = base[1].x;+    d = base[2].x;+    base[1].x = a = ( base[0].x + c ) / 2;+    base[5].x = b = ( base[3].x + d ) / 2;+    c = ( c + d ) / 2;+    base[2].x = a = ( a + c ) / 2;+    base[4].x = b = ( b + c ) / 2;+    base[3].x = ( a + b ) / 2;++    base[6].y = base[3].y;+    c = base[1].y;+    d = base[2].y;+    base[1].y = a = ( base[0].y + c ) / 2;+    base[5].y = b = ( base[3].y + d ) / 2;+    c = ( c + d ) / 2;+    base[2].y = a = ( a + c ) / 2;+    base[4].y = b = ( b + c ) / 2;+    base[3].y = ( a + b ) / 2;+  }+++  static void+  gray_render_cubic( RAS_ARG_ const FT_Vector*  control1,+                              const FT_Vector*  control2,+                              const FT_Vector*  to )+  {+    FT_Vector*  arc;+++    arc      = ras.bez_stack;+    arc[0].x = UPSCALE( to->x );+    arc[0].y = UPSCALE( to->y );+    arc[1].x = UPSCALE( control2->x );+    arc[1].y = UPSCALE( control2->y );+    arc[2].x = UPSCALE( control1->x );+    arc[2].y = UPSCALE( control1->y );+    arc[3].x = ras.x;+    arc[3].y = ras.y;++    for (;;)+    {+      /* Check that the arc crosses the current band. */+      TPos  min, max, y;+++      min = max = arc[0].y;++      y = arc[1].y;+      if ( y < min )+        min = y;+      if ( y > max )+        max = y;++      y = arc[2].y;+      if ( y < min )+        min = y;+      if ( y > max )+        max = y;++      y = arc[3].y;+      if ( y < min )+        min = y;+      if ( y > max )+        max = y;++      if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )+        goto Draw;++      /* Decide whether to split or draw. See `Rapid Termination          */+      /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */+      /* F. Hain, at                                                      */+      /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */++      {+        TPos  dx, dy, dx_, dy_;+        TPos  dx1, dy1, dx2, dy2;+        TPos  L, s, s_limit;+++        /* dx and dy are x and y components of the P0-P3 chord vector. */+        dx = arc[3].x - arc[0].x;+        dy = arc[3].y - arc[0].y;++        /* L is an (under)estimate of the Euclidean distance P0-P3.       */+        /*                                                                */+        /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated   */+        /* with least maximum error by                                    */+        /*                                                                */+        /*   r_upperbound = dx + (sqrt(2) - 1) * dy  ,                    */+        /*                                                                */+        /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */+        /* error of no more than 8.4%.                                    */+        /*                                                                */+        /* Similarly, some elementary calculus shows that r can be        */+        /* underestimated with least maximum error by                     */+        /*                                                                */+        /*   r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx                    */+        /*                  + sqrt(2 - sqrt(2)) / 2 * dy  .               */+        /*                                                                */+        /* 236/256 and 97/256 are (under)estimates of the two algebraic   */+        /* numbers, giving an error of no more than 8.1%.                 */++        dx_ = FT_ABS( dx );+        dy_ = FT_ABS( dy );++        /* This is the same as                     */+        /*                                         */+        /*   L = ( 236 * FT_MAX( dx_, dy_ )        */+        /*       + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */+        L = ( dx_ > dy_ ? 236 * dx_ +  97 * dy_+                        :  97 * dx_ + 236 * dy_ ) >> 8;++        /* Avoid possible arithmetic overflow below by splitting. */+        if ( L > 32767 )+          goto Split;++        /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */+        s_limit = L * (TPos)( ONE_PIXEL / 6 );++        /* s is L * the perpendicular distance from P1 to the line P0-P3. */+        dx1 = arc[1].x - arc[0].x;+        dy1 = arc[1].y - arc[0].y;+        s = FT_ABS( dy * dx1 - dx * dy1 );++        if ( s > s_limit )+          goto Split;++        /* s is L * the perpendicular distance from P2 to the line P0-P3. */+        dx2 = arc[2].x - arc[0].x;+        dy2 = arc[2].y - arc[0].y;+        s = FT_ABS( dy * dx2 - dx * dy2 );++        if ( s > s_limit )+          goto Split;++        /* If P1 or P2 is outside P0-P3, split the curve. */+        if ( dy * dy1 + dx * dx1 < 0                                     ||+             dy * dy2 + dx * dx2 < 0                                     ||+             dy * (arc[3].y - arc[1].y) + dx * (arc[3].x - arc[1].x) < 0 ||+             dy * (arc[3].y - arc[2].y) + dx * (arc[3].x - arc[2].x) < 0 )+          goto Split;++        /* No reason to split. */+        goto Draw;+      }++    Split:+      gray_split_cubic( arc );+      arc += 3;+      continue;++    Draw:+      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );++      if ( arc == ras.bez_stack )+        return;++      arc -= 3;+    }+  }+++  static int+  gray_move_to( const FT_Vector*  to,+                PWorker           worker )+  {+    TPos  x, y;+++    /* record current cell, if any */+    gray_record_cell( RAS_VAR );++    /* start to a new position */+    x = UPSCALE( to->x );+    y = UPSCALE( to->y );++    gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );++    worker->x = x;+    worker->y = y;+    return 0;+  }+++  static int+  gray_line_to( const FT_Vector*  to,+                PWorker           worker )+  {+    gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );+    return 0;+  }+++  static int+  gray_conic_to( const FT_Vector*  control,+                 const FT_Vector*  to,+                 PWorker           worker )+  {+    gray_render_conic( RAS_VAR_ control, to );+    return 0;+  }+++  static int+  gray_cubic_to( const FT_Vector*  control1,+                 const FT_Vector*  control2,+                 const FT_Vector*  to,+                 PWorker           worker )+  {+    gray_render_cubic( RAS_VAR_ control1, control2, to );+    return 0;+  }+++  static void+  gray_render_span( int             y,+                    int             count,+                    const FT_Span*  spans,+                    PWorker         worker )+  {+    unsigned char*  p;+    FT_Bitmap*      map = &worker->target;+++    /* first of all, compute the scanline offset */+    p = (unsigned char*)map->buffer - y * map->pitch;+    if ( map->pitch >= 0 )+      p += (unsigned)( ( map->rows - 1 ) * map->pitch );++    for ( ; count > 0; count--, spans++ )+    {+      unsigned char  coverage = spans->coverage;+++      if ( coverage )+      {+        /* For small-spans it is faster to do it by ourselves than+         * calling `memset'.  This is mainly due to the cost of the+         * function call.+         */+        if ( spans->len >= 8 )+          FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );+        else+        {+          unsigned char*  q = p + spans->x;+++          switch ( spans->len )+          {+          case 7: *q++ = (unsigned char)coverage;+          case 6: *q++ = (unsigned char)coverage;+          case 5: *q++ = (unsigned char)coverage;+          case 4: *q++ = (unsigned char)coverage;+          case 3: *q++ = (unsigned char)coverage;+          case 2: *q++ = (unsigned char)coverage;+          case 1: *q   = (unsigned char)coverage;+          default:+            ;+          }+        }+      }+    }+  }+++  static void+  gray_hline( RAS_ARG_ TCoord  x,+                       TCoord  y,+                       TPos    area,+                       TCoord  acount )+  {+    FT_Span*  span;+    int       count;+    int       coverage;+++    /* compute the coverage line's coverage, depending on the    */+    /* outline fill rule                                         */+    /*                                                           */+    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */+    /*                                                           */+    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );+                                                    /* use range 0..256 */+    if ( coverage < 0 )+      coverage = -coverage;++    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )+    {+      coverage &= 511;++      if ( coverage > 256 )+        coverage = 512 - coverage;+      else if ( coverage == 256 )+        coverage = 255;+    }+    else+    {+      /* normal non-zero winding rule */+      if ( coverage >= 256 )+        coverage = 255;+    }++    y += (TCoord)ras.min_ey;+    x += (TCoord)ras.min_ex;++    /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */+    if ( x >= 32767 )+      x = 32767;++    /* FT_Span.y is an integer, so limit our coordinates appropriately */+    if ( y >= FT_INT_MAX )+      y = FT_INT_MAX;++    if ( coverage )+    {+      /* see whether we can add this span to the current list */+      count = ras.num_gray_spans;+      span  = ras.gray_spans + count - 1;+      if ( count > 0                          &&+           ras.span_y == y                    &&+           (int)span->x + span->len == (int)x &&+           span->coverage == coverage         )+      {+        span->len = (unsigned short)( span->len + acount );+        return;+      }++      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )+      {+        if ( ras.render_span && count > 0 )+          ras.render_span( ras.span_y, count, ras.gray_spans,+                           ras.render_span_data );++#ifdef FT_DEBUG_LEVEL_TRACE++        if ( count > 0 )+        {+          int  n;+++          FT_TRACE7(( "y = %3d ", ras.span_y ));+          span = ras.gray_spans;+          for ( n = 0; n < count; n++, span++ )+            FT_TRACE7(( "[%d..%d]:%02x ",+                        span->x, span->x + span->len - 1, span->coverage ));+          FT_TRACE7(( "\n" ));+        }++#endif /* FT_DEBUG_LEVEL_TRACE */++        ras.num_gray_spans = 0;+        ras.span_y         = (int)y;++        count = 0;+        span  = ras.gray_spans;+      }+      else+        span++;++      /* add a gray span to the current list */+      span->x        = (short)x;+      span->len      = (unsigned short)acount;+      span->coverage = (unsigned char)coverage;++      ras.num_gray_spans++;+    }+  }+++#ifdef FT_DEBUG_LEVEL_TRACE++  /* to be called while in the debugger --                                */+  /* this function causes a compiler warning since it is unused otherwise */+  static void+  gray_dump_cells( RAS_ARG )+  {+    int  yindex;+++    for ( yindex = 0; yindex < ras.ycount; yindex++ )+    {+      PCell  cell;+++      printf( "%3d:", yindex );++      for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )+        printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );+      printf( "\n" );+    }+  }++#endif /* FT_DEBUG_LEVEL_TRACE */+++  static void+  gray_sweep( RAS_ARG_ const FT_Bitmap*  target )+  {+    int  yindex;++    FT_UNUSED( target );+++    if ( ras.num_cells == 0 )+      return;++    ras.num_gray_spans = 0;++    FT_TRACE7(( "gray_sweep: start\n" ));++    for ( yindex = 0; yindex < ras.ycount; yindex++ )+    {+      PCell   cell  = ras.ycells[yindex];+      TCoord  cover = 0;+      TCoord  x     = 0;+++      for ( ; cell != NULL; cell = cell->next )+      {+        TPos  area;+++        if ( cell->x > x && cover != 0 )+          gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),+                      cell->x - x );++        cover += cell->cover;+        area   = cover * ( ONE_PIXEL * 2 ) - cell->area;++        if ( area != 0 && cell->x >= 0 )+          gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );++        x = cell->x + 1;+      }++      if ( cover != 0 )+        gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),+                    ras.count_ex - x );+    }++    if ( ras.render_span && ras.num_gray_spans > 0 )+      ras.render_span( ras.span_y, ras.num_gray_spans,+                       ras.gray_spans, ras.render_span_data );++    FT_TRACE7(( "gray_sweep: end\n" ));+  }+++#ifdef _STANDALONE_++  /*************************************************************************/+  /*                                                                       */+  /*  The following function should only compile in stand-alone mode,      */+  /*  i.e., when building this component without the rest of FreeType.     */+  /*                                                                       */+  /*************************************************************************/++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    FT_Outline_Decompose                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Walk over an outline's structure to decompose it into individual   */+  /*    segments and Bézier arcs.  This function is also able to emit      */+  /*    `move to' and `close to' operations to indicate the start and end  */+  /*    of new contours in the outline.                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    outline        :: A pointer to the source target.                  */+  /*                                                                       */+  /*    func_interface :: A table of `emitters', i.e., function pointers   */+  /*                      called during decomposition to indicate path     */+  /*                      operations.                                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    user           :: A typeless pointer which is passed to each       */+  /*                      emitter during the decomposition.  It can be     */+  /*                      used to store the state during the               */+  /*                      decomposition.                                   */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Error code.  0 means success.                                      */+  /*                                                                       */+  static int+  FT_Outline_Decompose( const FT_Outline*        outline,+                        const FT_Outline_Funcs*  func_interface,+                        void*                    user )+  {+#undef SCALED+#define SCALED( x )  ( ( (x) << shift ) - delta )++    FT_Vector   v_last;+    FT_Vector   v_control;+    FT_Vector   v_start;++    FT_Vector*  point;+    FT_Vector*  limit;+    char*       tags;++    int         error;++    int   n;         /* index of contour in outline     */+    int   first;     /* index of first point in contour */+    char  tag;       /* current point's state           */++    int   shift;+    TPos  delta;+++    if ( !outline || !func_interface )+      return ErrRaster_Invalid_Argument;++    shift = func_interface->shift;+    delta = func_interface->delta;+    first = 0;++    for ( n = 0; n < outline->n_contours; n++ )+    {+      int  last;  /* index of last point in contour */+++      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));++      last  = outline->contours[n];+      if ( last < 0 )+        goto Invalid_Outline;+      limit = outline->points + last;++      v_start   = outline->points[first];+      v_start.x = SCALED( v_start.x );+      v_start.y = SCALED( v_start.y );++      v_last   = outline->points[last];+      v_last.x = SCALED( v_last.x );+      v_last.y = SCALED( v_last.y );++      v_control = v_start;++      point = outline->points + first;+      tags  = outline->tags   + first;+      tag   = FT_CURVE_TAG( tags[0] );++      /* A contour cannot start with a cubic control point! */+      if ( tag == FT_CURVE_TAG_CUBIC )+        goto Invalid_Outline;++      /* check first point to determine origin */+      if ( tag == FT_CURVE_TAG_CONIC )+      {+        /* first point is conic control.  Yes, this happens. */+        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )+        {+          /* start at last point if it is on the curve */+          v_start = v_last;+          limit--;+        }+        else+        {+          /* if both first and last points are conic,         */+          /* start at their middle and record its position    */+          /* for closure                                      */+          v_start.x = ( v_start.x + v_last.x ) / 2;+          v_start.y = ( v_start.y + v_last.y ) / 2;++          v_last = v_start;+        }+        point--;+        tags--;+      }++      FT_TRACE5(( "  move to (%.2f, %.2f)\n",+                  v_start.x / 64.0, v_start.y / 64.0 ));+      error = func_interface->move_to( &v_start, user );+      if ( error )+        goto Exit;++      while ( point < limit )+      {+        point++;+        tags++;++        tag = FT_CURVE_TAG( tags[0] );+        switch ( tag )+        {+        case FT_CURVE_TAG_ON:  /* emit a single line_to */+          {+            FT_Vector  vec;+++            vec.x = SCALED( point->x );+            vec.y = SCALED( point->y );++            FT_TRACE5(( "  line to (%.2f, %.2f)\n",+                        vec.x / 64.0, vec.y / 64.0 ));+            error = func_interface->line_to( &vec, user );+            if ( error )+              goto Exit;+            continue;+          }++        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */+          v_control.x = SCALED( point->x );+          v_control.y = SCALED( point->y );++        Do_Conic:+          if ( point < limit )+          {+            FT_Vector  vec;+            FT_Vector  v_middle;+++            point++;+            tags++;+            tag = FT_CURVE_TAG( tags[0] );++            vec.x = SCALED( point->x );+            vec.y = SCALED( point->y );++            if ( tag == FT_CURVE_TAG_ON )+            {+              FT_TRACE5(( "  conic to (%.2f, %.2f)"+                          " with control (%.2f, %.2f)\n",+                          vec.x / 64.0, vec.y / 64.0,+                          v_control.x / 64.0, v_control.y / 64.0 ));+              error = func_interface->conic_to( &v_control, &vec, user );+              if ( error )+                goto Exit;+              continue;+            }++            if ( tag != FT_CURVE_TAG_CONIC )+              goto Invalid_Outline;++            v_middle.x = ( v_control.x + vec.x ) / 2;+            v_middle.y = ( v_control.y + vec.y ) / 2;++            FT_TRACE5(( "  conic to (%.2f, %.2f)"+                        " with control (%.2f, %.2f)\n",+                        v_middle.x / 64.0, v_middle.y / 64.0,+                        v_control.x / 64.0, v_control.y / 64.0 ));+            error = func_interface->conic_to( &v_control, &v_middle, user );+            if ( error )+              goto Exit;++            v_control = vec;+            goto Do_Conic;+          }++          FT_TRACE5(( "  conic to (%.2f, %.2f)"+                      " with control (%.2f, %.2f)\n",+                      v_start.x / 64.0, v_start.y / 64.0,+                      v_control.x / 64.0, v_control.y / 64.0 ));+          error = func_interface->conic_to( &v_control, &v_start, user );+          goto Close;++        default:  /* FT_CURVE_TAG_CUBIC */+          {+            FT_Vector  vec1, vec2;+++            if ( point + 1 > limit                             ||+                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )+              goto Invalid_Outline;++            point += 2;+            tags  += 2;++            vec1.x = SCALED( point[-2].x );+            vec1.y = SCALED( point[-2].y );++            vec2.x = SCALED( point[-1].x );+            vec2.y = SCALED( point[-1].y );++            if ( point <= limit )+            {+              FT_Vector  vec;+++              vec.x = SCALED( point->x );+              vec.y = SCALED( point->y );++              FT_TRACE5(( "  cubic to (%.2f, %.2f)"+                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",+                          vec.x / 64.0, vec.y / 64.0,+                          vec1.x / 64.0, vec1.y / 64.0,+                          vec2.x / 64.0, vec2.y / 64.0 ));+              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );+              if ( error )+                goto Exit;+              continue;+            }++            FT_TRACE5(( "  cubic to (%.2f, %.2f)"+                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",+                        v_start.x / 64.0, v_start.y / 64.0,+                        vec1.x / 64.0, vec1.y / 64.0,+                        vec2.x / 64.0, vec2.y / 64.0 ));+            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );+            goto Close;+          }+        }+      }++      /* close the contour with a line segment */+      FT_TRACE5(( "  line to (%.2f, %.2f)\n",+                  v_start.x / 64.0, v_start.y / 64.0 ));+      error = func_interface->line_to( &v_start, user );++   Close:+      if ( error )+        goto Exit;++      first = last + 1;+    }++    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));+    return 0;++  Exit:+    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));+    return error;++  Invalid_Outline:+    return ErrRaster_Invalid_Outline;+  }++#endif /* _STANDALONE_ */+++  typedef struct  TBand_+  {+    TPos  min, max;++  } TBand;++    FT_DEFINE_OUTLINE_FUNCS(func_interface,+      (FT_Outline_MoveTo_Func) gray_move_to,+      (FT_Outline_LineTo_Func) gray_line_to,+      (FT_Outline_ConicTo_Func)gray_conic_to,+      (FT_Outline_CubicTo_Func)gray_cubic_to,+      0,+      0+    )++  static int+  gray_convert_glyph_inner( RAS_ARG )+  {++    volatile int  error = 0;++#ifdef FT_CONFIG_OPTION_PIC+      FT_Outline_Funcs func_interface;+      Init_Class_func_interface(&func_interface);+#endif++    if ( ft_setjmp( ras.jump_buffer ) == 0 )+    {+      error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );+      gray_record_cell( RAS_VAR );+    }+    else+      error = ErrRaster_Memory_Overflow;++    return error;+  }+++  static int+  gray_convert_glyph( RAS_ARG )+  {+    TBand            bands[40];+    TBand* volatile  band;+    int volatile     n, num_bands;+    TPos volatile    min, max, max_y;+    FT_BBox*         clip;+++    /* Set up state in the raster object */+    gray_compute_cbox( RAS_VAR );++    /* clip to target bitmap, exit if nothing to do */+    clip = &ras.clip_box;++    if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||+         ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )+      return 0;++    if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;+    if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;++    if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;+    if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;++    ras.count_ex = ras.max_ex - ras.min_ex;+    ras.count_ey = ras.max_ey - ras.min_ey;++    /* set up vertical bands */+    num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );+    if ( num_bands == 0 )+      num_bands = 1;+    if ( num_bands >= 39 )+      num_bands = 39;++    ras.band_shoot = 0;++    min   = ras.min_ey;+    max_y = ras.max_ey;++    for ( n = 0; n < num_bands; n++, min = max )+    {+      max = min + ras.band_size;+      if ( n == num_bands - 1 || max > max_y )+        max = max_y;++      bands[0].min = min;+      bands[0].max = max;+      band         = bands;++      while ( band >= bands )+      {+        TPos  bottom, top, middle;+        int   error;++        {+          PCell  cells_max;+          int    yindex;+          long   cell_start, cell_end, cell_mod;+++          ras.ycells = (PCell*)ras.buffer;+          ras.ycount = band->max - band->min;++          cell_start = sizeof ( PCell ) * ras.ycount;+          cell_mod   = cell_start % sizeof ( TCell );+          if ( cell_mod > 0 )+            cell_start += sizeof ( TCell ) - cell_mod;++          cell_end  = ras.buffer_size;+          cell_end -= cell_end % sizeof( TCell );++          cells_max = (PCell)( (char*)ras.buffer + cell_end );+          ras.cells = (PCell)( (char*)ras.buffer + cell_start );+          if ( ras.cells >= cells_max )+            goto ReduceBands;++          ras.max_cells = cells_max - ras.cells;+          if ( ras.max_cells < 2 )+            goto ReduceBands;++          for ( yindex = 0; yindex < ras.ycount; yindex++ )+            ras.ycells[yindex] = NULL;+        }++        ras.num_cells = 0;+        ras.invalid   = 1;+        ras.min_ey    = band->min;+        ras.max_ey    = band->max;+        ras.count_ey  = band->max - band->min;++        error = gray_convert_glyph_inner( RAS_VAR );++        if ( !error )+        {+          gray_sweep( RAS_VAR_ &ras.target );+          band--;+          continue;+        }+        else if ( error != ErrRaster_Memory_Overflow )+          return 1;++      ReduceBands:+        /* render pool overflow; we will reduce the render band by half */+        bottom = band->min;+        top    = band->max;+        middle = bottom + ( ( top - bottom ) >> 1 );++        /* This is too complex for a single scanline; there must */+        /* be some problems.                                     */+        if ( middle == bottom )+        {+#ifdef FT_DEBUG_LEVEL_TRACE+          FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));+#endif+          return 1;+        }++        if ( bottom-top >= ras.band_size )+          ras.band_shoot++;++        band[1].min = bottom;+        band[1].max = middle;+        band[0].min = middle;+        band[0].max = top;+        band++;+      }+    }++    if ( ras.band_shoot > 8 && ras.band_size > 16 )+      ras.band_size = ras.band_size / 2;++    return 0;+  }+++  static int+  gray_raster_render( PRaster                  raster,+                      const FT_Raster_Params*  params )+  {+    const FT_Outline*  outline    = (const FT_Outline*)params->source;+    const FT_Bitmap*   target_map = params->target;+    PWorker            worker;+++    if ( !raster || !raster->buffer || !raster->buffer_size )+      return ErrRaster_Invalid_Argument;++    if ( !outline )+      return ErrRaster_Invalid_Outline;++    /* return immediately if the outline is empty */+    if ( outline->n_points == 0 || outline->n_contours <= 0 )+      return 0;++    if ( !outline->contours || !outline->points )+      return ErrRaster_Invalid_Outline;++    if ( outline->n_points !=+           outline->contours[outline->n_contours - 1] + 1 )+      return ErrRaster_Invalid_Outline;++    worker = raster->worker;++    /* if direct mode is not set, we must have a target bitmap */+    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )+    {+      if ( !target_map )+        return ErrRaster_Invalid_Argument;++      /* nothing to do */+      if ( !target_map->width || !target_map->rows )+        return 0;++      if ( !target_map->buffer )+        return ErrRaster_Invalid_Argument;+    }++    /* this version does not support monochrome rendering */+    if ( !( params->flags & FT_RASTER_FLAG_AA ) )+      return ErrRaster_Invalid_Mode;++    /* compute clipping box */+    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )+    {+      /* compute clip box from target pixmap */+      ras.clip_box.xMin = 0;+      ras.clip_box.yMin = 0;+      ras.clip_box.xMax = target_map->width;+      ras.clip_box.yMax = target_map->rows;+    }+    else if ( params->flags & FT_RASTER_FLAG_CLIP )+      ras.clip_box = params->clip_box;+    else+    {+      ras.clip_box.xMin = -32768L;+      ras.clip_box.yMin = -32768L;+      ras.clip_box.xMax =  32767L;+      ras.clip_box.yMax =  32767L;+    }++    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );++    ras.outline        = *outline;+    ras.num_cells      = 0;+    ras.invalid        = 1;+    ras.band_size      = raster->band_size;+    ras.num_gray_spans = 0;++    if ( params->flags & FT_RASTER_FLAG_DIRECT )+    {+      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;+      ras.render_span_data = params->user;+    }+    else+    {+      ras.target           = *target_map;+      ras.render_span      = (FT_Raster_Span_Func)gray_render_span;+      ras.render_span_data = &ras;+    }++    return gray_convert_glyph( RAS_VAR );+  }+++  /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/+  /****                         a static object.                   *****/++#ifdef _STANDALONE_++  static int+  gray_raster_new( void*       memory,+                   FT_Raster*  araster )+  {+    static TRaster  the_raster;++    FT_UNUSED( memory );+++    *araster = (FT_Raster)&the_raster;+    FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );++    return 0;+  }+++  static void+  gray_raster_done( FT_Raster  raster )+  {+    /* nothing */+    FT_UNUSED( raster );+  }++#else /* !_STANDALONE_ */++  static int+  gray_raster_new( FT_Memory   memory,+                   FT_Raster*  araster )+  {+    FT_Error  error;+    PRaster   raster = NULL;+++    *araster = 0;+    if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) )+    {+      raster->memory = memory;+      *araster = (FT_Raster)raster;+    }++    return error;+  }+++  static void+  gray_raster_done( FT_Raster  raster )+  {+    FT_Memory  memory = (FT_Memory)((PRaster)raster)->memory;+++    FT_FREE( raster );+  }++#endif /* !_STANDALONE_ */+++  static void+  gray_raster_reset( FT_Raster  raster,+                     char*      pool_base,+                     long       pool_size )+  {+    PRaster  rast = (PRaster)raster;+++    if ( raster )+    {+      if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 )+      {+        PWorker  worker = (PWorker)pool_base;+++        rast->worker      = worker;+        rast->buffer      = pool_base ++                              ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) &+                                ~( sizeof ( TCell ) - 1 ) );+        rast->buffer_size = (long)( ( pool_base + pool_size ) -+                                    (char*)rast->buffer ) &+                                      ~( sizeof ( TCell ) - 1 );+        rast->band_size   = (int)( rast->buffer_size /+                                     ( sizeof ( TCell ) * 8 ) );+      }+      else+      {+        rast->buffer      = NULL;+        rast->buffer_size = 0;+        rast->worker      = NULL;+      }+    }+  }+++  FT_DEFINE_RASTER_FUNCS(ft_grays_raster,+    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Raster_New_Func)     gray_raster_new,+    (FT_Raster_Reset_Func)   gray_raster_reset,+    (FT_Raster_Set_Mode_Func)0,+    (FT_Raster_Render_Func)  gray_raster_render,+    (FT_Raster_Done_Func)    gray_raster_done+  )+++/* END */+++/* Local Variables: */+/* coding: utf-8    */+/* End:             */
+ src/smooth/ftgrays.h view
@@ -0,0 +1,58 @@+/***************************************************************************/+/*                                                                         */+/*  ftgrays.h                                                              */+/*                                                                         */+/*    FreeType smooth renderer declaration                                 */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTGRAYS_H__+#define __FTGRAYS_H__++#ifdef __cplusplus+  extern "C" {+#endif+++#ifdef _STANDALONE_+#include "ftimage.h"+#else+#include <ft2build.h>+#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */+#include FT_IMAGE_H+#endif+++  /*************************************************************************/+  /*                                                                       */+  /* To make ftgrays.h independent from configuration files we check       */+  /* whether FT_EXPORT_VAR has been defined already.                       */+  /*                                                                       */+  /* On some systems and compilers (Win32 mostly), an extra keyword is     */+  /* necessary to compile the library as a DLL.                            */+  /*                                                                       */+#ifndef FT_EXPORT_VAR+#define FT_EXPORT_VAR( x )  extern  x+#endif++  FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_grays_raster;+++#ifdef __cplusplus+  }+#endif++#endif /* __FTGRAYS_H__ */+++/* END */
+ src/smooth/ftsmerrs.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  ftsmerrs.h                                                             */+/*                                                                         */+/*    smooth renderer error codes (specification only).                    */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the smooth renderer error enumeration     */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __FTSMERRS_H__+#define __FTSMERRS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  Smooth_Err_+#define FT_ERR_BASE    FT_Mod_Err_Smooth++#include FT_ERRORS_H++#endif /* __FTSMERRS_H__ */+++/* END */
+ src/smooth/ftsmooth.c view
@@ -0,0 +1,499 @@+/***************************************************************************/+/*                                                                         */+/*  ftsmooth.c                                                             */+/*                                                                         */+/*    Anti-aliasing renderer interface (body).                             */+/*                                                                         */+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_OUTLINE_H+#include "ftsmooth.h"+#include "ftgrays.h"+#include "ftspic.h"++#include "ftsmerrs.h"+++  /* initialize renderer -- init its raster */+  static FT_Error+  ft_smooth_init( FT_Renderer  render )+  {+    FT_Library  library = FT_MODULE_LIBRARY( render );+++    render->clazz->raster_class->raster_reset( render->raster,+                                               library->raster_pool,+                                               library->raster_pool_size );++    return 0;+  }+++  /* sets render-specific mode */+  static FT_Error+  ft_smooth_set_mode( FT_Renderer  render,+                      FT_ULong     mode_tag,+                      FT_Pointer   data )+  {+    /* we simply pass it to the raster */+    return render->clazz->raster_class->raster_set_mode( render->raster,+                                                         mode_tag,+                                                         data );+  }++  /* transform a given glyph image */+  static FT_Error+  ft_smooth_transform( FT_Renderer       render,+                       FT_GlyphSlot      slot,+                       const FT_Matrix*  matrix,+                       const FT_Vector*  delta )+  {+    FT_Error  error = Smooth_Err_Ok;+++    if ( slot->format != render->glyph_format )+    {+      error = Smooth_Err_Invalid_Argument;+      goto Exit;+    }++    if ( matrix )+      FT_Outline_Transform( &slot->outline, matrix );++    if ( delta )+      FT_Outline_Translate( &slot->outline, delta->x, delta->y );++  Exit:+    return error;+  }+++  /* return the glyph's control box */+  static void+  ft_smooth_get_cbox( FT_Renderer   render,+                      FT_GlyphSlot  slot,+                      FT_BBox*      cbox )+  {+    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );++    if ( slot->format == render->glyph_format )+      FT_Outline_Get_CBox( &slot->outline, cbox );+  }+++  /* convert a slot's glyph image into a bitmap */+  static FT_Error+  ft_smooth_render_generic( FT_Renderer       render,+                            FT_GlyphSlot      slot,+                            FT_Render_Mode    mode,+                            const FT_Vector*  origin,+                            FT_Render_Mode    required_mode )+  {+    FT_Error     error;+    FT_Outline*  outline = NULL;+    FT_BBox      cbox;+    FT_UInt      width, height, height_org, width_org, pitch;+    FT_Bitmap*   bitmap;+    FT_Memory    memory;+    FT_Int       hmul = mode == FT_RENDER_MODE_LCD;+    FT_Int       vmul = mode == FT_RENDER_MODE_LCD_V;+    FT_Pos       x_shift, y_shift, x_left, y_top;++    FT_Raster_Params  params;+++    /* check glyph image format */+    if ( slot->format != render->glyph_format )+    {+      error = Smooth_Err_Invalid_Argument;+      goto Exit;+    }++    /* check mode */+    if ( mode != required_mode )+      return Smooth_Err_Cannot_Render_Glyph;++    outline = &slot->outline;++    /* translate the outline to the new origin if needed */+    if ( origin )+      FT_Outline_Translate( outline, origin->x, origin->y );++    /* compute the control box, and grid fit it */+    FT_Outline_Get_CBox( outline, &cbox );++    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );+    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );+    cbox.xMax = FT_PIX_CEIL( cbox.xMax );+    cbox.yMax = FT_PIX_CEIL( cbox.yMax );++    if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )+    {+      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"+                 " xMin = %d, xMax = %d\n",+                 cbox.xMin >> 6, cbox.xMax >> 6 ));+      return Smooth_Err_Raster_Overflow;+    }+    else+      width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );++    if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )+    {+      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"+                 " yMin = %d, yMax = %d\n",+                 cbox.yMin >> 6, cbox.yMax >> 6 ));+      return Smooth_Err_Raster_Overflow;+    }+    else+      height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );++    bitmap = &slot->bitmap;+    memory = render->root.memory;++    width_org  = width;+    height_org = height;++    /* release old bitmap buffer */+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )+    {+      FT_FREE( bitmap->buffer );+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;+    }++    /* allocate new one */+    pitch = width;+    if ( hmul )+    {+      width = width * 3;+      pitch = FT_PAD_CEIL( width, 4 );+    }++    if ( vmul )+      height *= 3;++    x_shift = (FT_Int) cbox.xMin;+    y_shift = (FT_Int) cbox.yMin;+    x_left  = (FT_Int)( cbox.xMin >> 6 );+    y_top   = (FT_Int)( cbox.yMax >> 6 );++#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING++    if ( slot->library->lcd_filter_func )+    {+      FT_Int  extra = slot->library->lcd_extra;+++      if ( hmul )+      {+        x_shift -= 64 * ( extra >> 1 );+        width   += 3 * extra;+        pitch    = FT_PAD_CEIL( width, 4 );+        x_left  -= extra >> 1;+      }++      if ( vmul )+      {+        y_shift -= 64 * ( extra >> 1 );+        height  += 3 * extra;+        y_top   += extra >> 1;+      }+    }++#endif++#if FT_UINT_MAX > 0xFFFFU++    /* Required check is ( pitch * height < FT_ULONG_MAX ),     */+    /* but we care realistic cases only. Always pitch <= width. */+    if ( width > 0x7FFFU || height > 0x7FFFU )+    {+      FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",+                 width, height ));+      return Smooth_Err_Raster_Overflow;+    }++#endif++    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;+    bitmap->num_grays  = 256;+    bitmap->width      = width;+    bitmap->rows       = height;+    bitmap->pitch      = pitch;++    /* translate outline to render it into the bitmap */+    FT_Outline_Translate( outline, -x_shift, -y_shift );++    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )+      goto Exit;++    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;++    /* set up parameters */+    params.target = bitmap;+    params.source = outline;+    params.flags  = FT_RASTER_FLAG_AA;++#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING++    /* implode outline if needed */+    {+      FT_Vector*  points     = outline->points;+      FT_Vector*  points_end = points + outline->n_points;+      FT_Vector*  vec;+++      if ( hmul )+        for ( vec = points; vec < points_end; vec++ )+          vec->x *= 3;++      if ( vmul )+        for ( vec = points; vec < points_end; vec++ )+          vec->y *= 3;+    }++    /* render outline into the bitmap */+    error = render->raster_render( render->raster, &params );++    /* deflate outline if needed */+    {+      FT_Vector*  points     = outline->points;+      FT_Vector*  points_end = points + outline->n_points;+      FT_Vector*  vec;+++      if ( hmul )+        for ( vec = points; vec < points_end; vec++ )+          vec->x /= 3;++      if ( vmul )+        for ( vec = points; vec < points_end; vec++ )+          vec->y /= 3;+    }++    if ( slot->library->lcd_filter_func )+      slot->library->lcd_filter_func( bitmap, mode, slot->library );++#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */++    /* render outline into bitmap */+    error = render->raster_render( render->raster, &params );++    /* expand it horizontally */+    if ( hmul )+    {+      FT_Byte*  line = bitmap->buffer;+      FT_UInt   hh;+++      for ( hh = height_org; hh > 0; hh--, line += pitch )+      {+        FT_UInt   xx;+        FT_Byte*  end = line + width;+++        for ( xx = width_org; xx > 0; xx-- )+        {+          FT_UInt  pixel = line[xx-1];+++          end[-3] = (FT_Byte)pixel;+          end[-2] = (FT_Byte)pixel;+          end[-1] = (FT_Byte)pixel;+          end    -= 3;+        }+      }+    }++    /* expand it vertically */+    if ( vmul )+    {+      FT_Byte*  read  = bitmap->buffer + ( height - height_org ) * pitch;+      FT_Byte*  write = bitmap->buffer;+      FT_UInt   hh;+++      for ( hh = height_org; hh > 0; hh-- )+      {+        ft_memcpy( write, read, pitch );+        write += pitch;++        ft_memcpy( write, read, pitch );+        write += pitch;++        ft_memcpy( write, read, pitch );+        write += pitch;+        read  += pitch;+      }+    }++#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */++    FT_Outline_Translate( outline, x_shift, y_shift );++    /*+     * XXX: on 16bit system, we return an error for huge bitmap+     * to prevent an overflow.+     */+    if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )+      return Smooth_Err_Invalid_Pixel_Size;++    if ( error )+      goto Exit;++    slot->format      = FT_GLYPH_FORMAT_BITMAP;+    slot->bitmap_left = (FT_Int)x_left;+    slot->bitmap_top  = (FT_Int)y_top;++  Exit:+    if ( outline && origin )+      FT_Outline_Translate( outline, -origin->x, -origin->y );++    return error;+  }+++  /* convert a slot's glyph image into a bitmap */+  static FT_Error+  ft_smooth_render( FT_Renderer       render,+                    FT_GlyphSlot      slot,+                    FT_Render_Mode    mode,+                    const FT_Vector*  origin )+  {+    if ( mode == FT_RENDER_MODE_LIGHT )+      mode = FT_RENDER_MODE_NORMAL;++    return ft_smooth_render_generic( render, slot, mode, origin,+                                     FT_RENDER_MODE_NORMAL );+  }+++  /* convert a slot's glyph image into a horizontal LCD bitmap */+  static FT_Error+  ft_smooth_render_lcd( FT_Renderer       render,+                        FT_GlyphSlot      slot,+                        FT_Render_Mode    mode,+                        const FT_Vector*  origin )+  {+    FT_Error  error;++    error = ft_smooth_render_generic( render, slot, mode, origin,+                                      FT_RENDER_MODE_LCD );+    if ( !error )+      slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;++    return error;+  }+++  /* convert a slot's glyph image into a vertical LCD bitmap */+  static FT_Error+  ft_smooth_render_lcd_v( FT_Renderer       render,+                          FT_GlyphSlot      slot,+                          FT_Render_Mode    mode,+                          const FT_Vector*  origin )+  {+    FT_Error  error;++    error = ft_smooth_render_generic( render, slot, mode, origin,+                                      FT_RENDER_MODE_LCD_V );+    if ( !error )+      slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;++    return error;+  }+++  FT_DEFINE_RENDERER(ft_smooth_renderer_class,++      FT_MODULE_RENDERER,+      sizeof( FT_RendererRec ),++      "smooth",+      0x10000L,+      0x20000L,++      0,    /* module specific interface */++      (FT_Module_Constructor)ft_smooth_init,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  0+    ,++    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Renderer_RenderFunc)   ft_smooth_render,+    (FT_Renderer_TransformFunc)ft_smooth_transform,+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,++    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET+  )+++  FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class,+  +      FT_MODULE_RENDERER,+      sizeof( FT_RendererRec ),++      "smooth-lcd",+      0x10000L,+      0x20000L,++      0,    /* module specific interface */++      (FT_Module_Constructor)ft_smooth_init,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  0+    ,++    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd,+    (FT_Renderer_TransformFunc)ft_smooth_transform,+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,++    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET+  )++  FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class,++      FT_MODULE_RENDERER,+      sizeof( FT_RendererRec ),++      "smooth-lcdv",+      0x10000L,+      0x20000L,++      0,    /* module specific interface */++      (FT_Module_Constructor)ft_smooth_init,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  0+    ,++    FT_GLYPH_FORMAT_OUTLINE,++    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd_v,+    (FT_Renderer_TransformFunc)ft_smooth_transform,+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,++    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET+  )+++/* END */
+ src/smooth/ftsmooth.h view
@@ -0,0 +1,49 @@+/***************************************************************************/+/*                                                                         */+/*  ftsmooth.h                                                             */+/*                                                                         */+/*    Anti-aliasing renderer interface (specification).                    */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTSMOOTH_H__+#define __FTSMOOTH_H__+++#include <ft2build.h>+#include FT_RENDER_H+++FT_BEGIN_HEADER+++#ifndef FT_CONFIG_OPTION_NO_STD_RASTER+  FT_DECLARE_RENDERER( ft_std_renderer_class )+#endif++#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER+  FT_DECLARE_RENDERER( ft_smooth_renderer_class )++  FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class )++  FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class )+#endif++++FT_END_HEADER++#endif /* __FTSMOOTH_H__ */+++/* END */
+ src/smooth/ftspic.c view
@@ -0,0 +1,98 @@+/***************************************************************************/+/*                                                                         */+/*  ftspic.c                                                               */+/*                                                                         */+/*    The FreeType position independent code services for smooth module.   */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "ftspic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from ftgrays.c */+  void FT_Init_Class_ft_grays_raster(FT_Raster_Funcs*);++  void+  ft_smooth_renderer_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->smooth )+    {+      SmoothPIC* container = (SmoothPIC*)pic_container->smooth;+      if(--container->ref_count)+        return;+      FT_FREE( container );+      pic_container->smooth = NULL;+    }+  }+++  FT_Error+  ft_smooth_renderer_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error         = Smooth_Err_Ok;+    SmoothPIC*         container;+    FT_Memory          memory        = library->memory;+++    /* since this function also serve smooth_lcd and smooth_lcdv renderers, +       it implements reference counting */+    if(pic_container->smooth)+    {+      ((SmoothPIC*)pic_container->smooth)->ref_count++;+      return error;+    }++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof(*container) );+    pic_container->smooth = container;+    container->ref_count = 1;++    /* initialize pointer table - this is how the module usually expects this data */+    FT_Init_Class_ft_grays_raster(&container->ft_grays_raster);+/*Exit:*/+    if(error)+      ft_smooth_renderer_class_pic_free(library);+    return error;+  }++  /* re-route these init and free functions to the above functions */+  FT_Error ft_smooth_lcd_renderer_class_pic_init(FT_Library library)+  {+    return ft_smooth_renderer_class_pic_init(library);+  }+  void ft_smooth_lcd_renderer_class_pic_free(FT_Library library)+  {+    ft_smooth_renderer_class_pic_free(library);+  }+  FT_Error ft_smooth_lcdv_renderer_class_pic_init(FT_Library library)+  {+    return ft_smooth_renderer_class_pic_init(library);+  }+  void ft_smooth_lcdv_renderer_class_pic_free(FT_Library library)+  {+    ft_smooth_renderer_class_pic_free(library);+  }++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/smooth/ftspic.h view
@@ -0,0 +1,50 @@+/***************************************************************************/+/*                                                                         */+/*  ftspic.h                                                               */+/*                                                                         */+/*    The FreeType position independent code services for smooth module.   */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __FTSPIC_H__+#define __FTSPIC_H__++  +FT_BEGIN_HEADER++#include FT_INTERNAL_PIC_H++#ifndef FT_CONFIG_OPTION_PIC+#define FT_GRAYS_RASTER_GET        ft_grays_raster++#else /* FT_CONFIG_OPTION_PIC */++  typedef struct SmoothPIC_+  {+    int ref_count;+    FT_Raster_Funcs ft_grays_raster;+  } SmoothPIC;++#define GET_PIC(lib)               ((SmoothPIC*)((lib)->pic_container.smooth))+#define FT_GRAYS_RASTER_GET        (GET_PIC(library)->ft_grays_raster)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __FTSPIC_H__ */+++/* END */
+ src/smooth/smooth.c view
@@ -0,0 +1,27 @@+/***************************************************************************/+/*                                                                         */+/*  smooth.c                                                               */+/*                                                                         */+/*    FreeType anti-aliasing rasterer module component (body only).        */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "ftspic.c"+#include "ftgrays.c"+#include "ftsmooth.c"+++/* END */
+ src/truetype/truetype.c view
@@ -0,0 +1,37 @@+/***************************************************************************/+/*                                                                         */+/*  truetype.c                                                             */+/*                                                                         */+/*    FreeType TrueType driver component (body only).                      */+/*                                                                         */+/*  Copyright 1996-2001, 2004, 2006 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "ttpic.c"+#include "ttdriver.c"   /* driver interface    */+#include "ttpload.c"    /* tables loader       */+#include "ttgload.c"    /* glyph loader        */+#include "ttobjs.c"     /* object manager      */++#ifdef TT_USE_BYTECODE_INTERPRETER+#include "ttinterp.c"+#endif++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include "ttgxvar.c"    /* gx distortable font */+#endif+++/* END */
+ src/truetype/ttdriver.c view
@@ -0,0 +1,487 @@+/***************************************************************************/+/*                                                                         */+/*  ttdriver.c                                                             */+/*                                                                         */+/*    TrueType font driver implementation (body).                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009    */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include FT_SERVICE_XFREE86_NAME_H++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include FT_MULTIPLE_MASTERS_H+#include FT_SERVICE_MULTIPLE_MASTERS_H+#endif++#include FT_SERVICE_TRUETYPE_ENGINE_H+#include FT_SERVICE_TRUETYPE_GLYF_H++#include "ttdriver.h"+#include "ttgload.h"+#include "ttpload.h"++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include "ttgxvar.h"+#endif++#include "tterrors.h"++#include "ttpic.h"++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttdriver+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                          F A C E S                              ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#undef  PAIR_TAG+#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \+                                     (FT_ULong)right        )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_get_kerning                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A driver method used to return the kerning vector between two      */+  /*    glyphs of the same face.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to the source face object.                 */+  /*                                                                       */+  /*    left_glyph  :: The index of the left glyph in the kern pair.       */+  /*                                                                       */+  /*    right_glyph :: The index of the right glyph in the kern pair.      */+  /*                                                                       */+  /* <Output>                                                              */+  /*    kerning     :: The kerning vector.  This is in font units for      */+  /*                   scalable formats, and in pixels for fixed-sizes     */+  /*                   formats.                                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only horizontal layouts (left-to-right & right-to-left) are        */+  /*    supported by this function.  Other layouts, or more sophisticated  */+  /*    kernings, are out of scope of this method (the basic driver        */+  /*    interface is meant to be simple).                                  */+  /*                                                                       */+  /*    They can be implemented by format-specific interfaces.             */+  /*                                                                       */+  static FT_Error+  tt_get_kerning( FT_Face     ttface,          /* TT_Face */+                  FT_UInt     left_glyph,+                  FT_UInt     right_glyph,+                  FT_Vector*  kerning )+  {+    TT_Face       face = (TT_Face)ttface;+    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;+++    kerning->x = 0;+    kerning->y = 0;++    if ( sfnt )+      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );++    return 0;+  }+++#undef PAIR_TAG+++  static FT_Error+  tt_get_advances( FT_Face    ttface,+                   FT_UInt    start,+                   FT_UInt    count,+                   FT_Int32   flags,+                   FT_Fixed  *advances )+  {+    FT_UInt  nn;+    TT_Face  face  = (TT_Face) ttface;+    FT_Bool  check = FT_BOOL(+                       !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) );+++    /* XXX: TODO: check for sbits */++    if ( flags & FT_LOAD_VERTICAL_LAYOUT )+    {+      for ( nn = 0; nn < count; nn++ )+      {+        FT_Short   tsb;+        FT_UShort  ah;+++        TT_Get_VMetrics( face, start + nn, check, &tsb, &ah );+        advances[nn] = ah;+      }+    }+    else+    {+      for ( nn = 0; nn < count; nn++ )+      {+        FT_Short   lsb;+        FT_UShort  aw;+++        TT_Get_HMetrics( face, start + nn, check, &lsb, &aw );+        advances[nn] = aw;+      }+    }++    return TT_Err_Ok;+  }++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                           S I Z E S                             ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  static FT_Error+  tt_size_select( FT_Size   size,+                  FT_ULong  strike_index )+  {+    TT_Face   ttface = (TT_Face)size->face;+    TT_Size   ttsize = (TT_Size)size;+    FT_Error  error  = TT_Err_Ok;+++    ttsize->strike_index = strike_index;++    if ( FT_IS_SCALABLE( size->face ) )+    {+      /* use the scaled metrics, even when tt_size_reset fails */+      FT_Select_Metrics( size->face, strike_index );++      tt_size_reset( ttsize );+    }+    else+    {+      SFNT_Service      sfnt    = (SFNT_Service) ttface->sfnt;+      FT_Size_Metrics*  metrics = &size->metrics;+++      error = sfnt->load_strike_metrics( ttface, strike_index, metrics );+      if ( error )+        ttsize->strike_index = 0xFFFFFFFFUL;+    }++    return error;+  }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */+++  static FT_Error+  tt_size_request( FT_Size          size,+                   FT_Size_Request  req )+  {+    TT_Size   ttsize = (TT_Size)size;+    FT_Error  error  = TT_Err_Ok;+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++    if ( FT_HAS_FIXED_SIZES( size->face ) )+    {+      TT_Face       ttface = (TT_Face)size->face;+      SFNT_Service  sfnt   = (SFNT_Service) ttface->sfnt;+      FT_ULong      strike_index;+++      error = sfnt->set_sbit_strike( ttface, req, &strike_index );++      if ( error )+        ttsize->strike_index = 0xFFFFFFFFUL;+      else+        return tt_size_select( size, strike_index );+    }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */++    FT_Request_Metrics( size->face, req );++    if ( FT_IS_SCALABLE( size->face ) )+      error = tt_size_reset( ttsize );++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Load_Glyph                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A driver method used to load a glyph within a given glyph slot.    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    slot        :: A handle to the target slot object where the glyph  */+  /*                   will be loaded.                                     */+  /*                                                                       */+  /*    size        :: A handle to the source face size at which the glyph */+  /*                   must be scaled, loaded, etc.                        */+  /*                                                                       */+  /*    glyph_index :: The index of the glyph in the font file.            */+  /*                                                                       */+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */+  /*                   FT_LOAD_XXX constants can be used to control the    */+  /*                   glyph loading process (e.g., whether the outline    */+  /*                   should be scaled, whether to load bitmaps or not,   */+  /*                   whether to hint the outline, etc).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  Load_Glyph( FT_GlyphSlot  ttslot,         /* TT_GlyphSlot */+              FT_Size       ttsize,         /* TT_Size      */+              FT_UInt       glyph_index,+              FT_Int32      load_flags )+  {+    TT_GlyphSlot  slot = (TT_GlyphSlot)ttslot;+    TT_Size       size = (TT_Size)ttsize;+    FT_Face       face = ttslot->face;+    FT_Error      error;+++    if ( !slot )+      return TT_Err_Invalid_Slot_Handle;++    if ( !size )+      return TT_Err_Invalid_Size_Handle;++    if ( !face )+      return TT_Err_Invalid_Argument;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( glyph_index >= (FT_UInt)face->num_glyphs &&+         !face->internal->incremental_interface   )+#else+    if ( glyph_index >= (FT_UInt)face->num_glyphs )+#endif+      return TT_Err_Invalid_Argument;++    if ( load_flags & FT_LOAD_NO_HINTING )+    {+      /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT   */+      /* are necessary to disable hinting for tricky fonts */          ++      if ( FT_IS_TRICKY( face ) )+        load_flags &= ~FT_LOAD_NO_HINTING;++      if ( load_flags & FT_LOAD_NO_AUTOHINT )+        load_flags |= FT_LOAD_NO_HINTING;+    }++    if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )+    {+      load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;++      if ( !FT_IS_TRICKY( face ) )+        load_flags |= FT_LOAD_NO_HINTING;+    }++    /* now load the glyph outline if necessary */+    error = TT_Load_Glyph( size, slot, glyph_index, load_flags );++    /* force drop-out mode to 2 - irrelevant now */+    /* slot->outline.dropout_mode = 2; */++    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /****                                                                 ****/+  /****                                                                 ****/+  /****                D R I V E R  I N T E R F A C E                   ****/+  /****                                                                 ****/+  /****                                                                 ****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+  FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters,+    (FT_Get_MM_Func)        NULL,+    (FT_Set_MM_Design_Func) NULL,+    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,+    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,+    (FT_Set_Var_Design_Func)TT_Set_Var_Design+  )+#endif++  static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =+  {+#ifdef TT_USE_BYTECODE_INTERPRETER++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED+#else+    FT_TRUETYPE_ENGINE_TYPE_PATENTED+#endif++#else /* !TT_USE_BYTECODE_INTERPRETER */++    FT_TRUETYPE_ENGINE_TYPE_NONE++#endif /* TT_USE_BYTECODE_INTERPRETER */+  };++  FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf,+    (TT_Glyf_GetLocationFunc)tt_face_get_location+  )++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+  FT_DEFINE_SERVICEDESCREC4(tt_services,+    FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TRUETYPE,+    FT_SERVICE_ID_MULTI_MASTERS,   &FT_TT_SERVICE_GX_MULTI_MASTERS_GET,+    FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,+    FT_SERVICE_ID_TT_GLYF,         &FT_TT_SERVICE_TRUETYPE_GLYF_GET+  )+#else+  FT_DEFINE_SERVICEDESCREC3(tt_services,+    FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TRUETYPE,+    FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,+    FT_SERVICE_ID_TT_GLYF,         &FT_TT_SERVICE_TRUETYPE_GLYF_GET+  )+#endif++  FT_CALLBACK_DEF( FT_Module_Interface )+  tt_get_interface( FT_Module    driver,    /* TT_Driver */+                    const char*  tt_interface )+  {+    FT_Module_Interface  result;+    FT_Module            sfntd;+    SFNT_Service         sfnt;++    result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface );+    if ( result != NULL )+      return result;++    if ( !driver )+      return NULL;++    /* only return the default interface from the SFNT module */+    sfntd = FT_Get_Module( driver->library, "sfnt" );+    if ( sfntd )+    {+      sfnt = (SFNT_Service)( sfntd->clazz->module_interface );+      if ( sfnt )+        return sfnt->get_interface( driver, tt_interface );+    }++    return 0;+  }+++  /* The FT_DriverInterface structure is defined in ftdriver.h. */++#ifdef TT_USE_BYTECODE_INTERPRETER+#define TT_HINTER_FLAG   FT_MODULE_DRIVER_HAS_HINTER+#else+#define TT_HINTER_FLAG   0+#endif++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS+#define TT_SIZE_SELECT    tt_size_select+#else+#define TT_SIZE_SELECT    0+#endif++  FT_DEFINE_DRIVER(tt_driver_class,+  +    +      FT_MODULE_FONT_DRIVER        |+      FT_MODULE_DRIVER_SCALABLE    |+      TT_HINTER_FLAG,++      sizeof ( TT_DriverRec ),++      "truetype",      /* driver name                           */+      0x10000L,        /* driver version == 1.0                 */+      0x20000L,        /* driver requires FreeType 2.0 or above */++      (void*)0,        /* driver specific interface */++      tt_driver_init,+      tt_driver_done,+      tt_get_interface,++    sizeof ( TT_FaceRec ),+    sizeof ( TT_SizeRec ),+    sizeof ( FT_GlyphSlotRec ),++    tt_face_init,+    tt_face_done,+    tt_size_init,+    tt_size_done,+    tt_slot_init,+    0,                      /* FT_Slot_DoneFunc */++    ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */+    ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */++    Load_Glyph,++    tt_get_kerning,+    0,                      /* FT_Face_AttachFunc      */+    tt_get_advances,++    tt_size_request,+    TT_SIZE_SELECT+  )+++/* END */
+ src/truetype/ttdriver.h view
@@ -0,0 +1,38 @@+/***************************************************************************/+/*                                                                         */+/*  ttdriver.h                                                             */+/*                                                                         */+/*    High-level TrueType driver interface (specification).                */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTDRIVER_H__+#define __TTDRIVER_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER+++  FT_DECLARE_DRIVER( tt_driver_class )+++FT_END_HEADER++#endif /* __TTDRIVER_H__ */+++/* END */
+ src/truetype/tterrors.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  tterrors.h                                                             */+/*                                                                         */+/*    TrueType error codes (specification only).                           */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the TrueType error enumeration            */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __TTERRORS_H__+#define __TTERRORS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  TT_Err_+#define FT_ERR_BASE    FT_Mod_Err_TrueType++#include FT_ERRORS_H++#endif /* __TTERRORS_H__ */++/* END */
+ src/truetype/ttgload.c view
@@ -0,0 +1,2147 @@+/***************************************************************************/+/*                                                                         */+/*  ttgload.c                                                              */+/*                                                                         */+/*    TrueType Glyph Loader (body).                                        */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include FT_TRUETYPE_TAGS_H+#include FT_OUTLINE_H++#include "ttgload.h"+#include "ttpload.h"++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include "ttgxvar.h"+#endif++#include "tterrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttgload+++  /*************************************************************************/+  /*                                                                       */+  /* Composite font flags.                                                 */+  /*                                                                       */+#define ARGS_ARE_WORDS             0x0001+#define ARGS_ARE_XY_VALUES         0x0002+#define ROUND_XY_TO_GRID           0x0004+#define WE_HAVE_A_SCALE            0x0008+/* reserved                        0x0010 */+#define MORE_COMPONENTS            0x0020+#define WE_HAVE_AN_XY_SCALE        0x0040+#define WE_HAVE_A_2X2              0x0080+#define WE_HAVE_INSTR              0x0100+#define USE_MY_METRICS             0x0200+#define OVERLAP_COMPOUND           0x0400+#define SCALED_COMPONENT_OFFSET    0x0800+#define UNSCALED_COMPONENT_OFFSET  0x1000+++  /*************************************************************************/+  /*                                                                       */+  /* Returns the horizontal metrics in font units for a given glyph.  If   */+  /* `check' is true, take care of monospaced fonts by returning the       */+  /* advance width maximum.                                                */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  TT_Get_HMetrics( TT_Face     face,+                   FT_UInt     idx,+                   FT_Bool     check,+                   FT_Short*   lsb,+                   FT_UShort*  aw )+  {+    ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );++    if ( check && face->postscript.isFixedPitch )+      *aw = face->horizontal.advance_Width_Max;++    FT_TRACE5(( "  advance width (font units): %d\n", *aw ));+    FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Returns the vertical metrics in font units for a given glyph.         */+  /* Greg Hitchcock from Microsoft told us that if there were no `vmtx'    */+  /* table, typoAscender/Descender from the `OS/2' table would be used     */+  /* instead, and if there were no `OS/2' table, use ascender/descender    */+  /* from the `hhea' table.  But that is not what Microsoft's rasterizer   */+  /* apparently does: It uses the ppem value as the advance height, and    */+  /* sets the top side bearing to be zero.                                 */+  /*                                                                       */+  /* The monospace `check' is probably not meaningful here, but we leave   */+  /* it in for a consistent interface.                                     */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  TT_Get_VMetrics( TT_Face     face,+                   FT_UInt     idx,+                   FT_Bool     check,+                   FT_Short*   tsb,+                   FT_UShort*  ah )+  {+    FT_UNUSED( check );++    if ( face->vertical_info )+      ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );++#if 1             /* Empirically determined, at variance with what MS said */++    else+    {+      *tsb = 0;+      *ah  = face->root.units_per_EM;+    }++#else      /* This is what MS said to do.  It isn't what they do, however. */++    else if ( face->os2.version != 0xFFFFU )+    {+      *tsb = face->os2.sTypoAscender;+      *ah  = face->os2.sTypoAscender - face->os2.sTypoDescender;+    }+    else+    {+      *tsb = face->horizontal.Ascender;+      *ah  = face->horizontal.Ascender - face->horizontal.Descender;+    }++#endif++    FT_TRACE5(( "  advance height (font units): %d\n", *ah ));+    FT_TRACE5(( "  top side bearing (font units): %d\n", *tsb ));+  }+++  static void+  tt_get_metrics( TT_Loader  loader,+                  FT_UInt    glyph_index )+  {+    TT_Face  face = (TT_Face)loader->face;++    FT_Short   left_bearing = 0, top_bearing = 0;+    FT_UShort  advance_width = 0, advance_height = 0;+++    TT_Get_HMetrics( face, glyph_index,+                     (FT_Bool)!( loader->load_flags &+                                 FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),+                     &left_bearing,+                     &advance_width );+    TT_Get_VMetrics( face, glyph_index,+                     (FT_Bool)!( loader->load_flags &+                                 FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),+                     &top_bearing,+                     &advance_height );++    loader->left_bearing = left_bearing;+    loader->advance      = advance_width;+    loader->top_bearing  = top_bearing;+    loader->vadvance     = advance_height;++    if ( !loader->linear_def )+    {+      loader->linear_def = 1;+      loader->linear     = advance_width;+    }+  }+++#ifdef FT_CONFIG_OPTION_INCREMENTAL++  static void+  tt_get_metrics_incr_overrides( TT_Loader  loader,+                                 FT_UInt    glyph_index )+  {+    TT_Face  face = (TT_Face)loader->face;++    FT_Short   left_bearing = 0, top_bearing = 0;+    FT_UShort  advance_width = 0, advance_height = 0;+++    /* If this is an incrementally loaded font check whether there are */+    /* overriding metrics for this glyph.                              */+    if ( face->root.internal->incremental_interface                           &&+         face->root.internal->incremental_interface->funcs->get_glyph_metrics )+    {+      FT_Incremental_MetricsRec  metrics;+      FT_Error                   error;+++      metrics.bearing_x = loader->left_bearing;+      metrics.bearing_y = 0;+      metrics.advance   = loader->advance;+      metrics.advance_v = 0;++      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(+                face->root.internal->incremental_interface->object,+                glyph_index, FALSE, &metrics );+      if ( error )+        goto Exit;++      left_bearing  = (FT_Short)metrics.bearing_x;+      advance_width = (FT_UShort)metrics.advance;++#if 0++      /* GWW: Do I do the same for vertical metrics? */+      metrics.bearing_x = 0;+      metrics.bearing_y = loader->top_bearing;+      metrics.advance   = loader->vadvance;++      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(+                face->root.internal->incremental_interface->object,+                glyph_index, TRUE, &metrics );+      if ( error )+        goto Exit;++      top_bearing    = (FT_Short)metrics.bearing_y;+      advance_height = (FT_UShort)metrics.advance;++#endif /* 0 */++      loader->left_bearing = left_bearing;+      loader->advance      = advance_width;+      loader->top_bearing  = top_bearing;+      loader->vadvance     = advance_height;++      if ( !loader->linear_def )+      {+        loader->linear_def = 1;+        loader->linear     = advance_width;+      }+    }++  Exit:+    return;+  }++#endif /* FT_CONFIG_OPTION_INCREMENTAL */+++  /*************************************************************************/+  /*                                                                       */+  /* Translates an array of coordinates.                                   */+  /*                                                                       */+  static void+  translate_array( FT_UInt     n,+                   FT_Vector*  coords,+                   FT_Pos      delta_x,+                   FT_Pos      delta_y )+  {+    FT_UInt  k;+++    if ( delta_x )+      for ( k = 0; k < n; k++ )+        coords[k].x += delta_x;++    if ( delta_y )+      for ( k = 0; k < n; k++ )+        coords[k].y += delta_y;+  }+++#undef  IS_HINTED+#define IS_HINTED( flags )  ( ( flags & FT_LOAD_NO_HINTING ) == 0 )+++  /*************************************************************************/+  /*                                                                       */+  /* The following functions are used by default with TrueType fonts.      */+  /* However, they can be replaced by alternatives if we need to support   */+  /* TrueType-compressed formats (like MicroType) in the future.           */+  /*                                                                       */+  /*************************************************************************/++  FT_CALLBACK_DEF( FT_Error )+  TT_Access_Glyph_Frame( TT_Loader  loader,+                         FT_UInt    glyph_index,+                         FT_ULong   offset,+                         FT_UInt    byte_count )+  {+    FT_Error   error;+    FT_Stream  stream = loader->stream;++    /* for non-debug mode */+    FT_UNUSED( glyph_index );+++    FT_TRACE4(( "Glyph %ld\n", glyph_index ));++    /* the following line sets the `error' variable through macros! */+    if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )+      return error;++    loader->cursor = stream->cursor;+    loader->limit  = stream->limit;++    return TT_Err_Ok;+  }+++  FT_CALLBACK_DEF( void )+  TT_Forget_Glyph_Frame( TT_Loader  loader )+  {+    FT_Stream  stream = loader->stream;+++    FT_FRAME_EXIT();+  }+++  FT_CALLBACK_DEF( FT_Error )+  TT_Load_Glyph_Header( TT_Loader  loader )+  {+    FT_Byte*  p     = loader->cursor;+    FT_Byte*  limit = loader->limit;+++    if ( p + 10 > limit )+      return TT_Err_Invalid_Outline;++    loader->n_contours = FT_NEXT_SHORT( p );++    loader->bbox.xMin = FT_NEXT_SHORT( p );+    loader->bbox.yMin = FT_NEXT_SHORT( p );+    loader->bbox.xMax = FT_NEXT_SHORT( p );+    loader->bbox.yMax = FT_NEXT_SHORT( p );++    FT_TRACE5(( "  # of contours: %d\n", loader->n_contours ));+    FT_TRACE5(( "  xMin: %4d  xMax: %4d\n", loader->bbox.xMin,+                                            loader->bbox.xMax ));+    FT_TRACE5(( "  yMin: %4d  yMax: %4d\n", loader->bbox.yMin,+                                            loader->bbox.yMax ));+    loader->cursor = p;++    return TT_Err_Ok;+  }+++  FT_CALLBACK_DEF( FT_Error )+  TT_Load_Simple_Glyph( TT_Loader  load )+  {+    FT_Error        error;+    FT_Byte*        p          = load->cursor;+    FT_Byte*        limit      = load->limit;+    FT_GlyphLoader  gloader    = load->gloader;+    FT_Int          n_contours = load->n_contours;+    FT_Outline*     outline;+    TT_Face         face       = (TT_Face)load->face;+    FT_UShort       n_ins;+    FT_Int          n_points;++    FT_Byte         *flag, *flag_limit;+    FT_Byte         c, count;+    FT_Vector       *vec, *vec_limit;+    FT_Pos          x;+    FT_Short        *cont, *cont_limit, prev_cont;+    FT_Int          xy_size = 0;+++    /* check that we can add the contours to the glyph */+    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );+    if ( error )+      goto Fail;++    /* reading the contours' endpoints & number of points */+    cont       = gloader->current.outline.contours;+    cont_limit = cont + n_contours;++    /* check space for contours array + instructions count */+    if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )+      goto Invalid_Outline;++    prev_cont = FT_NEXT_USHORT( p );++    if ( n_contours > 0 )+      cont[0] = prev_cont;++    for ( cont++; cont < cont_limit; cont++ )+    {+      cont[0] = FT_NEXT_USHORT( p );+      if ( cont[0] <= prev_cont )+      {+        /* unordered contours: this is invalid */+        error = TT_Err_Invalid_Table;+        goto Fail;+      }+      prev_cont = cont[0];+    }++    n_points = 0;+    if ( n_contours > 0 )+    {+      n_points = cont[-1] + 1;+      if ( n_points < 0 )+        goto Invalid_Outline;+    }++    /* note that we will add four phantom points later */+    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );+    if ( error )+      goto Fail;++    /* we'd better check the contours table right now */+    outline = &gloader->current.outline;++    for ( cont = outline->contours + 1; cont < cont_limit; cont++ )+      if ( cont[-1] >= cont[0] )+        goto Invalid_Outline;++    /* reading the bytecode instructions */+    load->glyph->control_len  = 0;+    load->glyph->control_data = 0;++    if ( p + 2 > limit )+      goto Invalid_Outline;++    n_ins = FT_NEXT_USHORT( p );++    FT_TRACE5(( "  Instructions size: %u\n", n_ins ));++    if ( n_ins > face->max_profile.maxSizeOfInstructions )+    {+      FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",+                  n_ins ));+      error = TT_Err_Too_Many_Hints;+      goto Fail;+    }++    if ( ( limit - p ) < n_ins )+    {+      FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));+      error = TT_Err_Too_Many_Hints;+      goto Fail;+    }++#ifdef TT_USE_BYTECODE_INTERPRETER++    if ( IS_HINTED( load->load_flags ) )+    {+      load->glyph->control_len  = n_ins;+      load->glyph->control_data = load->exec->glyphIns;++      FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );+    }++#endif /* TT_USE_BYTECODE_INTERPRETER */++    p += n_ins;++    /* reading the point tags */+    flag       = (FT_Byte*)outline->tags;+    flag_limit = flag + n_points;++    FT_ASSERT( flag != NULL );++    while ( flag < flag_limit )+    {+      if ( p + 1 > limit )+        goto Invalid_Outline;++      *flag++ = c = FT_NEXT_BYTE( p );+      if ( c & 8 )+      {+        if ( p + 1 > limit )+          goto Invalid_Outline;++        count = FT_NEXT_BYTE( p );+        if ( flag + (FT_Int)count > flag_limit )+          goto Invalid_Outline;++        for ( ; count > 0; count-- )+          *flag++ = c;+      }+    }++    /* reading the X coordinates */++    vec       = outline->points;+    vec_limit = vec + n_points;+    flag      = (FT_Byte*)outline->tags;+    x         = 0;++    if ( p + xy_size > limit )+      goto Invalid_Outline;++    for ( ; vec < vec_limit; vec++, flag++ )+    {+      FT_Pos   y = 0;+      FT_Byte  f = *flag;+++      if ( f & 2 )+      {+        if ( p + 1 > limit )+          goto Invalid_Outline;++        y = (FT_Pos)FT_NEXT_BYTE( p );+        if ( ( f & 16 ) == 0 )+          y = -y;+      }+      else if ( ( f & 16 ) == 0 )+      {+        if ( p + 2 > limit )+          goto Invalid_Outline;++        y = (FT_Pos)FT_NEXT_SHORT( p );+      }++      x     += y;+      vec->x = x;+      /* the cast is for stupid compilers */+      *flag  = (FT_Byte)( f & ~( 2 | 16 ) );+    }++    /* reading the Y coordinates */++    vec       = gloader->current.outline.points;+    vec_limit = vec + n_points;+    flag      = (FT_Byte*)outline->tags;+    x         = 0;++    for ( ; vec < vec_limit; vec++, flag++ )+    {+      FT_Pos   y = 0;+      FT_Byte  f = *flag;+++      if ( f & 4 )+      {+        if ( p + 1 > limit )+          goto Invalid_Outline;++        y = (FT_Pos)FT_NEXT_BYTE( p );+        if ( ( f & 32 ) == 0 )+          y = -y;+      }+      else if ( ( f & 32 ) == 0 )+      {+        if ( p + 2 > limit )+          goto Invalid_Outline;++        y = (FT_Pos)FT_NEXT_SHORT( p );+      }++      x     += y;+      vec->y = x;+      /* the cast is for stupid compilers */+      *flag  = (FT_Byte)( f & FT_CURVE_TAG_ON );+    }++    outline->n_points   = (FT_UShort)n_points;+    outline->n_contours = (FT_Short) n_contours;++    load->cursor = p;++  Fail:+    return error;++  Invalid_Outline:+    error = TT_Err_Invalid_Outline;+    goto Fail;+  }+++  FT_CALLBACK_DEF( FT_Error )+  TT_Load_Composite_Glyph( TT_Loader  loader )+  {+    FT_Error        error;+    FT_Byte*        p       = loader->cursor;+    FT_Byte*        limit   = loader->limit;+    FT_GlyphLoader  gloader = loader->gloader;+    FT_SubGlyph     subglyph;+    FT_UInt         num_subglyphs;+++    num_subglyphs = 0;++    do+    {+      FT_Fixed  xx, xy, yy, yx;+      FT_UInt   count;+++      /* check that we can load a new subglyph */+      error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );+      if ( error )+        goto Fail;++      /* check space */+      if ( p + 4 > limit )+        goto Invalid_Composite;++      subglyph = gloader->current.subglyphs + num_subglyphs;++      subglyph->arg1 = subglyph->arg2 = 0;++      subglyph->flags = FT_NEXT_USHORT( p );+      subglyph->index = FT_NEXT_USHORT( p );++      /* check space */+      count = 2;+      if ( subglyph->flags & ARGS_ARE_WORDS )+        count += 2;+      if ( subglyph->flags & WE_HAVE_A_SCALE )+        count += 2;+      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )+        count += 4;+      else if ( subglyph->flags & WE_HAVE_A_2X2 )+        count += 8;++      if ( p + count > limit )+        goto Invalid_Composite;++      /* read arguments */+      if ( subglyph->flags & ARGS_ARE_WORDS )+      {+        subglyph->arg1 = FT_NEXT_SHORT( p );+        subglyph->arg2 = FT_NEXT_SHORT( p );+      }+      else+      {+        subglyph->arg1 = FT_NEXT_CHAR( p );+        subglyph->arg2 = FT_NEXT_CHAR( p );+      }++      /* read transform */+      xx = yy = 0x10000L;+      xy = yx = 0;++      if ( subglyph->flags & WE_HAVE_A_SCALE )+      {+        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+        yy = xx;+      }+      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )+      {+        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+        yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+      }+      else if ( subglyph->flags & WE_HAVE_A_2X2 )+      {+        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+        yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+        xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+        yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;+      }++      subglyph->transform.xx = xx;+      subglyph->transform.xy = xy;+      subglyph->transform.yx = yx;+      subglyph->transform.yy = yy;++      num_subglyphs++;++    } while ( subglyph->flags & MORE_COMPONENTS );++    gloader->current.num_subglyphs = num_subglyphs;++#ifdef TT_USE_BYTECODE_INTERPRETER++    {+      FT_Stream  stream = loader->stream;+++      /* we must undo the FT_FRAME_ENTER in order to point */+      /* to the composite instructions, if we find some.   */+      /* We will process them later.                       */+      /*                                                   */+      loader->ins_pos = (FT_ULong)( FT_STREAM_POS() ++                                    p - limit );+    }++#endif++    loader->cursor = p;++  Fail:+    return error;++  Invalid_Composite:+    error = TT_Err_Invalid_Composite;+    goto Fail;+  }+++  FT_LOCAL_DEF( void )+  TT_Init_Glyph_Loading( TT_Face  face )+  {+    face->access_glyph_frame   = TT_Access_Glyph_Frame;+    face->read_glyph_header    = TT_Load_Glyph_Header;+    face->read_simple_glyph    = TT_Load_Simple_Glyph;+    face->read_composite_glyph = TT_Load_Composite_Glyph;+    face->forget_glyph_frame   = TT_Forget_Glyph_Frame;+  }+++  static void+  tt_prepare_zone( TT_GlyphZone  zone,+                   FT_GlyphLoad  load,+                   FT_UInt       start_point,+                   FT_UInt       start_contour )+  {+    zone->n_points    = (FT_UShort)( load->outline.n_points - start_point );+    zone->n_contours  = (FT_Short) ( load->outline.n_contours -+                                       start_contour );+    zone->org         = load->extra_points + start_point;+    zone->cur         = load->outline.points + start_point;+    zone->orus        = load->extra_points2 + start_point;+    zone->tags        = (FT_Byte*)load->outline.tags + start_point;+    zone->contours    = (FT_UShort*)load->outline.contours + start_contour;+    zone->first_point = (FT_UShort)start_point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Hint_Glyph                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Hint the glyph using the zone prepared by the caller.  Note that   */+  /*    the zone is supposed to include four phantom points.               */+  /*                                                                       */+  static FT_Error+  TT_Hint_Glyph( TT_Loader  loader,+                 FT_Bool    is_composite )+  {+    TT_GlyphZone  zone = &loader->zone;+    FT_Pos        origin;++#ifdef TT_USE_BYTECODE_INTERPRETER+    FT_UInt       n_ins;+#else+    FT_UNUSED( is_composite );+#endif+++#ifdef TT_USE_BYTECODE_INTERPRETER+    if ( loader->glyph->control_len > 0xFFFFL )+    {+      FT_TRACE1(( "TT_Hint_Glyph: too long instructions " ));+      FT_TRACE1(( "(0x%lx byte) is truncated\n",+                 loader->glyph->control_len ));+    }+    n_ins = (FT_UInt)( loader->glyph->control_len );+#endif++    origin = zone->cur[zone->n_points - 4].x;+    origin = FT_PIX_ROUND( origin ) - origin;+    if ( origin )+      translate_array( zone->n_points, zone->cur, origin, 0 );++#ifdef TT_USE_BYTECODE_INTERPRETER+    /* save original point position in org */+    if ( n_ins > 0 )+      FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );++    /* Reset graphics state. */+    loader->exec->GS = ((TT_Size)loader->size)->GS;++    /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */+    /*      completely refer to the (already) hinted subglyphs.     */+    if ( is_composite )+    {+      loader->exec->metrics.x_scale = 1 << 16;+      loader->exec->metrics.y_scale = 1 << 16;++      FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );+    }+    else+    {+      loader->exec->metrics.x_scale =+        ((TT_Size)loader->size)->metrics.x_scale;+      loader->exec->metrics.y_scale =+        ((TT_Size)loader->size)->metrics.y_scale;+    }+#endif++    /* round pp2 and pp4 */+    zone->cur[zone->n_points - 3].x =+      FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );+    zone->cur[zone->n_points - 1].y =+      FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );++#ifdef TT_USE_BYTECODE_INTERPRETER++    if ( n_ins > 0 )+    {+      FT_Bool   debug;+      FT_Error  error;++      FT_GlyphLoader  gloader         = loader->gloader;+      FT_Outline      current_outline = gloader->current.outline;+++      error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,+                                loader->exec->glyphIns, n_ins );+      if ( error )+        return error;++      loader->exec->is_composite = is_composite;+      loader->exec->pts          = *zone;++      debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&+                       ((TT_Size)loader->size)->debug             );++      error = TT_Run_Context( loader->exec, debug );+      if ( error && loader->exec->pedantic_hinting )+        return error;++      /* store drop-out mode in bits 5-7; set bit 2 also as a marker */+      current_outline.tags[0] |=+        ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;+    }++#endif++    /* save glyph phantom points */+    if ( !loader->preserve_pps )+    {+      loader->pp1 = zone->cur[zone->n_points - 4];+      loader->pp2 = zone->cur[zone->n_points - 3];+      loader->pp3 = zone->cur[zone->n_points - 2];+      loader->pp4 = zone->cur[zone->n_points - 1];+    }++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Process_Simple_Glyph                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Once a simple glyph has been loaded, it needs to be processed.     */+  /*    Usually, this means scaling and hinting through bytecode           */+  /*    interpretation.                                                    */+  /*                                                                       */+  static FT_Error+  TT_Process_Simple_Glyph( TT_Loader  loader )+  {+    FT_GlyphLoader  gloader = loader->gloader;+    FT_Error        error   = TT_Err_Ok;+    FT_Outline*     outline;+    FT_Int          n_points;+++    outline  = &gloader->current.outline;+    n_points = outline->n_points;++    /* set phantom points */++    outline->points[n_points    ] = loader->pp1;+    outline->points[n_points + 1] = loader->pp2;+    outline->points[n_points + 2] = loader->pp3;+    outline->points[n_points + 3] = loader->pp4;++    outline->tags[n_points    ] = 0;+    outline->tags[n_points + 1] = 0;+    outline->tags[n_points + 2] = 0;+    outline->tags[n_points + 3] = 0;++    n_points += 4;++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT++    if ( ((TT_Face)loader->face)->doblend )+    {+      /* Deltas apply to the unscaled data. */+      FT_Vector*  deltas;+      FT_Memory   memory = loader->face->memory;+      FT_Int      i;+++      error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),+                                        loader->glyph_index,+                                        &deltas,+                                        n_points );+      if ( error )+        return error;++      for ( i = 0; i < n_points; ++i )+      {+        outline->points[i].x += deltas[i].x;+        outline->points[i].y += deltas[i].y;+      }++      FT_FREE( deltas );+    }++#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */++    if ( IS_HINTED( loader->load_flags ) )+    {+      tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );++      FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,+                     loader->zone.n_points + 4 );+    }++    /* scale the glyph */+    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )+    {+      FT_Vector*  vec     = outline->points;+      FT_Vector*  limit   = outline->points + n_points;+      FT_Fixed    x_scale = ((TT_Size)loader->size)->metrics.x_scale;+      FT_Fixed    y_scale = ((TT_Size)loader->size)->metrics.y_scale;+++      for ( ; vec < limit; vec++ )+      {+        vec->x = FT_MulFix( vec->x, x_scale );+        vec->y = FT_MulFix( vec->y, y_scale );+      }++      loader->pp1 = outline->points[n_points - 4];+      loader->pp2 = outline->points[n_points - 3];+      loader->pp3 = outline->points[n_points - 2];+      loader->pp4 = outline->points[n_points - 1];+    }++    if ( IS_HINTED( loader->load_flags ) )+    {+      loader->zone.n_points += 4;++      error = TT_Hint_Glyph( loader, 0 );+    }++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Process_Composite_Component                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Once a composite component has been loaded, it needs to be         */+  /*    processed.  Usually, this means transforming and translating.      */+  /*                                                                       */+  static FT_Error+  TT_Process_Composite_Component( TT_Loader    loader,+                                  FT_SubGlyph  subglyph,+                                  FT_UInt      start_point,+                                  FT_UInt      num_base_points )+  {+    FT_GlyphLoader  gloader    = loader->gloader;+    FT_Vector*      base_vec   = gloader->base.outline.points;+    FT_UInt         num_points = gloader->base.outline.n_points;+    FT_Bool         have_scale;+    FT_Pos          x, y;+++    have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE     |+                                              WE_HAVE_AN_XY_SCALE |+                                              WE_HAVE_A_2X2       ) );++    /* perform the transform required for this subglyph */+    if ( have_scale )+    {+      FT_UInt  i;+++      for ( i = num_base_points; i < num_points; i++ )+        FT_Vector_Transform( base_vec + i, &subglyph->transform );+    }++    /* get offset */+    if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )+    {+      FT_UInt     k = subglyph->arg1;+      FT_UInt     l = subglyph->arg2;+      FT_Vector*  p1;+      FT_Vector*  p2;+++      /* match l-th point of the newly loaded component to the k-th point */+      /* of the previously loaded components.                             */++      /* change to the point numbers used by our outline */+      k += start_point;+      l += num_base_points;+      if ( k >= num_base_points ||+           l >= num_points      )+        return TT_Err_Invalid_Composite;++      p1 = gloader->base.outline.points + k;+      p2 = gloader->base.outline.points + l;++      x = p1->x - p2->x;+      y = p1->y - p2->y;+    }+    else+    {+      x = subglyph->arg1;+      y = subglyph->arg2;++      if ( !x && !y )+        return TT_Err_Ok;++  /* Use a default value dependent on                                     */+  /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED.  This is useful for old TT */+  /* fonts which don't set the xxx_COMPONENT_OFFSET bit.                  */++      if ( have_scale &&+#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED+           !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )+#else+            ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )+#endif+      {++#if 0++  /*************************************************************************/+  /*                                                                       */+  /* This algorithm is what Apple documents.  But it doesn't work.         */+  /*                                                                       */+        int  a = subglyph->transform.xx > 0 ?  subglyph->transform.xx+                                            : -subglyph->transform.xx;+        int  b = subglyph->transform.yx > 0 ?  subglyph->transform.yx+                                            : -subglyph->transform.yx;+        int  c = subglyph->transform.xy > 0 ?  subglyph->transform.xy+                                            : -subglyph->transform.xy;+        int  d = subglyph->transform.yy > 0 ? subglyph->transform.yy+                                            : -subglyph->transform.yy;+        int  m = a > b ? a : b;+        int  n = c > d ? c : d;+++        if ( a - b <= 33 && a - b >= -33 )+          m *= 2;+        if ( c - d <= 33 && c - d >= -33 )+          n *= 2;+        x = FT_MulFix( x, m );+        y = FT_MulFix( y, n );++#else /* 0 */++  /*************************************************************************/+  /*                                                                       */+  /* This algorithm is a guess and works much better than the above.       */+  /*                                                                       */+        FT_Fixed  mac_xscale = FT_SqrtFixed(+                                 (FT_Int32)FT_MulFix( subglyph->transform.xx,+                                                      subglyph->transform.xx ) ++                                 (FT_Int32)FT_MulFix( subglyph->transform.xy,+                                                      subglyph->transform.xy ) );+        FT_Fixed  mac_yscale = FT_SqrtFixed(+                                 (FT_Int32)FT_MulFix( subglyph->transform.yy,+                                                      subglyph->transform.yy ) ++                                 (FT_Int32)FT_MulFix( subglyph->transform.yx,+                                                      subglyph->transform.yx ) );+++        x = FT_MulFix( x, mac_xscale );+        y = FT_MulFix( y, mac_yscale );++#endif /* 0 */++      }++      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )+      {+        FT_Fixed  x_scale = ((TT_Size)loader->size)->metrics.x_scale;+        FT_Fixed  y_scale = ((TT_Size)loader->size)->metrics.y_scale;+++        x = FT_MulFix( x, x_scale );+        y = FT_MulFix( y, y_scale );++        if ( subglyph->flags & ROUND_XY_TO_GRID )+        {+          x = FT_PIX_ROUND( x );+          y = FT_PIX_ROUND( y );+        }+      }+    }++    if ( x || y )+      translate_array( num_points - num_base_points,+                       base_vec + num_base_points,+                       x, y );++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Process_Composite_Glyph                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    This is slightly different from TT_Process_Simple_Glyph, in that   */+  /*    its sole purpose is to hint the glyph.  Thus this function is      */+  /*    only available when bytecode interpreter is enabled.               */+  /*                                                                       */+  static FT_Error+  TT_Process_Composite_Glyph( TT_Loader  loader,+                              FT_UInt    start_point,+                              FT_UInt    start_contour )+  {+    FT_Error     error;+    FT_Outline*  outline;+    FT_UInt      i;+++    outline = &loader->gloader->base.outline;++    /* make room for phantom points */+    error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,+                                         outline->n_points + 4,+                                         0 );+    if ( error )+      return error;++    outline->points[outline->n_points    ] = loader->pp1;+    outline->points[outline->n_points + 1] = loader->pp2;+    outline->points[outline->n_points + 2] = loader->pp3;+    outline->points[outline->n_points + 3] = loader->pp4;++    outline->tags[outline->n_points    ] = 0;+    outline->tags[outline->n_points + 1] = 0;+    outline->tags[outline->n_points + 2] = 0;+    outline->tags[outline->n_points + 3] = 0;++#ifdef TT_USE_BYTECODE_INTERPRETER++    {+      FT_Stream  stream = loader->stream;+      FT_UShort  n_ins, max_ins;+      FT_ULong   tmp;+++      /* TT_Load_Composite_Glyph only gives us the offset of instructions */+      /* so we read them here                                             */+      if ( FT_STREAM_SEEK( loader->ins_pos ) ||+           FT_READ_USHORT( n_ins )           )+        return error;++      FT_TRACE5(( "  Instructions size = %d\n", n_ins ));++      /* check it */+      max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions;+      if ( n_ins > max_ins )+      {+        /* acroread ignores this field, so we only do a rough safety check */+        if ( (FT_Int)n_ins > loader->byte_len )+        {+          FT_TRACE1(( "TT_Process_Composite_Glyph: "+                      "too many instructions (%d) for glyph with length %d\n",+                      n_ins, loader->byte_len ));+          return TT_Err_Too_Many_Hints;+        }++        tmp = loader->exec->glyphSize;+        error = Update_Max( loader->exec->memory,+                            &tmp,+                            sizeof ( FT_Byte ),+                            (void*)&loader->exec->glyphIns,+                            n_ins );+        loader->exec->glyphSize = (FT_UShort)tmp;+        if ( error )+          return error;+      }+      else if ( n_ins == 0 )+        return TT_Err_Ok;++      if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )+        return error;++      loader->glyph->control_data = loader->exec->glyphIns;+      loader->glyph->control_len  = n_ins;+    }++#endif++    tt_prepare_zone( &loader->zone, &loader->gloader->base,+                     start_point, start_contour );++    /* Some points are likely touched during execution of  */+    /* instructions on components.  So let's untouch them. */+    for ( i = start_point; i < loader->zone.n_points; i++ )+      loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;++    loader->zone.n_points += 4;++    return TT_Hint_Glyph( loader, 1 );+  }+++  /* Calculate the four phantom points.                     */+  /* The first two stand for horizontal origin and advance. */+  /* The last two stand for vertical origin and advance.    */+#define TT_LOADER_SET_PP( loader )                                          \+          do {                                                              \+            (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \+            (loader)->pp1.y = 0;                                            \+            (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \+            (loader)->pp2.y = 0;                                            \+            (loader)->pp3.x = 0;                                            \+            (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax;  \+            (loader)->pp4.x = 0;                                            \+            (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \+          } while ( 0 )+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    load_truetype_glyph                                                */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Loads a given truetype glyph.  Handles composites and uses a       */+  /*    TT_Loader object.                                                  */+  /*                                                                       */+  static FT_Error+  load_truetype_glyph( TT_Loader  loader,+                       FT_UInt    glyph_index,+                       FT_UInt    recurse_count,+                       FT_Bool    header_only )+  {+    FT_Error        error        = TT_Err_Ok;+    FT_Fixed        x_scale, y_scale;+    FT_ULong        offset;+    TT_Face         face         = (TT_Face)loader->face;+    FT_GlyphLoader  gloader      = loader->gloader;+    FT_Bool         opened_frame = 0;++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    FT_Vector*      deltas       = NULL;+#endif++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    FT_StreamRec    inc_stream;+    FT_Data         glyph_data;+    FT_Bool         glyph_data_loaded = 0;+#endif+++    /* some fonts have an incorrect value of `maxComponentDepth', */+    /* thus we allow depth 1 to catch the majority of them        */+    if ( recurse_count > 1                                   &&+         recurse_count > face->max_profile.maxComponentDepth )+    {+      error = TT_Err_Invalid_Composite;+      goto Exit;+    }++    /* check glyph index */+    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )+    {+      error = TT_Err_Invalid_Glyph_Index;+      goto Exit;+    }++    loader->glyph_index = glyph_index;++    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )+    {+      x_scale = ((TT_Size)loader->size)->metrics.x_scale;+      y_scale = ((TT_Size)loader->size)->metrics.y_scale;+    }+    else+    {+      x_scale = 0x10000L;+      y_scale = 0x10000L;+    }++    tt_get_metrics( loader, glyph_index );++    /* Set `offset' to the start of the glyph relative to the start of */+    /* the `glyf' table, and `byte_len' to the length of the glyph in  */+    /* bytes.                                                          */++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* If we are loading glyph data via the incremental interface, set */+    /* the loader stream to a memory stream reading the data returned  */+    /* by the interface.                                               */+    if ( face->root.internal->incremental_interface )+    {+      error = face->root.internal->incremental_interface->funcs->get_glyph_data(+                face->root.internal->incremental_interface->object,+                glyph_index, &glyph_data );+      if ( error )+        goto Exit;++      glyph_data_loaded = 1;+      offset            = 0;+      loader->byte_len  = glyph_data.length;++      FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );+      FT_Stream_OpenMemory( &inc_stream,+                            glyph_data.pointer, glyph_data.length );++      loader->stream = &inc_stream;+    }+    else++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++      offset = tt_face_get_location( face, glyph_index,+                                     (FT_UInt*)&loader->byte_len );++    if ( loader->byte_len > 0 )+    {+#ifdef FT_CONFIG_OPTION_INCREMENTAL+      /* for the incremental interface, `glyf_offset' is always zero */+      if ( !loader->glyf_offset                        &&+           !face->root.internal->incremental_interface )+#else+      if ( !loader->glyf_offset )+#endif /* FT_CONFIG_OPTION_INCREMENTAL */+      {+        FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));+        error = TT_Err_Invalid_Table;+        goto Exit;+      }++      error = face->access_glyph_frame( loader, glyph_index,+                                        loader->glyf_offset + offset,+                                        loader->byte_len );+      if ( error )+        goto Exit;++      opened_frame = 1;++      /* read glyph header first */+      error = face->read_glyph_header( loader );+      if ( error || header_only )+        goto Exit;+    }++    if ( loader->byte_len == 0 || loader->n_contours == 0 )+    {+      loader->bbox.xMin = 0;+      loader->bbox.xMax = 0;+      loader->bbox.yMin = 0;+      loader->bbox.yMax = 0;++      if ( header_only )+        goto Exit;++      /* must initialize points before (possibly) overriding */+      /* glyph metrics from the incremental interface        */+      TT_LOADER_SET_PP( loader );++#ifdef FT_CONFIG_OPTION_INCREMENTAL+      tt_get_metrics_incr_overrides( loader, glyph_index );+#endif++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT++      if ( ((TT_Face)(loader->face))->doblend )+      {+        /* this must be done before scaling */+        FT_Memory  memory = loader->face->memory;+++        error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),+                                          glyph_index, &deltas, 4 );+        if ( error )+          goto Exit;++        loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y;+        loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y;+        loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y;+        loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y;++        FT_FREE( deltas );+      }++#endif++      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )+      {+        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );+        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );+        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );+        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );+      }++      error = TT_Err_Ok;+      goto Exit;+    }++    /* must initialize points before (possibly) overriding */+    /* glyph metrics from the incremental interface        */+    TT_LOADER_SET_PP( loader );++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    tt_get_metrics_incr_overrides( loader, glyph_index );+#endif++    /***********************************************************************/+    /***********************************************************************/+    /***********************************************************************/++    /* if it is a simple glyph, load it */++    if ( loader->n_contours > 0 )+    {+      error = face->read_simple_glyph( loader );+      if ( error )+        goto Exit;++      /* all data have been read */+      face->forget_glyph_frame( loader );+      opened_frame = 0;++      error = TT_Process_Simple_Glyph( loader );+      if ( error )+        goto Exit;++      FT_GlyphLoader_Add( gloader );+    }++    /***********************************************************************/+    /***********************************************************************/+    /***********************************************************************/++    /* otherwise, load a composite! */+    else if ( loader->n_contours == -1 )+    {+      FT_UInt   start_point;+      FT_UInt   start_contour;+      FT_ULong  ins_pos;  /* position of composite instructions, if any */+++      start_point   = gloader->base.outline.n_points;+      start_contour = gloader->base.outline.n_contours;++      /* for each subglyph, read composite header */+      error = face->read_composite_glyph( loader );+      if ( error )+        goto Exit;++      /* store the offset of instructions */+      ins_pos = loader->ins_pos;++      /* all data we need are read */+      face->forget_glyph_frame( loader );+      opened_frame = 0;++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT++      if ( face->doblend )+      {+        FT_Int       i, limit;+        FT_SubGlyph  subglyph;+        FT_Memory    memory = face->root.memory;+++        /* this provides additional offsets */+        /* for each component's translation */++        if ( ( error = TT_Vary_Get_Glyph_Deltas(+                         face,+                         glyph_index,+                         &deltas,+                         gloader->current.num_subglyphs + 4 )) != 0 )+          goto Exit;++        subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;+        limit    = gloader->current.num_subglyphs;++        for ( i = 0; i < limit; ++i, ++subglyph )+        {+          if ( subglyph->flags & ARGS_ARE_XY_VALUES )+          {+            /* XXX: overflow check for subglyph->{arg1,arg2}.   */+            /* deltas[i].{x,y} must be within signed 16-bit,    */+            /* but the restriction of summed delta is not clear */+            subglyph->arg1 += (FT_Int16)deltas[i].x;+            subglyph->arg2 += (FT_Int16)deltas[i].y;+          }+        }++        loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y;+        loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y;+        loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y;+        loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y;++        FT_FREE( deltas );+      }++#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */++      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )+      {+        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );+        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );+        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );+        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );+      }++      /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */+      /* `as is' in the glyph slot (the client application will be     */+      /* responsible for interpreting these data)...                   */+      if ( loader->load_flags & FT_LOAD_NO_RECURSE )+      {+        FT_GlyphLoader_Add( gloader );+        loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;++        goto Exit;+      }++      /*********************************************************************/+      /*********************************************************************/+      /*********************************************************************/++      {+        FT_UInt      n, num_base_points;+        FT_SubGlyph  subglyph       = 0;++        FT_UInt      num_points     = start_point;+        FT_UInt      num_subglyphs  = gloader->current.num_subglyphs;+        FT_UInt      num_base_subgs = gloader->base.num_subglyphs;++        FT_Stream    old_stream     = loader->stream;+        FT_Int       old_byte_len   = loader->byte_len;+++        FT_GlyphLoader_Add( gloader );++        /* read each subglyph independently */+        for ( n = 0; n < num_subglyphs; n++ )+        {+          FT_Vector  pp[4];+++          /* Each time we call load_truetype_glyph in this loop, the   */+          /* value of `gloader.base.subglyphs' can change due to table */+          /* reallocations.  We thus need to recompute the subglyph    */+          /* pointer on each iteration.                                */+          subglyph = gloader->base.subglyphs + num_base_subgs + n;++          pp[0] = loader->pp1;+          pp[1] = loader->pp2;+          pp[2] = loader->pp3;+          pp[3] = loader->pp4;++          num_base_points = gloader->base.outline.n_points;++          error = load_truetype_glyph( loader, subglyph->index,+                                       recurse_count + 1, FALSE );+          if ( error )+            goto Exit;++          /* restore subglyph pointer */+          subglyph = gloader->base.subglyphs + num_base_subgs + n;++          if ( !( subglyph->flags & USE_MY_METRICS ) )+          {+            loader->pp1 = pp[0];+            loader->pp2 = pp[1];+            loader->pp3 = pp[2];+            loader->pp4 = pp[3];+          }++          num_points = gloader->base.outline.n_points;++          if ( num_points == num_base_points )+            continue;++          /* gloader->base.outline consists of three parts:               */+          /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */+          /*                                                              */+          /* (1): exists from the beginning                               */+          /* (2): components that have been loaded so far                 */+          /* (3): the newly loaded component                              */+          TT_Process_Composite_Component( loader, subglyph, start_point,+                                          num_base_points );+        }++        loader->stream   = old_stream;+        loader->byte_len = old_byte_len;++        /* process the glyph */+        loader->ins_pos = ins_pos;+        if ( IS_HINTED( loader->load_flags ) &&++#ifdef TT_USE_BYTECODE_INTERPRETER++             subglyph->flags & WE_HAVE_INSTR &&++#endif++             num_points > start_point )+          TT_Process_Composite_Glyph( loader, start_point, start_contour );++      }+    }+    else+    {+      /* invalid composite count (negative but not -1) */+      error = TT_Err_Invalid_Outline;+      goto Exit;+    }++    /***********************************************************************/+    /***********************************************************************/+    /***********************************************************************/++  Exit:++    if ( opened_frame )+      face->forget_glyph_frame( loader );++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    if ( glyph_data_loaded )+      face->root.internal->incremental_interface->funcs->free_glyph_data(+        face->root.internal->incremental_interface->object,+        &glyph_data );++#endif++    return error;+  }+++  static FT_Error+  compute_glyph_metrics( TT_Loader  loader,+                         FT_UInt    glyph_index )+  {+    FT_BBox       bbox;+    TT_Face       face = (TT_Face)loader->face;+    FT_Fixed      y_scale;+    TT_GlyphSlot  glyph = loader->glyph;+    TT_Size       size = (TT_Size)loader->size;+++    y_scale = 0x10000L;+    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )+      y_scale = size->root.metrics.y_scale;++    if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )+      FT_Outline_Get_CBox( &glyph->outline, &bbox );+    else+      bbox = loader->bbox;++    /* get the device-independent horizontal advance; it is scaled later */+    /* by the base layer.                                                */+    {+      FT_Pos  advance = loader->linear;+++      /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */+      /* correctly support DynaLab fonts, which have an incorrect       */+      /* `advance_Width_Max' field!  It is used, to my knowledge,       */+      /* exclusively in the X-TrueType font server.                     */+      /*                                                                */+      if ( face->postscript.isFixedPitch                                     &&+           ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 )+        advance = face->horizontal.advance_Width_Max;++      /* we need to return the advance in font units in linearHoriAdvance, */+      /* it will be scaled later by the base layer.                        */+      glyph->linearHoriAdvance = advance;+    }++    glyph->metrics.horiBearingX = bbox.xMin;+    glyph->metrics.horiBearingY = bbox.yMax;+    glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;++    /* adjust advance width to the value contained in the hdmx table */+    if ( !face->postscript.isFixedPitch  &&+         IS_HINTED( loader->load_flags ) )+    {+      FT_Byte*  widthp;+++      widthp = tt_face_get_device_metrics( face,+                                           size->root.metrics.x_ppem,+                                           glyph_index );++      if ( widthp )+        glyph->metrics.horiAdvance = *widthp << 6;+    }++    /* set glyph dimensions */+    glyph->metrics.width  = bbox.xMax - bbox.xMin;+    glyph->metrics.height = bbox.yMax - bbox.yMin;++    /* Now take care of vertical metrics.  In the case where there is */+    /* no vertical information within the font (relatively common),   */+    /* create some metrics manually                                   */+    {+      FT_Pos  top;      /* scaled vertical top side bearing  */+      FT_Pos  advance;  /* scaled vertical advance height    */+++      /* Get the unscaled top bearing and advance height. */+      if ( face->vertical_info                   &&+           face->vertical.number_Of_VMetrics > 0 )+      {+        top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,+                                   y_scale );++        if ( loader->pp3.y <= loader->pp4.y )+          advance = 0;+        else+          advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,+                                          y_scale );+      }+      else+      {+        FT_Pos  height;+++        /* XXX Compute top side bearing and advance height in  */+        /*     Get_VMetrics instead of here.                   */++        /* NOTE: The OS/2 values are the only `portable' ones, */+        /*       which is why we use them, if there is an OS/2 */+        /*       table in the font.  Otherwise, we use the     */+        /*       values defined in the horizontal header.      */++        height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,+                                      y_scale );+        if ( face->os2.version != 0xFFFFU )+          advance = (FT_Pos)( face->os2.sTypoAscender -+                              face->os2.sTypoDescender );+        else+          advance = (FT_Pos)( face->horizontal.Ascender -+                              face->horizontal.Descender );++        top = ( advance - height ) / 2;+      }++#ifdef FT_CONFIG_OPTION_INCREMENTAL+      {+        FT_Incremental_InterfaceRec*  incr;+        FT_Incremental_MetricsRec     metrics;+        FT_Error                      error;+++        incr = face->root.internal->incremental_interface;++        /* If this is an incrementally loaded font see if there are */+        /* overriding metrics for this glyph.                       */+        if ( incr && incr->funcs->get_glyph_metrics )+        {+          metrics.bearing_x = 0;+          metrics.bearing_y = top;+          metrics.advance   = advance;++          error = incr->funcs->get_glyph_metrics( incr->object,+                                                  glyph_index,+                                                  TRUE,+                                                  &metrics );+          if ( error )+            return error;++          top     = metrics.bearing_y;+          advance = metrics.advance;+        }+      }++      /* GWW: Do vertical metrics get loaded incrementally too? */++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++      glyph->linearVertAdvance = advance;++      /* scale the metrics */+      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )+      {+        top     = FT_MulFix( top,     y_scale );+        advance = FT_MulFix( advance, y_scale );+      }++      /* XXX: for now, we have no better algorithm for the lsb, but it */+      /*      should work fine.                                        */+      /*                                                               */+      glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -+                                      glyph->metrics.horiAdvance / 2;+      glyph->metrics.vertBearingY = top;+      glyph->metrics.vertAdvance  = advance;+    }++    return 0;+  }+++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++  static FT_Error+  load_sbit_image( TT_Size       size,+                   TT_GlyphSlot  glyph,+                   FT_UInt       glyph_index,+                   FT_Int32      load_flags )+  {+    TT_Face             face;+    SFNT_Service        sfnt;+    FT_Stream           stream;+    FT_Error            error;+    TT_SBit_MetricsRec  metrics;+++    face   = (TT_Face)glyph->face;+    sfnt   = (SFNT_Service)face->sfnt;+    stream = face->root.stream;++    error = sfnt->load_sbit_image( face,+                                   size->strike_index,+                                   glyph_index,+                                   (FT_Int)load_flags,+                                   stream,+                                   &glyph->bitmap,+                                   &metrics );+    if ( !error )+    {+      glyph->outline.n_points   = 0;+      glyph->outline.n_contours = 0;++      glyph->metrics.width  = (FT_Pos)metrics.width  << 6;+      glyph->metrics.height = (FT_Pos)metrics.height << 6;++      glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;+      glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;+      glyph->metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;++      glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;+      glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;+      glyph->metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;++      glyph->format = FT_GLYPH_FORMAT_BITMAP;++      if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )+      {+        glyph->bitmap_left = metrics.vertBearingX;+        glyph->bitmap_top  = metrics.vertBearingY;+      }+      else+      {+        glyph->bitmap_left = metrics.horiBearingX;+        glyph->bitmap_top  = metrics.horiBearingY;+      }+    }++    return error;+  }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */+++  static FT_Error+  tt_loader_init( TT_Loader     loader,+                  TT_Size       size,+                  TT_GlyphSlot  glyph,+                  FT_Int32      load_flags,+                  FT_Bool       glyf_table_only )+  {+    TT_Face    face;+    FT_Stream  stream;+++    face   = (TT_Face)glyph->face;+    stream = face->root.stream;++    FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );++#ifdef TT_USE_BYTECODE_INTERPRETER++    /* load execution context */+    if ( IS_HINTED( load_flags ) && !glyf_table_only )+    {+      TT_ExecContext  exec;+      FT_Bool         grayscale;+++      if ( !size->cvt_ready )+      {+        FT_Error  error = tt_size_ready_bytecode( size );+        if ( error )+          return error;+      }++      /* query new execution context */+      exec = size->debug ? size->context+                         : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;+      if ( !exec )+        return TT_Err_Could_Not_Find_Context;++      grayscale =+        FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO );++      TT_Load_Context( exec, face, size );++      /* a change from mono to grayscale rendering (and vice versa) */+      /* requires a re-execution of the CVT program                 */+      if ( grayscale != exec->grayscale )+      {+        FT_UInt  i;+++        FT_TRACE4(( "tt_loader_init: grayscale change,"+                    " re-executing `prep' table\n" ));++        exec->grayscale = grayscale;++        for ( i = 0; i < size->cvt_size; i++ )+          size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );+        tt_size_run_prep( size );+      }++      /* see whether the cvt program has disabled hinting */+      if ( exec->GS.instruct_control & 1 )+        load_flags |= FT_LOAD_NO_HINTING;++      /* load default graphics state -- if needed */+      if ( exec->GS.instruct_control & 2 )+        exec->GS = tt_default_graphics_state;++      exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );+      loader->exec = exec;+      loader->instructions = exec->glyphIns;+    }++#endif /* TT_USE_BYTECODE_INTERPRETER */++    /* seek to the beginning of the glyph table -- for Type 42 fonts     */+    /* the table might be accessed from a Postscript stream or something */+    /* else...                                                           */++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    if ( face->root.internal->incremental_interface )+      loader->glyf_offset = 0;+    else++#endif++    {+      FT_Error  error = face->goto_table( face, TTAG_glyf, stream, 0 );+++      if ( error == TT_Err_Table_Missing )+        loader->glyf_offset = 0;+      else if ( error )+      {+        FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));+        return error;+      }+      else+        loader->glyf_offset = FT_STREAM_POS();+    }++    /* get face's glyph loader */+    if ( !glyf_table_only )+    {+      FT_GlyphLoader  gloader = glyph->internal->loader;+++      FT_GlyphLoader_Rewind( gloader );+      loader->gloader = gloader;+    }++    loader->load_flags = load_flags;++    loader->face   = (FT_Face)face;+    loader->size   = (FT_Size)size;+    loader->glyph  = (FT_GlyphSlot)glyph;+    loader->stream = stream;++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Load_Glyph                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A function used to load a single glyph within a given glyph slot,  */+  /*    for a given size.                                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    glyph       :: A handle to a target slot object where the glyph    */+  /*                   will be loaded.                                     */+  /*                                                                       */+  /*    size        :: A handle to the source face size at which the glyph */+  /*                   must be scaled/loaded.                              */+  /*                                                                       */+  /*    glyph_index :: The index of the glyph in the font file.            */+  /*                                                                       */+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */+  /*                   FT_LOAD_XXX constants can be used to control the    */+  /*                   glyph loading process (e.g., whether the outline    */+  /*                   should be scaled, whether to load bitmaps or not,   */+  /*                   whether to hint the outline, etc).                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Load_Glyph( TT_Size       size,+                 TT_GlyphSlot  glyph,+                 FT_UInt       glyph_index,+                 FT_Int32      load_flags )+  {+    TT_Face       face;+    FT_Error      error;+    TT_LoaderRec  loader;+++    face   = (TT_Face)glyph->face;+    error  = TT_Err_Ok;++#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS++    /* try to load embedded bitmap if any              */+    /*                                                 */+    /* XXX: The convention should be emphasized in     */+    /*      the documents because it can be confusing. */+    if ( size->strike_index != 0xFFFFFFFFUL      &&+         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )+    {+      error = load_sbit_image( size, glyph, glyph_index, load_flags );+      if ( !error )+      {+        FT_Face  root = &face->root;+++        if ( FT_IS_SCALABLE( root ) )+        {+          /* for the bbox we need the header only */+          (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );+          (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );+          glyph->linearHoriAdvance = loader.linear;+          glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax -+                                       loader.vadvance;+          if ( face->postscript.isFixedPitch                             &&+               ( load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 )+            glyph->linearHoriAdvance = face->horizontal.advance_Width_Max;+        }++        return TT_Err_Ok;+      }+    }++#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */++    /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */+    if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )+      return TT_Err_Invalid_Size_Handle;++    if ( load_flags & FT_LOAD_SBITS_ONLY )+      return TT_Err_Invalid_Argument;++    error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );+    if ( error )+      return error;++    glyph->format        = FT_GLYPH_FORMAT_OUTLINE;+    glyph->num_subglyphs = 0;+    glyph->outline.flags = 0;++    /* main loading loop */+    error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );+    if ( !error )+    {+      if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )+      {+        glyph->num_subglyphs = loader.gloader->base.num_subglyphs;+        glyph->subglyphs     = loader.gloader->base.subglyphs;+      }+      else+      {+        glyph->outline        = loader.gloader->base.outline;+        glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;++        /* Translate array so that (0,0) is the glyph's origin.  Note  */+        /* that this behaviour is independent on the value of bit 1 of */+        /* the `flags' field in the `head' table -- at least major     */+        /* applications like Acroread indicate that.                   */+        if ( loader.pp1.x )+          FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );+      }++#ifdef TT_USE_BYTECODE_INTERPRETER++      if ( IS_HINTED( load_flags ) )+      {+        if ( loader.exec->GS.scan_control )+        {+          /* convert scan conversion mode to FT_OUTLINE_XXX flags */+          switch ( loader.exec->GS.scan_type )+          {+          case 0: /* simple drop-outs including stubs */+            glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;+            break;+          case 1: /* simple drop-outs excluding stubs */+            /* nothing; it's the default rendering mode */+            break;+          case 4: /* smart drop-outs including stubs */+            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |+                                    FT_OUTLINE_INCLUDE_STUBS;+            break;+          case 5: /* smart drop-outs excluding stubs  */+            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;+            break;++          default: /* no drop-out control */+            glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;+            break;+          }+        }+        else+          glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;+      }++#endif /* TT_USE_BYTECODE_INTERPRETER */++      compute_glyph_metrics( &loader, glyph_index );+    }++    /* Set the `high precision' bit flag.                           */+    /* This is _critical_ to get correct output for monochrome      */+    /* TrueType glyphs at all sizes using the bytecode interpreter. */+    /*                                                              */+    if ( !( load_flags & FT_LOAD_NO_SCALE ) &&+         size->root.metrics.y_ppem < 24     )+      glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;++    return error;+  }+++/* END */
+ src/truetype/ttgload.h view
@@ -0,0 +1,63 @@+/***************************************************************************/+/*                                                                         */+/*  ttgload.h                                                              */+/*                                                                         */+/*    TrueType Glyph Loader (specification).                               */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTGLOAD_H__+#define __TTGLOAD_H__+++#include <ft2build.h>+#include "ttobjs.h"++#ifdef TT_USE_BYTECODE_INTERPRETER+#include "ttinterp.h"+#endif+++FT_BEGIN_HEADER+++  FT_LOCAL( void )+  TT_Init_Glyph_Loading( TT_Face  face );++  FT_LOCAL( void )+  TT_Get_HMetrics( TT_Face     face,+                   FT_UInt     idx,+                   FT_Bool     check,+                   FT_Short*   lsb,+                   FT_UShort*  aw );++  FT_LOCAL( void )+  TT_Get_VMetrics( TT_Face     face,+                   FT_UInt     idx,+                   FT_Bool     check,+                   FT_Short*   tsb,+                   FT_UShort*  ah );++  FT_LOCAL( FT_Error )+  TT_Load_Glyph( TT_Size       size,+                 TT_GlyphSlot  glyph,+                 FT_UInt       glyph_index,+                 FT_Int32      load_flags );+++FT_END_HEADER++#endif /* __TTGLOAD_H__ */+++/* END */
+ src/truetype/ttgxvar.c view
@@ -0,0 +1,1548 @@+/***************************************************************************/+/*                                                                         */+/*  ttgxvar.c                                                              */+/*                                                                         */+/*    TrueType GX Font Variation loader                                    */+/*                                                                         */+/*  Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 by                  */+/*  David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.     */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at      */+  /*                                                                       */+  /*   http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html  */+  /*                                                                       */+  /* The documentation for `fvar' is inconsistent.  At one point it says   */+  /* that `countSizePairs' should be 3, at another point 2.  It should     */+  /* be 2.                                                                 */+  /*                                                                       */+  /* The documentation for `gvar' is not intelligible; `cvar' refers you   */+  /* to `gvar' and is thus also incomprehensible.                          */+  /*                                                                       */+  /* The documentation for `avar' appears correct, but Apple has no fonts  */+  /* with an `avar' table, so it is hard to test.                          */+  /*                                                                       */+  /* Many thanks to John Jenkins (at Apple) in figuring this out.          */+  /*                                                                       */+  /*                                                                       */+  /* Apple's `kern' table has some references to tuple indices, but as     */+  /* there is no indication where these indices are defined, nor how to    */+  /* interpolate the kerning values (different tuples have different       */+  /* classes) this issue is ignored.                                       */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_SFNT_H+#include FT_TRUETYPE_TAGS_H+#include FT_MULTIPLE_MASTERS_H++#include "ttpload.h"+#include "ttgxvar.h"++#include "tterrors.h"+++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+++#define FT_Stream_FTell( stream )  \+          ( (stream)->cursor - (stream)->base )+#define FT_Stream_SeekSet( stream, off ) \+              ( (stream)->cursor = (stream)->base+(off) )+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttgxvar+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                       Internal Routines                       *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'.  It        */+  /* indicates that there is a delta for every point without needing to    */+  /* enumerate all of them.                                                */+  /*                                                                       */+#define ALL_POINTS  (FT_UShort*)( -1 )+++#define GX_PT_POINTS_ARE_WORDS      0x80+#define GX_PT_POINT_RUN_COUNT_MASK  0x7F+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_var_readpackedpoints                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Read a set of points to which the following deltas will apply.     */+  /*    Points are packed with a run length encoding.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream    :: The data stream.                                      */+  /*                                                                       */+  /* <Output>                                                              */+  /*    point_cnt :: The number of points read.  A zero value means that   */+  /*                 all points in the glyph will be affected, without     */+  /*                 enumerating them individually.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    An array of FT_UShort containing the affected points or the        */+  /*    special value ALL_POINTS.                                          */+  /*                                                                       */+  static FT_UShort*+  ft_var_readpackedpoints( FT_Stream  stream,+                           FT_UInt   *point_cnt )+  {+    FT_UShort *points;+    FT_Int     n;+    FT_Int     runcnt;+    FT_Int     i;+    FT_Int     j;+    FT_Int     first;+    FT_Memory  memory = stream->memory;+    FT_Error   error  = TT_Err_Ok;++    FT_UNUSED( error );+++    *point_cnt = n = FT_GET_BYTE();+    if ( n == 0 )+      return ALL_POINTS;++    if ( n & GX_PT_POINTS_ARE_WORDS )+      n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 );++    if ( FT_NEW_ARRAY( points, n ) )+      return NULL;++    i = 0;+    while ( i < n )+    {+      runcnt = FT_GET_BYTE();+      if ( runcnt & GX_PT_POINTS_ARE_WORDS )+      {+        runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK;+        first  = points[i++] = FT_GET_USHORT();++        if ( runcnt < 1 || i + runcnt >= n )+          goto Exit;++        /* first point not included in runcount */+        for ( j = 0; j < runcnt; ++j )+          points[i++] = (FT_UShort)( first += FT_GET_USHORT() );+      }+      else+      {+        first = points[i++] = FT_GET_BYTE();++        if ( runcnt < 1 || i + runcnt >= n )+          goto Exit;++        for ( j = 0; j < runcnt; ++j )+          points[i++] = (FT_UShort)( first += FT_GET_BYTE() );+      }+    }++  Exit:+    return points;+  }+++  enum+  {+    GX_DT_DELTAS_ARE_ZERO      = 0x80,+    GX_DT_DELTAS_ARE_WORDS     = 0x40,+    GX_DT_DELTA_RUN_COUNT_MASK = 0x3F+  };+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_var_readpackeddeltas                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Read a set of deltas.  These are packed slightly differently than  */+  /*    points.  In particular there is no overall count.                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream    :: The data stream.                                      */+  /*                                                                       */+  /*    delta_cnt :: The number of to be read.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    An array of FT_Short containing the deltas for the affected        */+  /*    points.  (This only gets the deltas for one dimension.  It will    */+  /*    generally be called twice, once for x, once for y.  When used in   */+  /*    cvt table, it will only be called once.)                           */+  /*                                                                       */+  static FT_Short*+  ft_var_readpackeddeltas( FT_Stream  stream,+                           FT_Offset  delta_cnt )+  {+    FT_Short  *deltas = NULL;+    FT_UInt    runcnt;+    FT_Offset  i;+    FT_UInt    j;+    FT_Memory  memory = stream->memory;+    FT_Error   error  = TT_Err_Ok;++    FT_UNUSED( error );+++    if ( FT_NEW_ARRAY( deltas, delta_cnt ) )+      return NULL;++    i = 0;+    while ( i < delta_cnt )+    {+      runcnt = FT_GET_BYTE();+      if ( runcnt & GX_DT_DELTAS_ARE_ZERO )+      {+        /* runcnt zeroes get added */+        for ( j = 0;+              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;+              ++j )+          deltas[i++] = 0;+      }+      else if ( runcnt & GX_DT_DELTAS_ARE_WORDS )+      {+        /* runcnt shorts from the stack */+        for ( j = 0;+              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;+              ++j )+          deltas[i++] = FT_GET_SHORT();+      }+      else+      {+        /* runcnt signed bytes from the stack */+        for ( j = 0;+              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;+              ++j )+          deltas[i++] = FT_GET_CHAR();+      }++      if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) )+      {+        /* Bad format */+        FT_FREE( deltas );+        return NULL;+      }+    }++    return deltas;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_var_load_avar                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parse the `avar' table if present.  It need not be, so we return   */+  /*    nothing.                                                           */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face :: The font face.                                             */+  /*                                                                       */+  static void+  ft_var_load_avar( TT_Face  face )+  {+    FT_Stream       stream = FT_FACE_STREAM(face);+    FT_Memory       memory = stream->memory;+    GX_Blend        blend  = face->blend;+    GX_AVarSegment  segment;+    FT_Error        error = TT_Err_Ok;+    FT_ULong        version;+    FT_Long         axisCount;+    FT_Int          i, j;+    FT_ULong        table_len;++    FT_UNUSED( error );+++    blend->avar_checked = TRUE;+    if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 )+      return;++    if ( FT_FRAME_ENTER( table_len ) )+      return;++    version   = FT_GET_LONG();+    axisCount = FT_GET_LONG();++    if ( version != 0x00010000L                       ||+         axisCount != (FT_Long)blend->mmvar->num_axis )+      goto Exit;++    if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) )+      goto Exit;++    segment = &blend->avar_segment[0];+    for ( i = 0; i < axisCount; ++i, ++segment )+    {+      segment->pairCount = FT_GET_USHORT();+      if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )+      {+        /* Failure.  Free everything we have done so far.  We must do */+        /* it right now since loading the `avar' table is optional.   */++        for ( j = i - 1; j >= 0; --j )+          FT_FREE( blend->avar_segment[j].correspondence );++        FT_FREE( blend->avar_segment );+        blend->avar_segment = NULL;+        goto Exit;+      }++      for ( j = 0; j < segment->pairCount; ++j )+      {+        segment->correspondence[j].fromCoord =+          FT_GET_SHORT() << 2;    /* convert to Fixed */+        segment->correspondence[j].toCoord =+          FT_GET_SHORT()<<2;    /* convert to Fixed */+      }+    }++  Exit:+    FT_FRAME_EXIT();+  }+++  typedef struct  GX_GVar_Head_+  {+    FT_Long    version;+    FT_UShort  axisCount;+    FT_UShort  globalCoordCount;+    FT_ULong   offsetToCoord;+    FT_UShort  glyphCount;+    FT_UShort  flags;+    FT_ULong   offsetToData;++  } GX_GVar_Head;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_var_load_gvar                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Parses the `gvar' table if present.  If `fvar' is there, `gvar'    */+  /*    had better be there too.                                           */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face :: The font face.                                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  ft_var_load_gvar( TT_Face  face )+  {+    FT_Stream     stream = FT_FACE_STREAM(face);+    FT_Memory     memory = stream->memory;+    GX_Blend      blend  = face->blend;+    FT_Error      error;+    FT_UInt       i, j;+    FT_ULong      table_len;+    FT_ULong      gvar_start;+    FT_ULong      offsetToData;+    GX_GVar_Head  gvar_head;++    static const FT_Frame_Field  gvar_fields[] =+    {++#undef  FT_STRUCTURE+#define FT_STRUCTURE  GX_GVar_Head++      FT_FRAME_START( 20 ),+        FT_FRAME_LONG  ( version ),+        FT_FRAME_USHORT( axisCount ),+        FT_FRAME_USHORT( globalCoordCount ),+        FT_FRAME_ULONG ( offsetToCoord ),+        FT_FRAME_USHORT( glyphCount ),+        FT_FRAME_USHORT( flags ),+        FT_FRAME_ULONG ( offsetToData ),+      FT_FRAME_END+    };++    if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 )+      goto Exit;++    gvar_start = FT_STREAM_POS( );+    if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )+      goto Exit;++    blend->tuplecount  = gvar_head.globalCoordCount;+    blend->gv_glyphcnt = gvar_head.glyphCount;+    offsetToData       = gvar_start + gvar_head.offsetToData;++    if ( gvar_head.version   != (FT_Long)0x00010000L              ||+         gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )+    {+      error = TT_Err_Invalid_Table;+      goto Exit;+    }++    if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )+      goto Exit;++    if ( gvar_head.flags & 1 )+    {+      /* long offsets (one more offset than glyphs, to mark size of last) */+      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )+        goto Exit;++      for ( i = 0; i <= blend->gv_glyphcnt; ++i )+        blend->glyphoffsets[i] = offsetToData + FT_GET_LONG();++      FT_FRAME_EXIT();+    }+    else+    {+      /* short offsets (one more offset than glyphs, to mark size of last) */+      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )+        goto Exit;++      for ( i = 0; i <= blend->gv_glyphcnt; ++i )+        blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;+                                              /* XXX: Undocumented: `*2'! */++      FT_FRAME_EXIT();+    }++    if ( blend->tuplecount != 0 )+    {+      if ( FT_NEW_ARRAY( blend->tuplecoords,+                         gvar_head.axisCount * blend->tuplecount ) )+        goto Exit;++      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )       ||+           FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L )                   )+        goto Exit;++      for ( i = 0; i < blend->tuplecount; ++i )+        for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j )+          blend->tuplecoords[i * gvar_head.axisCount + j] =+            FT_GET_SHORT() << 2;                /* convert to FT_Fixed */++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    ft_var_apply_tuple                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Figure out whether a given tuple (design) applies to the current   */+  /*    blend, and if so, what is the scaling factor.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    blend           :: The current blend of the font.                  */+  /*                                                                       */+  /*    tupleIndex      :: A flag saying whether this is an intermediate   */+  /*                       tuple or not.                                   */+  /*                                                                       */+  /*    tuple_coords    :: The coordinates of the tuple in normalized axis */+  /*                       units.                                          */+  /*                                                                       */+  /*    im_start_coords :: The initial coordinates where this tuple starts */+  /*                       to apply (for intermediate coordinates).        */+  /*                                                                       */+  /*    im_end_coords   :: The final coordinates after which this tuple no */+  /*                       longer applies (for intermediate coordinates).  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    An FT_Fixed value containing the scaling factor.                   */+  /*                                                                       */+  static FT_Fixed+  ft_var_apply_tuple( GX_Blend   blend,+                      FT_UShort  tupleIndex,+                      FT_Fixed*  tuple_coords,+                      FT_Fixed*  im_start_coords,+                      FT_Fixed*  im_end_coords )+  {+    FT_UInt   i;+    FT_Fixed  apply;+    FT_Fixed  temp;+++    apply = 0x10000L;+    for ( i = 0; i < blend->num_axis; ++i )+    {+      if ( tuple_coords[i] == 0 )+        /* It's not clear why (for intermediate tuples) we don't need     */+        /* to check against start/end -- the documentation says we don't. */+        /* Similarly, it's unclear why we don't need to scale along the   */+        /* axis.                                                          */+        continue;++      else if ( blend->normalizedcoords[i] == 0                           ||+                ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||+                ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )+      {+        apply = 0;+        break;+      }++      else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )+        /* not an intermediate tuple */+        apply = FT_MulDiv( apply,+                           blend->normalizedcoords[i] > 0+                             ? blend->normalizedcoords[i]+                             : -blend->normalizedcoords[i],+                           0x10000L );++      else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||+                blend->normalizedcoords[i] >= im_end_coords[i]   )+      {+        apply = 0;+        break;+      }++      else if ( blend->normalizedcoords[i] < tuple_coords[i] )+      {+        temp = FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i],+                          0x10000L,+                          tuple_coords[i] - im_start_coords[i]);+        apply = FT_MulDiv( apply, temp, 0x10000L );+      }++      else+      {+        temp = FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i],+                          0x10000L,+                          im_end_coords[i] - tuple_coords[i] );+        apply = FT_MulDiv( apply, temp, 0x10000L );+      }+    }++    return apply;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****               MULTIPLE MASTERS SERVICE FUNCTIONS              *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  typedef struct  GX_FVar_Head_+  {+    FT_Long    version;+    FT_UShort  offsetToData;+    FT_UShort  countSizePairs;+    FT_UShort  axisCount;+    FT_UShort  axisSize;+    FT_UShort  instanceCount;+    FT_UShort  instanceSize;++  } GX_FVar_Head;+++  typedef struct  fvar_axis_+  {+    FT_ULong   axisTag;+    FT_ULong   minValue;+    FT_ULong   defaultValue;+    FT_ULong   maxValue;+    FT_UShort  flags;+    FT_UShort  nameID;++  } GX_FVar_Axis;+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Get_MM_Var                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Check that the font's `fvar' table is valid, parse it, and return  */+  /*    those data.                                                        */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: The font face.                                           */+  /*              TT_Get_MM_Var initializes the blend structure.           */+  /*                                                                       */+  /* <Output>                                                              */+  /*    master :: The `fvar' data (must be freed by caller).               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Get_MM_Var( TT_Face      face,+                 FT_MM_Var*  *master )+  {+    FT_Stream            stream = face->root.stream;+    FT_Memory            memory = face->root.memory;+    FT_ULong             table_len;+    FT_Error             error  = TT_Err_Ok;+    FT_ULong             fvar_start;+    FT_Int               i, j;+    FT_MM_Var*           mmvar;+    FT_Fixed*            next_coords;+    FT_String*           next_name;+    FT_Var_Axis*         a;+    FT_Var_Named_Style*  ns;+    GX_FVar_Head         fvar_head;++    static const FT_Frame_Field  fvar_fields[] =+    {++#undef  FT_STRUCTURE+#define FT_STRUCTURE  GX_FVar_Head++      FT_FRAME_START( 16 ),+        FT_FRAME_LONG  ( version ),+        FT_FRAME_USHORT( offsetToData ),+        FT_FRAME_USHORT( countSizePairs ),+        FT_FRAME_USHORT( axisCount ),+        FT_FRAME_USHORT( axisSize ),+        FT_FRAME_USHORT( instanceCount ),+        FT_FRAME_USHORT( instanceSize ),+      FT_FRAME_END+    };++    static const FT_Frame_Field  fvaraxis_fields[] =+    {++#undef  FT_STRUCTURE+#define FT_STRUCTURE  GX_FVar_Axis++      FT_FRAME_START( 20 ),+        FT_FRAME_ULONG ( axisTag ),+        FT_FRAME_ULONG ( minValue ),+        FT_FRAME_ULONG ( defaultValue ),+        FT_FRAME_ULONG ( maxValue ),+        FT_FRAME_USHORT( flags ),+        FT_FRAME_USHORT( nameID ),+      FT_FRAME_END+    };+++    if ( face->blend == NULL )+    {+      /* both `fvar' and `gvar' must be present */+      if ( (error = face->goto_table( face, TTAG_gvar,+                                      stream, &table_len )) != 0 )+        goto Exit;++      if ( (error = face->goto_table( face, TTAG_fvar,+                                      stream, &table_len )) != 0 )+        goto Exit;++      fvar_start = FT_STREAM_POS( );++      if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) )+        goto Exit;++      if ( fvar_head.version != (FT_Long)0x00010000L                      ||+           fvar_head.countSizePairs != 2                                  ||+           fvar_head.axisSize != 20                                       ||+           /* axisCount limit implied by 16-bit instanceSize */+           fvar_head.axisCount > 0x3FFE                                   ||+           fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount          ||+           /* instanceCount limit implied by limited range of name IDs */+           fvar_head.instanceCount > 0x7EFF                               ||+           fvar_head.offsetToData + fvar_head.axisCount * 20U ++             fvar_head.instanceCount * fvar_head.instanceSize > table_len )+      {+        error = TT_Err_Invalid_Table;+        goto Exit;+      }++      if ( FT_NEW( face->blend ) )+        goto Exit;++      /* cannot overflow 32-bit arithmetic because of limits above */+      face->blend->mmvar_len =+        sizeof ( FT_MM_Var ) ++        fvar_head.axisCount * sizeof ( FT_Var_Axis ) ++        fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) ++        fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) ++        5 * fvar_head.axisCount;++      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )+        goto Exit;+      face->blend->mmvar = mmvar;++      mmvar->num_axis =+        fvar_head.axisCount;+      mmvar->num_designs =+        (FT_UInt)-1;           /* meaningless in this context; each glyph */+                               /* may have a different number of designs  */+                               /* (or tuples, as called by Apple)         */+      mmvar->num_namedstyles =+        fvar_head.instanceCount;+      mmvar->axis =+        (FT_Var_Axis*)&(mmvar[1]);+      mmvar->namedstyle =+        (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]);++      next_coords =+        (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]);+      for ( i = 0; i < fvar_head.instanceCount; ++i )+      {+        mmvar->namedstyle[i].coords  = next_coords;+        next_coords                 += fvar_head.axisCount;+      }++      next_name = (FT_String*)next_coords;+      for ( i = 0; i < fvar_head.axisCount; ++i )+      {+        mmvar->axis[i].name  = next_name;+        next_name           += 5;+      }++      if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) )+        goto Exit;++      a = mmvar->axis;+      for ( i = 0; i < fvar_head.axisCount; ++i )+      {+        GX_FVar_Axis  axis_rec;+++        if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) )+          goto Exit;+        a->tag     = axis_rec.axisTag;+        a->minimum = axis_rec.minValue;     /* A Fixed */+        a->def     = axis_rec.defaultValue; /* A Fixed */+        a->maximum = axis_rec.maxValue;     /* A Fixed */+        a->strid   = axis_rec.nameID;++        a->name[0] = (FT_String)(   a->tag >> 24 );+        a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF );+        a->name[2] = (FT_String)( ( a->tag >>  8 ) & 0xFF );+        a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );+        a->name[4] = 0;++        ++a;+      }++      ns = mmvar->namedstyle;+      for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns )+      {+        if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )+          goto Exit;++        ns->strid       =    FT_GET_USHORT();+        (void) /* flags = */ FT_GET_USHORT();++        for ( j = 0; j < fvar_head.axisCount; ++j )+          ns->coords[j] = FT_GET_ULONG();     /* A Fixed */++        FT_FRAME_EXIT();+      }+    }++    if ( master != NULL )+    {+      FT_UInt  n;+++      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )+        goto Exit;+      FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );++      mmvar->axis =+        (FT_Var_Axis*)&(mmvar[1]);+      mmvar->namedstyle =+        (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]);+      next_coords =+        (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]);++      for ( n = 0; n < mmvar->num_namedstyles; ++n )+      {+        mmvar->namedstyle[n].coords  = next_coords;+        next_coords                 += mmvar->num_axis;+      }++      a = mmvar->axis;+      next_name = (FT_String*)next_coords;+      for ( n = 0; n < mmvar->num_axis; ++n )+      {+        a->name = next_name;++        /* standard PostScript names for some standard apple tags */+        if ( a->tag == TTAG_wght )+          a->name = (char *)"Weight";+        else if ( a->tag == TTAG_wdth )+          a->name = (char *)"Width";+        else if ( a->tag == TTAG_opsz )+          a->name = (char *)"OpticalSize";+        else if ( a->tag == TTAG_slnt )+          a->name = (char *)"Slant";++        next_name += 5;+        ++a;+      }++      *master = mmvar;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Set_MM_Blend                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Set the blend (normalized) coordinates for this instance of the    */+  /*    font.  Check that the `gvar' table is reasonable and does some     */+  /*    initial preparation.                                               */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The font.                                            */+  /*                  Initialize the blend structure with `gvar' data.     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    num_coords :: Must be the axis count of the font.                  */+  /*                                                                       */+  /*    coords     :: An array of num_coords, each between [-1,1].         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Set_MM_Blend( TT_Face    face,+                   FT_UInt    num_coords,+                   FT_Fixed*  coords )+  {+    FT_Error    error = TT_Err_Ok;+    GX_Blend    blend;+    FT_MM_Var*  mmvar;+    FT_UInt     i;+    FT_Memory   memory = face->root.memory;++    enum+    {+      mcvt_retain,+      mcvt_modify,+      mcvt_load++    } manageCvt;+++    face->doblend = FALSE;++    if ( face->blend == NULL )+    {+      if ( (error = TT_Get_MM_Var( face, NULL)) != 0 )+        goto Exit;+    }++    blend = face->blend;+    mmvar = blend->mmvar;++    if ( num_coords != mmvar->num_axis )+    {+      error = TT_Err_Invalid_Argument;+      goto Exit;+    }++    for ( i = 0; i < num_coords; ++i )+      if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )+      {+        error = TT_Err_Invalid_Argument;+        goto Exit;+      }++    if ( blend->glyphoffsets == NULL )+      if ( (error = ft_var_load_gvar( face )) != 0 )+        goto Exit;++    if ( blend->normalizedcoords == NULL )+    {+      if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) )+        goto Exit;++      manageCvt = mcvt_modify;++      /* If we have not set the blend coordinates before this, then the  */+      /* cvt table will still be what we read from the `cvt ' table and  */+      /* we don't need to reload it.  We may need to change it though... */+    }+    else+    {+      manageCvt = mcvt_retain;+      for ( i = 0; i < num_coords; ++i )+      {+        if ( blend->normalizedcoords[i] != coords[i] )+        {+          manageCvt = mcvt_load;+          break;+        }+      }++      /* If we don't change the blend coords then we don't need to do  */+      /* anything to the cvt table.  It will be correct.  Otherwise we */+      /* no longer have the original cvt (it was modified when we set  */+      /* the blend last time), so we must reload and then modify it.   */+    }++    blend->num_axis = num_coords;+    FT_MEM_COPY( blend->normalizedcoords,+                 coords,+                 num_coords * sizeof ( FT_Fixed ) );++    face->doblend = TRUE;++    if ( face->cvt != NULL )+    {+      switch ( manageCvt )+      {+      case mcvt_load:+        /* The cvt table has been loaded already; every time we change the */+        /* blend we may need to reload and remodify the cvt table.         */+        FT_FREE( face->cvt );+        face->cvt = NULL;++        tt_face_load_cvt( face, face->root.stream );+        break;++      case mcvt_modify:+        /* The original cvt table is in memory.  All we need to do is */+        /* apply the `cvar' table (if any).                           */+        tt_face_vary_cvt( face, face->root.stream );+        break;++      case mcvt_retain:+        /* The cvt table is correct for this set of coordinates. */+        break;+      }+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Set_Var_Design                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Set the coordinates for the instance, measured in the user         */+  /*    coordinate system.  Parse the `avar' table (if present) to convert */+  /*    from user to normalized coordinates.                               */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The font face.                                       */+  /*                  Initialize the blend struct with `gvar' data.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    num_coords :: This must be the axis count of the font.             */+  /*                                                                       */+  /*    coords     :: A coordinate array with `num_coords' elements.       */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Set_Var_Design( TT_Face    face,+                     FT_UInt    num_coords,+                     FT_Fixed*  coords )+  {+    FT_Error        error      = TT_Err_Ok;+    FT_Fixed*       normalized = NULL;+    GX_Blend        blend;+    FT_MM_Var*      mmvar;+    FT_UInt         i, j;+    FT_Var_Axis*    a;+    GX_AVarSegment  av;+    FT_Memory       memory = face->root.memory;+++    if ( face->blend == NULL )+    {+      if ( (error = TT_Get_MM_Var( face, NULL )) != 0 )+        goto Exit;+    }++    blend = face->blend;+    mmvar = blend->mmvar;++    if ( num_coords != mmvar->num_axis )+    {+      error = TT_Err_Invalid_Argument;+      goto Exit;+    }++    /* Axis normalization is a two stage process.  First we normalize */+    /* based on the [min,def,max] values for the axis to be [-1,0,1]. */+    /* Then, if there's an `avar' table, we renormalize this range.   */++    if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )+      goto Exit;++    a = mmvar->axis;+    for ( i = 0; i < mmvar->num_axis; ++i, ++a )+    {+      if ( coords[i] > a->maximum || coords[i] < a->minimum )+      {+        error = TT_Err_Invalid_Argument;+        goto Exit;+      }++      if ( coords[i] < a->def )+      {+        normalized[i] = -FT_MulDiv( coords[i] - a->def,+                                    0x10000L,+                                    a->minimum - a->def );+      }+      else if ( a->maximum == a->def )+        normalized[i] = 0;+      else+      {+        normalized[i] = FT_MulDiv( coords[i] - a->def,+                                   0x10000L,+                                   a->maximum - a->def );+      }+    }++    if ( !blend->avar_checked )+      ft_var_load_avar( face );++    if ( blend->avar_segment != NULL )+    {+      av = blend->avar_segment;+      for ( i = 0; i < mmvar->num_axis; ++i, ++av )+      {+        for ( j = 1; j < (FT_UInt)av->pairCount; ++j )+          if ( normalized[i] < av->correspondence[j].fromCoord )+          {+            normalized[i] =+              FT_MulDiv(+                FT_MulDiv(+                  normalized[i] - av->correspondence[j - 1].fromCoord,+                  0x10000L,+                  av->correspondence[j].fromCoord -+                    av->correspondence[j - 1].fromCoord ),+                av->correspondence[j].toCoord -+                  av->correspondence[j - 1].toCoord,+                0x10000L ) ++              av->correspondence[j - 1].toCoord;+            break;+          }+      }+    }++    error = TT_Set_MM_Blend( face, num_coords, normalized );++  Exit:+    FT_FREE( normalized );+    return error;+  }+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                     GX VAR PARSING ROUTINES                   *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_vary_cvt                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Modify the loaded cvt table according to the `cvar' table and the  */+  /*    font's blend.                                                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /*    Most errors are ignored.  It is perfectly valid not to have a      */+  /*    `cvar' table even if there is a `gvar' and `fvar' table.           */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_vary_cvt( TT_Face    face,+                    FT_Stream  stream )+  {+    FT_Error    error;+    FT_Memory   memory = stream->memory;+    FT_ULong    table_start;+    FT_ULong    table_len;+    FT_UInt     tupleCount;+    FT_ULong    offsetToData;+    FT_ULong    here;+    FT_UInt     i, j;+    FT_Fixed*   tuple_coords    = NULL;+    FT_Fixed*   im_start_coords = NULL;+    FT_Fixed*   im_end_coords   = NULL;+    GX_Blend    blend           = face->blend;+    FT_UInt     point_count;+    FT_UShort*  localpoints;+    FT_Short*   deltas;+++    FT_TRACE2(( "CVAR " ));++    if ( blend == NULL )+    {+      FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));++      error = TT_Err_Ok;+      goto Exit;+    }++    if ( face->cvt == NULL )+    {+      FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));++      error = TT_Err_Ok;+      goto Exit;+    }++    error = face->goto_table( face, TTAG_cvar, stream, &table_len );+    if ( error )+    {+      FT_TRACE2(( "is missing\n" ));++      error = TT_Err_Ok;+      goto Exit;+    }++    if ( FT_FRAME_ENTER( table_len ) )+    {+      error = TT_Err_Ok;+      goto Exit;+    }++    table_start = FT_Stream_FTell( stream );+    if ( FT_GET_LONG() != 0x00010000L )+    {+      FT_TRACE2(( "bad table version\n" ));++      error = TT_Err_Ok;+      goto FExit;+    }++    if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||+         FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||+         FT_NEW_ARRAY( im_end_coords, blend->num_axis )   )+      goto FExit;++    tupleCount   = FT_GET_USHORT();+    offsetToData = table_start + FT_GET_USHORT();++    /* The documentation implies there are flags packed into the        */+    /* tuplecount, but John Jenkins says that shared points don't apply */+    /* to `cvar', and no other flags are defined.                       */++    for ( i = 0; i < ( tupleCount & 0xFFF ); ++i )+    {+      FT_UInt   tupleDataSize;+      FT_UInt   tupleIndex;+      FT_Fixed  apply;+++      tupleDataSize = FT_GET_USHORT();+      tupleIndex    = FT_GET_USHORT();++      /* There is no provision here for a global tuple coordinate section, */+      /* so John says.  There are no tuple indices, just embedded tuples.  */++      if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )+      {+        for ( j = 0; j < blend->num_axis; ++j )+          tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from        */+                                                 /* short frac to fixed */+      }+      else+      {+        /* skip this tuple; it makes no sense */++        if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )+          for ( j = 0; j < 2 * blend->num_axis; ++j )+            (void)FT_GET_SHORT();++        offsetToData += tupleDataSize;+        continue;+      }++      if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )+      {+        for ( j = 0; j < blend->num_axis; ++j )+          im_start_coords[j] = FT_GET_SHORT() << 2;+        for ( j = 0; j < blend->num_axis; ++j )+          im_end_coords[j] = FT_GET_SHORT() << 2;+      }++      apply = ft_var_apply_tuple( blend,+                                  (FT_UShort)tupleIndex,+                                  tuple_coords,+                                  im_start_coords,+                                  im_end_coords );+      if ( /* tuple isn't active for our blend */+           apply == 0                                    ||+           /* global points not allowed,           */+           /* if they aren't local, makes no sense */+           !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) )+      {+        offsetToData += tupleDataSize;+        continue;+      }++      here = FT_Stream_FTell( stream );++      FT_Stream_SeekSet( stream, offsetToData );++      localpoints = ft_var_readpackedpoints( stream, &point_count );+      deltas      = ft_var_readpackeddeltas( stream,+                                             point_count == 0 ? face->cvt_size+                                                              : point_count );+      if ( localpoints == NULL || deltas == NULL )+        /* failure, ignore it */;++      else if ( localpoints == ALL_POINTS )+      {+        /* this means that there are deltas for every entry in cvt */+        for ( j = 0; j < face->cvt_size; ++j )+          face->cvt[j] = (FT_Short)( face->cvt[j] ++                                     FT_MulFix( deltas[j], apply ) );+      }++      else+      {+        for ( j = 0; j < point_count; ++j )+        {+          int  pindex = localpoints[j];++          face->cvt[pindex] = (FT_Short)( face->cvt[pindex] ++                                          FT_MulFix( deltas[j], apply ) );+        }+      }++      if ( localpoints != ALL_POINTS )+        FT_FREE( localpoints );+      FT_FREE( deltas );++      offsetToData += tupleDataSize;++      FT_Stream_SeekSet( stream, here );+    }++  FExit:+    FT_FRAME_EXIT();++  Exit:+    FT_FREE( tuple_coords );+    FT_FREE( im_start_coords );+    FT_FREE( im_end_coords );++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Vary_Get_Glyph_Deltas                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the appropriate deltas for the current glyph.                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to the target face object.                 */+  /*                                                                       */+  /*    glyph_index :: The index of the glyph being modified.              */+  /*                                                                       */+  /*    n_points    :: The number of the points in the glyph, including    */+  /*                   phantom points.                                     */+  /*                                                                       */+  /* <Output>                                                              */+  /*    deltas      :: The array of points to change.                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Vary_Get_Glyph_Deltas( TT_Face      face,+                            FT_UInt      glyph_index,+                            FT_Vector*  *deltas,+                            FT_UInt      n_points )+  {+    FT_Stream   stream = face->root.stream;+    FT_Memory   memory = stream->memory;+    GX_Blend    blend  = face->blend;+    FT_Vector*  delta_xy;++    FT_Error    error;+    FT_ULong    glyph_start;+    FT_UInt     tupleCount;+    FT_ULong    offsetToData;+    FT_ULong    here;+    FT_UInt     i, j;+    FT_Fixed*   tuple_coords    = NULL;+    FT_Fixed*   im_start_coords = NULL;+    FT_Fixed*   im_end_coords   = NULL;+    FT_UInt     point_count, spoint_count = 0;+    FT_UShort*  sharedpoints = NULL;+    FT_UShort*  localpoints  = NULL;+    FT_UShort*  points;+    FT_Short    *deltas_x, *deltas_y;+++    if ( !face->doblend || blend == NULL )+      return TT_Err_Invalid_Argument;++    /* to be freed by the caller */+    if ( FT_NEW_ARRAY( delta_xy, n_points ) )+      goto Exit;+    *deltas = delta_xy;++    if ( glyph_index >= blend->gv_glyphcnt      ||+         blend->glyphoffsets[glyph_index] ==+           blend->glyphoffsets[glyph_index + 1] )+      return TT_Err_Ok;               /* no variation data for this glyph */++    if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] )   ||+         FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] -+                           blend->glyphoffsets[glyph_index] ) )+      goto Fail1;++    glyph_start = FT_Stream_FTell( stream );++    /* each set of glyph variation data is formatted similarly to `cvar' */+    /* (except we get shared points and global tuples)                   */++    if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||+         FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||+         FT_NEW_ARRAY( im_end_coords, blend->num_axis )   )+      goto Fail2;++    tupleCount   = FT_GET_USHORT();+    offsetToData = glyph_start + FT_GET_USHORT();++    if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS )+    {+      here = FT_Stream_FTell( stream );++      FT_Stream_SeekSet( stream, offsetToData );++      sharedpoints = ft_var_readpackedpoints( stream, &spoint_count );+      offsetToData = FT_Stream_FTell( stream );++      FT_Stream_SeekSet( stream, here );+    }++    for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i )+    {+      FT_UInt   tupleDataSize;+      FT_UInt   tupleIndex;+      FT_Fixed  apply;+++      tupleDataSize = FT_GET_USHORT();+      tupleIndex    = FT_GET_USHORT();++      if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )+      {+        for ( j = 0; j < blend->num_axis; ++j )+          tuple_coords[j] = FT_GET_SHORT() << 2;  /* convert from        */+                                                  /* short frac to fixed */+      }+      else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )+      {+        error = TT_Err_Invalid_Table;+        goto Fail3;+      }+      else+      {+        FT_MEM_COPY(+          tuple_coords,+          &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis],+          blend->num_axis * sizeof ( FT_Fixed ) );+      }++      if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )+      {+        for ( j = 0; j < blend->num_axis; ++j )+          im_start_coords[j] = FT_GET_SHORT() << 2;+        for ( j = 0; j < blend->num_axis; ++j )+          im_end_coords[j] = FT_GET_SHORT() << 2;+      }++      apply = ft_var_apply_tuple( blend,+                                  (FT_UShort)tupleIndex,+                                  tuple_coords,+                                  im_start_coords,+                                  im_end_coords );++      if ( apply == 0 )              /* tuple isn't active for our blend */+      {+        offsetToData += tupleDataSize;+        continue;+      }++      here = FT_Stream_FTell( stream );++      if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS )+      {+        FT_Stream_SeekSet( stream, offsetToData );++        localpoints = ft_var_readpackedpoints( stream, &point_count );+        points      = localpoints;+      }+      else+      {+        points      = sharedpoints;+        point_count = spoint_count;+      }++      deltas_x = ft_var_readpackeddeltas( stream,+                                          point_count == 0 ? n_points+                                                           : point_count );+      deltas_y = ft_var_readpackeddeltas( stream,+                                          point_count == 0 ? n_points+                                                           : point_count );++      if ( points == NULL || deltas_y == NULL || deltas_x == NULL )+        ; /* failure, ignore it */++      else if ( points == ALL_POINTS )+      {+        /* this means that there are deltas for every point in the glyph */+        for ( j = 0; j < n_points; ++j )+        {+          delta_xy[j].x += FT_MulFix( deltas_x[j], apply );+          delta_xy[j].y += FT_MulFix( deltas_y[j], apply );+        }+      }++      else+      {+        for ( j = 0; j < point_count; ++j )+        {+          delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply );+          delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply );+        }+      }++      if ( localpoints != ALL_POINTS )+        FT_FREE( localpoints );+      FT_FREE( deltas_x );+      FT_FREE( deltas_y );++      offsetToData += tupleDataSize;++      FT_Stream_SeekSet( stream, here );+    }++  Fail3:+    FT_FREE( tuple_coords );+    FT_FREE( im_start_coords );+    FT_FREE( im_end_coords );++  Fail2:+    FT_FRAME_EXIT();++  Fail1:+    if ( error )+    {+      FT_FREE( delta_xy );+      *deltas = NULL;+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_done_blend                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Frees the blend internal data structure.                           */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_done_blend( FT_Memory  memory,+                 GX_Blend   blend )+  {+    if ( blend != NULL )+    {+      FT_UInt  i;+++      FT_FREE( blend->normalizedcoords );+      FT_FREE( blend->mmvar );++      if ( blend->avar_segment != NULL )+      {+        for ( i = 0; i < blend->num_axis; ++i )+          FT_FREE( blend->avar_segment[i].correspondence );+        FT_FREE( blend->avar_segment );+      }++      FT_FREE( blend->tuplecoords );+      FT_FREE( blend->glyphoffsets );+      FT_FREE( blend );+    }+  }++#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */+++/* END */
+ src/truetype/ttgxvar.h view
@@ -0,0 +1,182 @@+/***************************************************************************/+/*                                                                         */+/*  ttgxvar.h                                                              */+/*                                                                         */+/*    TrueType GX Font Variation loader (specification)                    */+/*                                                                         */+/*  Copyright 2004 by                                                      */+/*  David Turner, Robert Wilhelm, Werner Lemberg and George Williams.      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTGXVAR_H__+#define __TTGXVAR_H__+++#include <ft2build.h>+#include "ttobjs.h"+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    GX_AVarCorrespondenceRec                                           */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A data structure representing `shortFracCorrespondence' in `avar'  */+  /*    table according to the specifications from Apple.                  */+  /*                                                                       */+  typedef struct  GX_AVarCorrespondenceRec_+  {+    FT_Fixed  fromCoord;+    FT_Fixed  toCoord;++  } GX_AVarCorrespondenceRec_, *GX_AVarCorrespondence;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    GX_AVarRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Data from the segment field of `avar' table.                       */+  /*    There is one of these for each axis.                               */+  /*                                                                       */+  typedef struct  GX_AVarSegmentRec_+  {+    FT_UShort              pairCount;+    GX_AVarCorrespondence  correspondence; /* array with pairCount entries */++  } GX_AVarSegmentRec, *GX_AVarSegment;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    GX_BlendRec                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Data for interpolating a font from a distortable font specified    */+  /*    by the GX *var tables ([fgca]var).                                 */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    num_axis         :: The number of axes along which interpolation   */+  /*                         may happen                                    */+  /*                                                                       */+  /*    normalizedcoords :: A normalized value (between [-1,1]) indicating */+  /*                        the contribution along each axis to the final  */+  /*                        interpolated font.                             */+  /*                                                                       */+  typedef struct  GX_BlendRec_+  {+    FT_UInt         num_axis;+    FT_Fixed*       normalizedcoords;++    FT_MM_Var*      mmvar;+    FT_Offset       mmvar_len;++    FT_Bool         avar_checked;+    GX_AVarSegment  avar_segment;++    FT_UInt         tuplecount;      /* shared tuples in `gvar'           */+    FT_Fixed*       tuplecoords;     /* tuplecoords[tuplecount][num_axis] */++    FT_UInt         gv_glyphcnt;+    FT_ULong*       glyphoffsets;++  } GX_BlendRec;+++  /*************************************************************************/+  /*                                                                       */+  /* <enum>                                                                */+  /*    GX_TupleCountFlags                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Flags used within the `TupleCount' field of the `gvar' table.      */+  /*                                                                       */+  typedef enum  GX_TupleCountFlags_+  {+    GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000,+    GX_TC_RESERVED_TUPLE_FLAGS       = 0x7000,+    GX_TC_TUPLE_COUNT_MASK           = 0x0FFF++  } GX_TupleCountFlags;+++  /*************************************************************************/+  /*                                                                       */+  /* <enum>                                                                */+  /*    GX_TupleIndexFlags                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Flags used within the `TupleIndex' field of the `gvar' and `cvar'  */+  /*    tables.                                                            */+  /*                                                                       */+  typedef enum  GX_TupleIndexFlags_+  {+    GX_TI_EMBEDDED_TUPLE_COORD  = 0x8000,+    GX_TI_INTERMEDIATE_TUPLE    = 0x4000,+    GX_TI_PRIVATE_POINT_NUMBERS = 0x2000,+    GX_TI_RESERVED_TUPLE_FLAG   = 0x1000,+    GX_TI_TUPLE_INDEX_MASK      = 0x0FFF++  } GX_TupleIndexFlags;+++#define TTAG_wght  FT_MAKE_TAG( 'w', 'g', 'h', 't' )+#define TTAG_wdth  FT_MAKE_TAG( 'w', 'd', 't', 'h' )+#define TTAG_opsz  FT_MAKE_TAG( 'o', 'p', 's', 'z' )+#define TTAG_slnt  FT_MAKE_TAG( 's', 'l', 'n', 't' )+++  FT_LOCAL( FT_Error )+  TT_Set_MM_Blend( TT_Face    face,+                   FT_UInt    num_coords,+                   FT_Fixed*  coords );++  FT_LOCAL( FT_Error )+  TT_Set_Var_Design( TT_Face    face,+                     FT_UInt    num_coords,+                     FT_Fixed*  coords );++  FT_LOCAL( FT_Error )+  TT_Get_MM_Var( TT_Face      face,+                 FT_MM_Var*  *master );+++  FT_LOCAL( FT_Error )+  tt_face_vary_cvt( TT_Face    face,+                    FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  TT_Vary_Get_Glyph_Deltas( TT_Face      face,+                            FT_UInt      glyph_index,+                            FT_Vector*  *deltas,+                            FT_UInt      n_points );+++  FT_LOCAL( void )+  tt_done_blend( FT_Memory  memory,+                 GX_Blend   blend );+++FT_END_HEADER+++#endif /* __TTGXVAR_H__ */+++/* END */
+ src/truetype/ttinterp.c view
@@ -0,0 +1,8160 @@+/***************************************************************************/+/*                                                                         */+/*  ttinterp.c                                                             */+/*                                                                         */+/*    TrueType bytecode interpreter (body).                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010                                                         */+/*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_CALC_H+#include FT_TRIGONOMETRY_H+#include FT_SYSTEM_H++#include "ttinterp.h"++#include "tterrors.h"+++#ifdef TT_USE_BYTECODE_INTERPRETER+++#define TT_MULFIX           FT_MulFix+#define TT_MULDIV           FT_MulDiv+#define TT_MULDIV_NO_ROUND  FT_MulDiv_No_Round+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttinterp++  /*************************************************************************/+  /*                                                                       */+  /* In order to detect infinite loops in the code, we set up a counter    */+  /* within the run loop.  A single stroke of interpretation is now        */+  /* limited to a maximal number of opcodes defined below.                 */+  /*                                                                       */+#define MAX_RUNNABLE_OPCODES  1000000L+++  /*************************************************************************/+  /*                                                                       */+  /* There are two kinds of implementations:                               */+  /*                                                                       */+  /* a. static implementation                                              */+  /*                                                                       */+  /*    The current execution context is a static variable, which fields   */+  /*    are accessed directly by the interpreter during execution.  The    */+  /*    context is named `cur'.                                            */+  /*                                                                       */+  /*    This version is non-reentrant, of course.                          */+  /*                                                                       */+  /* b. indirect implementation                                            */+  /*                                                                       */+  /*    The current execution context is passed to _each_ function as its  */+  /*    first argument, and each field is thus accessed indirectly.        */+  /*                                                                       */+  /*    This version is fully re-entrant.                                  */+  /*                                                                       */+  /* The idea is that an indirect implementation may be slower to execute  */+  /* on low-end processors that are used in some systems (like 386s or     */+  /* even 486s).                                                           */+  /*                                                                       */+  /* As a consequence, the indirect implementation is now the default, as  */+  /* its performance costs can be considered negligible in our context.    */+  /* Note, however, that we kept the same source with macros because:      */+  /*                                                                       */+  /* - The code is kept very close in design to the Pascal code used for   */+  /*   development.                                                        */+  /*                                                                       */+  /* - It's much more readable that way!                                   */+  /*                                                                       */+  /* - It's still open to experimentation and tuning.                      */+  /*                                                                       */+  /*************************************************************************/+++#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */++#define CUR  (*exc)                             /* see ttobjs.h */++  /*************************************************************************/+  /*                                                                       */+  /* This macro is used whenever `exec' is unused in a function, to avoid  */+  /* stupid warnings from pedantic compilers.                              */+  /*                                                                       */+#define FT_UNUSED_EXEC  FT_UNUSED( exc )++#else                                           /* static implementation */++#define CUR  cur++#define FT_UNUSED_EXEC  int  __dummy = __dummy++  static+  TT_ExecContextRec  cur;   /* static exec. context variable */++  /* apparently, we have a _lot_ of direct indexing when accessing  */+  /* the static `cur', which makes the code bigger (due to all the  */+  /* four bytes addresses).                                         */++#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */+++  /*************************************************************************/+  /*                                                                       */+  /* The instruction argument stack.                                       */+  /*                                                                       */+#define INS_ARG  EXEC_OP_ FT_Long*  args    /* see ttobjs.h for EXEC_OP_ */+++  /*************************************************************************/+  /*                                                                       */+  /* This macro is used whenever `args' is unused in a function, to avoid  */+  /* stupid warnings from pedantic compilers.                              */+  /*                                                                       */+#define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )+++  /*************************************************************************/+  /*                                                                       */+  /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */+  /* increase readability of the code.                                     */+  /*                                                                       */+  /*************************************************************************/+++#define SKIP_Code() \+          SkipCode( EXEC_ARG )++#define GET_ShortIns() \+          GetShortIns( EXEC_ARG )++#define NORMalize( x, y, v ) \+          Normalize( EXEC_ARG_ x, y, v )++#define SET_SuperRound( scale, flags ) \+          SetSuperRound( EXEC_ARG_ scale, flags )++#define ROUND_None( d, c ) \+          Round_None( EXEC_ARG_ d, c )++#define INS_Goto_CodeRange( range, ip ) \+          Ins_Goto_CodeRange( EXEC_ARG_ range, ip )++#define CUR_Func_move( z, p, d ) \+          CUR.func_move( EXEC_ARG_ z, p, d )++#define CUR_Func_move_orig( z, p, d ) \+          CUR.func_move_orig( EXEC_ARG_ z, p, d )++#define CUR_Func_round( d, c ) \+          CUR.func_round( EXEC_ARG_ d, c )++#define CUR_Func_read_cvt( index ) \+          CUR.func_read_cvt( EXEC_ARG_ index )++#define CUR_Func_write_cvt( index, val ) \+          CUR.func_write_cvt( EXEC_ARG_ index, val )++#define CUR_Func_move_cvt( index, val ) \+          CUR.func_move_cvt( EXEC_ARG_ index, val )++#define CURRENT_Ratio() \+          Current_Ratio( EXEC_ARG )++#define CURRENT_Ppem() \+          Current_Ppem( EXEC_ARG )++#define CUR_Ppem() \+          Cur_PPEM( EXEC_ARG )++#define INS_SxVTL( a, b, c, d ) \+          Ins_SxVTL( EXEC_ARG_ a, b, c, d )++#define COMPUTE_Funcs() \+          Compute_Funcs( EXEC_ARG )++#define COMPUTE_Round( a ) \+          Compute_Round( EXEC_ARG_ a )++#define COMPUTE_Point_Displacement( a, b, c, d ) \+          Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )++#define MOVE_Zp2_Point( a, b, c, t ) \+          Move_Zp2_Point( EXEC_ARG_ a, b, c, t )+++#define CUR_Func_project( v1, v2 )  \+          CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )++#define CUR_Func_dualproj( v1, v2 )  \+          CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )++#define CUR_fast_project( v ) \+          CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )++#define CUR_fast_dualproj( v ) \+          CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )+++  /*************************************************************************/+  /*                                                                       */+  /* Instruction dispatch function, as used by the interpreter.            */+  /*                                                                       */+  typedef void  (*TInstruction_Function)( INS_ARG );+++  /*************************************************************************/+  /*                                                                       */+  /* Two simple bounds-checking macros.                                    */+  /*                                                                       */+#define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )+#define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )++#undef  SUCCESS+#define SUCCESS  0++#undef  FAILURE+#define FAILURE  1++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+#define GUESS_VECTOR( V )                                         \+  if ( CUR.face->unpatented_hinting )                             \+  {                                                               \+    CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \+    CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \+  }+#else+#define GUESS_VECTOR( V )+#endif++  /*************************************************************************/+  /*                                                                       */+  /*                        CODERANGE FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Goto_CodeRange                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Switches to a new code range (updates the code related elements in */+  /*    `exec', and `IP').                                                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range :: The new execution code range.                             */+  /*                                                                       */+  /*    IP    :: The new IP in the new code range.                         */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    exec  :: The target execution context.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Goto_CodeRange( TT_ExecContext  exec,+                     FT_Int          range,+                     FT_Long         IP )+  {+    TT_CodeRange*  coderange;+++    FT_ASSERT( range >= 1 && range <= 3 );++    coderange = &exec->codeRangeTable[range - 1];++    FT_ASSERT( coderange->base != NULL );++    /* NOTE: Because the last instruction of a program may be a CALL */+    /*       which will return to the first byte *after* the code    */+    /*       range, we test for IP <= Size instead of IP < Size.     */+    /*                                                               */+    FT_ASSERT( (FT_ULong)IP <= coderange->size );++    exec->code     = coderange->base;+    exec->codeSize = coderange->size;+    exec->IP       = IP;+    exec->curRange = range;++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Set_CodeRange                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Sets a code range.                                                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range  :: The code range index.                                    */+  /*                                                                       */+  /*    base   :: The new code base.                                       */+  /*                                                                       */+  /*    length :: The range size in bytes.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    exec   :: The target execution context.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Set_CodeRange( TT_ExecContext  exec,+                    FT_Int          range,+                    void*           base,+                    FT_Long         length )+  {+    FT_ASSERT( range >= 1 && range <= 3 );++    exec->codeRangeTable[range - 1].base = (FT_Byte*)base;+    exec->codeRangeTable[range - 1].size = length;++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Clear_CodeRange                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Clears a code range.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    range :: The code range index.                                     */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    exec  :: The target execution context.                             */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Does not set the Error variable.                                   */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Clear_CodeRange( TT_ExecContext  exec,+                      FT_Int          range )+  {+    FT_ASSERT( range >= 1 && range <= 3 );++    exec->codeRangeTable[range - 1].base = NULL;+    exec->codeRangeTable[range - 1].size = 0;++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                   EXECUTION CONTEXT ROUTINES                          */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Done_Context                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Destroys a given context.                                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    exec   :: A handle to the target execution context.                */+  /*                                                                       */+  /*    memory :: A handle to the parent memory object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the glyph loader and debugger should call this function.      */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Done_Context( TT_ExecContext  exec )+  {+    FT_Memory  memory = exec->memory;+++    /* points zone */+    exec->maxPoints   = 0;+    exec->maxContours = 0;++    /* free stack */+    FT_FREE( exec->stack );+    exec->stackSize = 0;++    /* free call stack */+    FT_FREE( exec->callStack );+    exec->callSize = 0;+    exec->callTop  = 0;++    /* free glyph code range */+    FT_FREE( exec->glyphIns );+    exec->glyphSize = 0;++    exec->size = NULL;+    exec->face = NULL;++    FT_FREE( exec );++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Init_Context                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a context object.                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory :: A handle to the parent memory object.                    */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    exec   :: A handle to the target execution context.                */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  static FT_Error+  Init_Context( TT_ExecContext  exec,+                FT_Memory       memory )+  {+    FT_Error  error;+++    FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));++    exec->memory   = memory;+    exec->callSize = 32;++    if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) )+      goto Fail_Memory;++    /* all values in the context are set to 0 already, but this is */+    /* here as a remainder                                         */+    exec->maxPoints   = 0;+    exec->maxContours = 0;++    exec->stackSize = 0;+    exec->glyphSize = 0;++    exec->stack     = NULL;+    exec->glyphIns  = NULL;++    exec->face = NULL;+    exec->size = NULL;++    return TT_Err_Ok;++  Fail_Memory:+    FT_ERROR(( "Init_Context: not enough memory for %p\n", exec ));+    TT_Done_Context( exec );++    return error;+ }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Update_Max                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Checks the size of a buffer and reallocates it if necessary.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory     :: A handle to the parent memory object.                */+  /*                                                                       */+  /*    multiplier :: The size in bytes of each element in the buffer.     */+  /*                                                                       */+  /*    new_max    :: The new capacity (size) of the buffer.               */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    size       :: The address of the buffer's current size expressed   */+  /*                  in elements.                                         */+  /*                                                                       */+  /*    buff       :: The address of the buffer base pointer.              */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  Update_Max( FT_Memory  memory,+              FT_ULong*  size,+              FT_Long    multiplier,+              void*      _pbuff,+              FT_ULong   new_max )+  {+    FT_Error  error;+    void**    pbuff = (void**)_pbuff;+++    if ( *size < new_max )+    {+      if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )+        return error;+      *size = new_max;+    }++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Load_Context                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Prepare an execution context for glyph hinting.                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source face object.                        */+  /*                                                                       */+  /*    size :: A handle to the source size object.                        */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    exec :: A handle to the target execution context.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the glyph loader and debugger should call this function.      */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Load_Context( TT_ExecContext  exec,+                   TT_Face         face,+                   TT_Size         size )+  {+    FT_Int          i;+    FT_ULong        tmp;+    TT_MaxProfile*  maxp;+    FT_Error        error;+++    exec->face = face;+    maxp       = &face->max_profile;+    exec->size = size;++    if ( size )+    {+      exec->numFDefs   = size->num_function_defs;+      exec->maxFDefs   = size->max_function_defs;+      exec->numIDefs   = size->num_instruction_defs;+      exec->maxIDefs   = size->max_instruction_defs;+      exec->FDefs      = size->function_defs;+      exec->IDefs      = size->instruction_defs;+      exec->tt_metrics = size->ttmetrics;+      exec->metrics    = size->metrics;++      exec->maxFunc    = size->max_func;+      exec->maxIns     = size->max_ins;++      for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )+        exec->codeRangeTable[i] = size->codeRangeTable[i];++      /* set graphics state */+      exec->GS = size->GS;++      exec->cvtSize = size->cvt_size;+      exec->cvt     = size->cvt;++      exec->storeSize = size->storage_size;+      exec->storage   = size->storage;++      exec->twilight  = size->twilight;++      /* In case of multi-threading it can happen that the old size object */+      /* no longer exists, thus we must clear all glyph zone references.   */+      ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) );+      exec->zp1 = exec->zp0;+      exec->zp2 = exec->zp0;+    }++    /* XXX: We reserve a little more elements on the stack to deal safely */+    /*      with broken fonts like arialbs, courbs, timesbs, etc.         */+    tmp = exec->stackSize;+    error = Update_Max( exec->memory,+                        &tmp,+                        sizeof ( FT_F26Dot6 ),+                        (void*)&exec->stack,+                        maxp->maxStackElements + 32 );+    exec->stackSize = (FT_UInt)tmp;+    if ( error )+      return error;++    tmp = exec->glyphSize;+    error = Update_Max( exec->memory,+                        &tmp,+                        sizeof ( FT_Byte ),+                        (void*)&exec->glyphIns,+                        maxp->maxSizeOfInstructions );+    exec->glyphSize = (FT_UShort)tmp;+    if ( error )+      return error;++    exec->pts.n_points   = 0;+    exec->pts.n_contours = 0;++    exec->zp1 = exec->pts;+    exec->zp2 = exec->pts;+    exec->zp0 = exec->pts;++    exec->instruction_trap = FALSE;++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Save_Context                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Saves the code ranges in a `size' object.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    exec :: A handle to the source execution context.                  */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    size :: A handle to the target size object.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the glyph loader and debugger should call this function.      */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Save_Context( TT_ExecContext  exec,+                   TT_Size         size )+  {+    FT_Int  i;+++    /* XXXX: Will probably disappear soon with all the code range */+    /*       management, which is now rather obsolete.            */+    /*                                                            */+    size->num_function_defs    = exec->numFDefs;+    size->num_instruction_defs = exec->numIDefs;++    size->max_func = exec->maxFunc;+    size->max_ins  = exec->maxIns;++    for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )+      size->codeRangeTable[i] = exec->codeRangeTable[i];++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_Run_Context                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Executes one or more instructions in the execution context.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    debug :: A Boolean flag.  If set, the function sets some internal  */+  /*             variables and returns immediately, otherwise TT_RunIns()  */+  /*             is called.                                                */+  /*                                                                       */+  /*             This is commented out currently.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    exec  :: A handle to the target execution context.                 */+  /*                                                                       */+  /* <Return>                                                              */+  /*    TrueType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the glyph loader and debugger should call this function.      */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  TT_Run_Context( TT_ExecContext  exec,+                  FT_Bool         debug )+  {+    FT_Error  error;+++    if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0  ) )+           != TT_Err_Ok )+      return error;++    exec->zp0 = exec->pts;+    exec->zp1 = exec->pts;+    exec->zp2 = exec->pts;++    exec->GS.gep0 = 1;+    exec->GS.gep1 = 1;+    exec->GS.gep2 = 1;++    exec->GS.projVector.x = 0x4000;+    exec->GS.projVector.y = 0x0000;++    exec->GS.freeVector = exec->GS.projVector;+    exec->GS.dualVector = exec->GS.projVector;++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    exec->GS.both_x_axis = TRUE;+#endif++    exec->GS.round_state = 1;+    exec->GS.loop        = 1;++    /* some glyphs leave something on the stack. so we clean it */+    /* before a new execution.                                  */+    exec->top     = 0;+    exec->callTop = 0;++#if 1+    FT_UNUSED( debug );++    return exec->face->interpreter( exec );+#else+    if ( !debug )+      return TT_RunIns( exec );+    else+      return TT_Err_Ok;+#endif+  }+++  /* The default value for `scan_control' is documented as FALSE in the */+  /* TrueType specification.  This is confusing since it implies a      */+  /* Boolean value.  However, this is not the case, thus both the       */+  /* default values of our `scan_type' and `scan_control' fields (which */+  /* the documentation's `scan_control' variable is split into) are     */+  /* zero.                                                              */++  const TT_GraphicsState  tt_default_graphics_state =+  {+    0, 0, 0,+    { 0x4000, 0 },+    { 0x4000, 0 },+    { 0x4000, 0 },++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    TRUE,+#endif++    1, 64, 1,+    TRUE, 68, 0, 0, 9, 3,+    0, FALSE, 0, 1, 1, 1+  };+++  /* documentation is in ttinterp.h */++  FT_EXPORT_DEF( TT_ExecContext )+  TT_New_Context( TT_Driver  driver )+  {+    TT_ExecContext  exec;+    FT_Memory       memory;+++    memory = driver->root.root.memory;+    exec   = driver->context;++    if ( !driver->context )+    {+      FT_Error  error;+++      /* allocate object */+      if ( FT_NEW( exec ) )+        goto Fail;++      /* initialize it; in case of error this deallocates `exec' too */+      error = Init_Context( exec, memory );+      if ( error )+        goto Fail;++      /* store it into the driver */+      driver->context = exec;+    }++    return driver->context;++  Fail:+    return NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Before an opcode is executed, the interpreter verifies that there are */+  /* enough arguments on the stack, with the help of the `Pop_Push_Count'  */+  /* table.                                                                */+  /*                                                                       */+  /* For each opcode, the first column gives the number of arguments that  */+  /* are popped from the stack; the second one gives the number of those   */+  /* that are pushed in result.                                            */+  /*                                                                       */+  /* Opcodes which have a varying number of parameters in the data stream  */+  /* (NPUSHB, NPUSHW) are handled specially; they have a negative value in */+  /* the `opcode_length' table, and the value in `Pop_Push_Count' is set   */+  /* to zero.                                                              */+  /*                                                                       */+  /*************************************************************************/+++#undef  PACK+#define PACK( x, y )  ( ( x << 4 ) | y )+++  static+  const FT_Byte  Pop_Push_Count[256] =+  {+    /* opcodes are gathered in groups of 16 */+    /* please keep the spaces as they are   */++    /*  SVTCA  y  */  PACK( 0, 0 ),+    /*  SVTCA  x  */  PACK( 0, 0 ),+    /*  SPvTCA y  */  PACK( 0, 0 ),+    /*  SPvTCA x  */  PACK( 0, 0 ),+    /*  SFvTCA y  */  PACK( 0, 0 ),+    /*  SFvTCA x  */  PACK( 0, 0 ),+    /*  SPvTL //  */  PACK( 2, 0 ),+    /*  SPvTL +   */  PACK( 2, 0 ),+    /*  SFvTL //  */  PACK( 2, 0 ),+    /*  SFvTL +   */  PACK( 2, 0 ),+    /*  SPvFS     */  PACK( 2, 0 ),+    /*  SFvFS     */  PACK( 2, 0 ),+    /*  GPV       */  PACK( 0, 2 ),+    /*  GFV       */  PACK( 0, 2 ),+    /*  SFvTPv    */  PACK( 0, 0 ),+    /*  ISECT     */  PACK( 5, 0 ),++    /*  SRP0      */  PACK( 1, 0 ),+    /*  SRP1      */  PACK( 1, 0 ),+    /*  SRP2      */  PACK( 1, 0 ),+    /*  SZP0      */  PACK( 1, 0 ),+    /*  SZP1      */  PACK( 1, 0 ),+    /*  SZP2      */  PACK( 1, 0 ),+    /*  SZPS      */  PACK( 1, 0 ),+    /*  SLOOP     */  PACK( 1, 0 ),+    /*  RTG       */  PACK( 0, 0 ),+    /*  RTHG      */  PACK( 0, 0 ),+    /*  SMD       */  PACK( 1, 0 ),+    /*  ELSE      */  PACK( 0, 0 ),+    /*  JMPR      */  PACK( 1, 0 ),+    /*  SCvTCi    */  PACK( 1, 0 ),+    /*  SSwCi     */  PACK( 1, 0 ),+    /*  SSW       */  PACK( 1, 0 ),++    /*  DUP       */  PACK( 1, 2 ),+    /*  POP       */  PACK( 1, 0 ),+    /*  CLEAR     */  PACK( 0, 0 ),+    /*  SWAP      */  PACK( 2, 2 ),+    /*  DEPTH     */  PACK( 0, 1 ),+    /*  CINDEX    */  PACK( 1, 1 ),+    /*  MINDEX    */  PACK( 1, 0 ),+    /*  AlignPTS  */  PACK( 2, 0 ),+    /*  INS_$28   */  PACK( 0, 0 ),+    /*  UTP       */  PACK( 1, 0 ),+    /*  LOOPCALL  */  PACK( 2, 0 ),+    /*  CALL      */  PACK( 1, 0 ),+    /*  FDEF      */  PACK( 1, 0 ),+    /*  ENDF      */  PACK( 0, 0 ),+    /*  MDAP[0]   */  PACK( 1, 0 ),+    /*  MDAP[1]   */  PACK( 1, 0 ),++    /*  IUP[0]    */  PACK( 0, 0 ),+    /*  IUP[1]    */  PACK( 0, 0 ),+    /*  SHP[0]    */  PACK( 0, 0 ),+    /*  SHP[1]    */  PACK( 0, 0 ),+    /*  SHC[0]    */  PACK( 1, 0 ),+    /*  SHC[1]    */  PACK( 1, 0 ),+    /*  SHZ[0]    */  PACK( 1, 0 ),+    /*  SHZ[1]    */  PACK( 1, 0 ),+    /*  SHPIX     */  PACK( 1, 0 ),+    /*  IP        */  PACK( 0, 0 ),+    /*  MSIRP[0]  */  PACK( 2, 0 ),+    /*  MSIRP[1]  */  PACK( 2, 0 ),+    /*  AlignRP   */  PACK( 0, 0 ),+    /*  RTDG      */  PACK( 0, 0 ),+    /*  MIAP[0]   */  PACK( 2, 0 ),+    /*  MIAP[1]   */  PACK( 2, 0 ),++    /*  NPushB    */  PACK( 0, 0 ),+    /*  NPushW    */  PACK( 0, 0 ),+    /*  WS        */  PACK( 2, 0 ),+    /*  RS        */  PACK( 1, 1 ),+    /*  WCvtP     */  PACK( 2, 0 ),+    /*  RCvt      */  PACK( 1, 1 ),+    /*  GC[0]     */  PACK( 1, 1 ),+    /*  GC[1]     */  PACK( 1, 1 ),+    /*  SCFS      */  PACK( 2, 0 ),+    /*  MD[0]     */  PACK( 2, 1 ),+    /*  MD[1]     */  PACK( 2, 1 ),+    /*  MPPEM     */  PACK( 0, 1 ),+    /*  MPS       */  PACK( 0, 1 ),+    /*  FlipON    */  PACK( 0, 0 ),+    /*  FlipOFF   */  PACK( 0, 0 ),+    /*  DEBUG     */  PACK( 1, 0 ),++    /*  LT        */  PACK( 2, 1 ),+    /*  LTEQ      */  PACK( 2, 1 ),+    /*  GT        */  PACK( 2, 1 ),+    /*  GTEQ      */  PACK( 2, 1 ),+    /*  EQ        */  PACK( 2, 1 ),+    /*  NEQ       */  PACK( 2, 1 ),+    /*  ODD       */  PACK( 1, 1 ),+    /*  EVEN      */  PACK( 1, 1 ),+    /*  IF        */  PACK( 1, 0 ),+    /*  EIF       */  PACK( 0, 0 ),+    /*  AND       */  PACK( 2, 1 ),+    /*  OR        */  PACK( 2, 1 ),+    /*  NOT       */  PACK( 1, 1 ),+    /*  DeltaP1   */  PACK( 1, 0 ),+    /*  SDB       */  PACK( 1, 0 ),+    /*  SDS       */  PACK( 1, 0 ),++    /*  ADD       */  PACK( 2, 1 ),+    /*  SUB       */  PACK( 2, 1 ),+    /*  DIV       */  PACK( 2, 1 ),+    /*  MUL       */  PACK( 2, 1 ),+    /*  ABS       */  PACK( 1, 1 ),+    /*  NEG       */  PACK( 1, 1 ),+    /*  FLOOR     */  PACK( 1, 1 ),+    /*  CEILING   */  PACK( 1, 1 ),+    /*  ROUND[0]  */  PACK( 1, 1 ),+    /*  ROUND[1]  */  PACK( 1, 1 ),+    /*  ROUND[2]  */  PACK( 1, 1 ),+    /*  ROUND[3]  */  PACK( 1, 1 ),+    /*  NROUND[0] */  PACK( 1, 1 ),+    /*  NROUND[1] */  PACK( 1, 1 ),+    /*  NROUND[2] */  PACK( 1, 1 ),+    /*  NROUND[3] */  PACK( 1, 1 ),++    /*  WCvtF     */  PACK( 2, 0 ),+    /*  DeltaP2   */  PACK( 1, 0 ),+    /*  DeltaP3   */  PACK( 1, 0 ),+    /*  DeltaCn[0] */ PACK( 1, 0 ),+    /*  DeltaCn[1] */ PACK( 1, 0 ),+    /*  DeltaCn[2] */ PACK( 1, 0 ),+    /*  SROUND    */  PACK( 1, 0 ),+    /*  S45Round  */  PACK( 1, 0 ),+    /*  JROT      */  PACK( 2, 0 ),+    /*  JROF      */  PACK( 2, 0 ),+    /*  ROFF      */  PACK( 0, 0 ),+    /*  INS_$7B   */  PACK( 0, 0 ),+    /*  RUTG      */  PACK( 0, 0 ),+    /*  RDTG      */  PACK( 0, 0 ),+    /*  SANGW     */  PACK( 1, 0 ),+    /*  AA        */  PACK( 1, 0 ),++    /*  FlipPT    */  PACK( 0, 0 ),+    /*  FlipRgON  */  PACK( 2, 0 ),+    /*  FlipRgOFF */  PACK( 2, 0 ),+    /*  INS_$83   */  PACK( 0, 0 ),+    /*  INS_$84   */  PACK( 0, 0 ),+    /*  ScanCTRL  */  PACK( 1, 0 ),+    /*  SDVPTL[0] */  PACK( 2, 0 ),+    /*  SDVPTL[1] */  PACK( 2, 0 ),+    /*  GetINFO   */  PACK( 1, 1 ),+    /*  IDEF      */  PACK( 1, 0 ),+    /*  ROLL      */  PACK( 3, 3 ),+    /*  MAX       */  PACK( 2, 1 ),+    /*  MIN       */  PACK( 2, 1 ),+    /*  ScanTYPE  */  PACK( 1, 0 ),+    /*  InstCTRL  */  PACK( 2, 0 ),+    /*  INS_$8F   */  PACK( 0, 0 ),++    /*  INS_$90  */   PACK( 0, 0 ),+    /*  INS_$91  */   PACK( 0, 0 ),+    /*  INS_$92  */   PACK( 0, 0 ),+    /*  INS_$93  */   PACK( 0, 0 ),+    /*  INS_$94  */   PACK( 0, 0 ),+    /*  INS_$95  */   PACK( 0, 0 ),+    /*  INS_$96  */   PACK( 0, 0 ),+    /*  INS_$97  */   PACK( 0, 0 ),+    /*  INS_$98  */   PACK( 0, 0 ),+    /*  INS_$99  */   PACK( 0, 0 ),+    /*  INS_$9A  */   PACK( 0, 0 ),+    /*  INS_$9B  */   PACK( 0, 0 ),+    /*  INS_$9C  */   PACK( 0, 0 ),+    /*  INS_$9D  */   PACK( 0, 0 ),+    /*  INS_$9E  */   PACK( 0, 0 ),+    /*  INS_$9F  */   PACK( 0, 0 ),++    /*  INS_$A0  */   PACK( 0, 0 ),+    /*  INS_$A1  */   PACK( 0, 0 ),+    /*  INS_$A2  */   PACK( 0, 0 ),+    /*  INS_$A3  */   PACK( 0, 0 ),+    /*  INS_$A4  */   PACK( 0, 0 ),+    /*  INS_$A5  */   PACK( 0, 0 ),+    /*  INS_$A6  */   PACK( 0, 0 ),+    /*  INS_$A7  */   PACK( 0, 0 ),+    /*  INS_$A8  */   PACK( 0, 0 ),+    /*  INS_$A9  */   PACK( 0, 0 ),+    /*  INS_$AA  */   PACK( 0, 0 ),+    /*  INS_$AB  */   PACK( 0, 0 ),+    /*  INS_$AC  */   PACK( 0, 0 ),+    /*  INS_$AD  */   PACK( 0, 0 ),+    /*  INS_$AE  */   PACK( 0, 0 ),+    /*  INS_$AF  */   PACK( 0, 0 ),++    /*  PushB[0]  */  PACK( 0, 1 ),+    /*  PushB[1]  */  PACK( 0, 2 ),+    /*  PushB[2]  */  PACK( 0, 3 ),+    /*  PushB[3]  */  PACK( 0, 4 ),+    /*  PushB[4]  */  PACK( 0, 5 ),+    /*  PushB[5]  */  PACK( 0, 6 ),+    /*  PushB[6]  */  PACK( 0, 7 ),+    /*  PushB[7]  */  PACK( 0, 8 ),+    /*  PushW[0]  */  PACK( 0, 1 ),+    /*  PushW[1]  */  PACK( 0, 2 ),+    /*  PushW[2]  */  PACK( 0, 3 ),+    /*  PushW[3]  */  PACK( 0, 4 ),+    /*  PushW[4]  */  PACK( 0, 5 ),+    /*  PushW[5]  */  PACK( 0, 6 ),+    /*  PushW[6]  */  PACK( 0, 7 ),+    /*  PushW[7]  */  PACK( 0, 8 ),++    /*  MDRP[00]  */  PACK( 1, 0 ),+    /*  MDRP[01]  */  PACK( 1, 0 ),+    /*  MDRP[02]  */  PACK( 1, 0 ),+    /*  MDRP[03]  */  PACK( 1, 0 ),+    /*  MDRP[04]  */  PACK( 1, 0 ),+    /*  MDRP[05]  */  PACK( 1, 0 ),+    /*  MDRP[06]  */  PACK( 1, 0 ),+    /*  MDRP[07]  */  PACK( 1, 0 ),+    /*  MDRP[08]  */  PACK( 1, 0 ),+    /*  MDRP[09]  */  PACK( 1, 0 ),+    /*  MDRP[10]  */  PACK( 1, 0 ),+    /*  MDRP[11]  */  PACK( 1, 0 ),+    /*  MDRP[12]  */  PACK( 1, 0 ),+    /*  MDRP[13]  */  PACK( 1, 0 ),+    /*  MDRP[14]  */  PACK( 1, 0 ),+    /*  MDRP[15]  */  PACK( 1, 0 ),++    /*  MDRP[16]  */  PACK( 1, 0 ),+    /*  MDRP[17]  */  PACK( 1, 0 ),+    /*  MDRP[18]  */  PACK( 1, 0 ),+    /*  MDRP[19]  */  PACK( 1, 0 ),+    /*  MDRP[20]  */  PACK( 1, 0 ),+    /*  MDRP[21]  */  PACK( 1, 0 ),+    /*  MDRP[22]  */  PACK( 1, 0 ),+    /*  MDRP[23]  */  PACK( 1, 0 ),+    /*  MDRP[24]  */  PACK( 1, 0 ),+    /*  MDRP[25]  */  PACK( 1, 0 ),+    /*  MDRP[26]  */  PACK( 1, 0 ),+    /*  MDRP[27]  */  PACK( 1, 0 ),+    /*  MDRP[28]  */  PACK( 1, 0 ),+    /*  MDRP[29]  */  PACK( 1, 0 ),+    /*  MDRP[30]  */  PACK( 1, 0 ),+    /*  MDRP[31]  */  PACK( 1, 0 ),++    /*  MIRP[00]  */  PACK( 2, 0 ),+    /*  MIRP[01]  */  PACK( 2, 0 ),+    /*  MIRP[02]  */  PACK( 2, 0 ),+    /*  MIRP[03]  */  PACK( 2, 0 ),+    /*  MIRP[04]  */  PACK( 2, 0 ),+    /*  MIRP[05]  */  PACK( 2, 0 ),+    /*  MIRP[06]  */  PACK( 2, 0 ),+    /*  MIRP[07]  */  PACK( 2, 0 ),+    /*  MIRP[08]  */  PACK( 2, 0 ),+    /*  MIRP[09]  */  PACK( 2, 0 ),+    /*  MIRP[10]  */  PACK( 2, 0 ),+    /*  MIRP[11]  */  PACK( 2, 0 ),+    /*  MIRP[12]  */  PACK( 2, 0 ),+    /*  MIRP[13]  */  PACK( 2, 0 ),+    /*  MIRP[14]  */  PACK( 2, 0 ),+    /*  MIRP[15]  */  PACK( 2, 0 ),++    /*  MIRP[16]  */  PACK( 2, 0 ),+    /*  MIRP[17]  */  PACK( 2, 0 ),+    /*  MIRP[18]  */  PACK( 2, 0 ),+    /*  MIRP[19]  */  PACK( 2, 0 ),+    /*  MIRP[20]  */  PACK( 2, 0 ),+    /*  MIRP[21]  */  PACK( 2, 0 ),+    /*  MIRP[22]  */  PACK( 2, 0 ),+    /*  MIRP[23]  */  PACK( 2, 0 ),+    /*  MIRP[24]  */  PACK( 2, 0 ),+    /*  MIRP[25]  */  PACK( 2, 0 ),+    /*  MIRP[26]  */  PACK( 2, 0 ),+    /*  MIRP[27]  */  PACK( 2, 0 ),+    /*  MIRP[28]  */  PACK( 2, 0 ),+    /*  MIRP[29]  */  PACK( 2, 0 ),+    /*  MIRP[30]  */  PACK( 2, 0 ),+    /*  MIRP[31]  */  PACK( 2, 0 )+  };+++#ifdef FT_DEBUG_LEVEL_TRACE++  static+  const char*  const opcode_name[256] =+  {+    "SVTCA y",+    "SVTCA x",+    "SPvTCA y",+    "SPvTCA x",+    "SFvTCA y",+    "SFvTCA x",+    "SPvTL ||",+    "SPvTL +",+    "SFvTL ||",+    "SFvTL +",+    "SPvFS",+    "SFvFS",+    "GPV",+    "GFV",+    "SFvTPv",+    "ISECT",++    "SRP0",+    "SRP1",+    "SRP2",+    "SZP0",+    "SZP1",+    "SZP2",+    "SZPS",+    "SLOOP",+    "RTG",+    "RTHG",+    "SMD",+    "ELSE",+    "JMPR",+    "SCvTCi",+    "SSwCi",+    "SSW",++    "DUP",+    "POP",+    "CLEAR",+    "SWAP",+    "DEPTH",+    "CINDEX",+    "MINDEX",+    "AlignPTS",+    "INS_$28",+    "UTP",+    "LOOPCALL",+    "CALL",+    "FDEF",+    "ENDF",+    "MDAP[0]",+    "MDAP[1]",++    "IUP[0]",+    "IUP[1]",+    "SHP[0]",+    "SHP[1]",+    "SHC[0]",+    "SHC[1]",+    "SHZ[0]",+    "SHZ[1]",+    "SHPIX",+    "IP",+    "MSIRP[0]",+    "MSIRP[1]",+    "AlignRP",+    "RTDG",+    "MIAP[0]",+    "MIAP[1]",++    "NPushB",+    "NPushW",+    "WS",+    "RS",+    "WCvtP",+    "RCvt",+    "GC[0]",+    "GC[1]",+    "SCFS",+    "MD[0]",+    "MD[1]",+    "MPPEM",+    "MPS",+    "FlipON",+    "FlipOFF",+    "DEBUG",++    "LT",+    "LTEQ",+    "GT",+    "GTEQ",+    "EQ",+    "NEQ",+    "ODD",+    "EVEN",+    "IF",+    "EIF",+    "AND",+    "OR",+    "NOT",+    "DeltaP1",+    "SDB",+    "SDS",++    "ADD",+    "SUB",+    "DIV",+    "MUL",+    "ABS",+    "NEG",+    "FLOOR",+    "CEILING",+    "ROUND[0]",+    "ROUND[1]",+    "ROUND[2]",+    "ROUND[3]",+    "NROUND[0]",+    "NROUND[1]",+    "NROUND[2]",+    "NROUND[3]",++    "WCvtF",+    "DeltaP2",+    "DeltaP3",+    "DeltaCn[0]",+    "DeltaCn[1]",+    "DeltaCn[2]",+    "SROUND",+    "S45Round",+    "JROT",+    "JROF",+    "ROFF",+    "INS_$7B",+    "RUTG",+    "RDTG",+    "SANGW",+    "AA",++    "FlipPT",+    "FlipRgON",+    "FlipRgOFF",+    "INS_$83",+    "INS_$84",+    "ScanCTRL",+    "SDVPTL[0]",+    "SDVPTL[1]",+    "GetINFO",+    "IDEF",+    "ROLL",+    "MAX",+    "MIN",+    "ScanTYPE",+    "InstCTRL",+    "INS_$8F",++    "INS_$90",+    "INS_$91",+    "INS_$92",+    "INS_$93",+    "INS_$94",+    "INS_$95",+    "INS_$96",+    "INS_$97",+    "INS_$98",+    "INS_$99",+    "INS_$9A",+    "INS_$9B",+    "INS_$9C",+    "INS_$9D",+    "INS_$9E",+    "INS_$9F",++    "INS_$A0",+    "INS_$A1",+    "INS_$A2",+    "INS_$A3",+    "INS_$A4",+    "INS_$A5",+    "INS_$A6",+    "INS_$A7",+    "INS_$A8",+    "INS_$A9",+    "INS_$AA",+    "INS_$AB",+    "INS_$AC",+    "INS_$AD",+    "INS_$AE",+    "INS_$AF",++    "PushB[0]",+    "PushB[1]",+    "PushB[2]",+    "PushB[3]",+    "PushB[4]",+    "PushB[5]",+    "PushB[6]",+    "PushB[7]",+    "PushW[0]",+    "PushW[1]",+    "PushW[2]",+    "PushW[3]",+    "PushW[4]",+    "PushW[5]",+    "PushW[6]",+    "PushW[7]",++    "MDRP[00]",+    "MDRP[01]",+    "MDRP[02]",+    "MDRP[03]",+    "MDRP[04]",+    "MDRP[05]",+    "MDRP[06]",+    "MDRP[07]",+    "MDRP[08]",+    "MDRP[09]",+    "MDRP[10]",+    "MDRP[11]",+    "MDRP[12]",+    "MDRP[13]",+    "MDRP[14]",+    "MDRP[15]",++    "MDRP[16]",+    "MDRP[17]",+    "MDRP[18]",+    "MDRP[19]",+    "MDRP[20]",+    "MDRP[21]",+    "MDRP[22]",+    "MDRP[23]",+    "MDRP[24]",+    "MDRP[25]",+    "MDRP[26]",+    "MDRP[27]",+    "MDRP[28]",+    "MDRP[29]",+    "MDRP[30]",+    "MDRP[31]",++    "MIRP[00]",+    "MIRP[01]",+    "MIRP[02]",+    "MIRP[03]",+    "MIRP[04]",+    "MIRP[05]",+    "MIRP[06]",+    "MIRP[07]",+    "MIRP[08]",+    "MIRP[09]",+    "MIRP[10]",+    "MIRP[11]",+    "MIRP[12]",+    "MIRP[13]",+    "MIRP[14]",+    "MIRP[15]",++    "MIRP[16]",+    "MIRP[17]",+    "MIRP[18]",+    "MIRP[19]",+    "MIRP[20]",+    "MIRP[21]",+    "MIRP[22]",+    "MIRP[23]",+    "MIRP[24]",+    "MIRP[25]",+    "MIRP[26]",+    "MIRP[27]",+    "MIRP[28]",+    "MIRP[29]",+    "MIRP[30]",+    "MIRP[31]"+  };++#endif /* FT_DEBUG_LEVEL_TRACE */+++  static+  const FT_Char  opcode_length[256] =+  {+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,++   -1,-2, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,++    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,++    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1+  };++#undef PACK++#if 1++  static FT_Int32+  TT_MulFix14( FT_Int32  a,+               FT_Int    b )+  {+    FT_Int32   sign;+    FT_UInt32  ah, al, mid, lo, hi;+++    sign = a ^ b;++    if ( a < 0 )+      a = -a;+    if ( b < 0 )+      b = -b;++    ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );+    al = (FT_UInt32)( a & 0xFFFFU );++    lo    = al * b;+    mid   = ah * b;+    hi    = mid >> 16;+    mid   = ( mid << 16 ) + ( 1 << 13 ); /* rounding */+    lo   += mid;+    if ( lo < mid )+      hi += 1;++    mid = ( lo >> 14 ) | ( hi << 18 );++    return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;+  }++#else++  /* compute (a*b)/2^14 with maximal accuracy and rounding */+  static FT_Int32+  TT_MulFix14( FT_Int32  a,+               FT_Int    b )+  {+    FT_Int32   m, s, hi;+    FT_UInt32  l, lo;+++    /* compute ax*bx as 64-bit value */+    l  = (FT_UInt32)( ( a & 0xFFFFU ) * b );+    m  = ( a >> 16 ) * b;++    lo = l + (FT_UInt32)( m << 16 );+    hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );++    /* divide the result by 2^14 with rounding */+    s   = hi >> 31;+    l   = lo + (FT_UInt32)s;+    hi += s + ( l < lo );+    lo  = l;++    l   = lo + 0x2000U;+    hi += l < lo;++    return ( hi << 18 ) | ( l >> 14 );+  }+#endif+++  /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */+  static FT_Int32+  TT_DotFix14( FT_Int32  ax,+               FT_Int32  ay,+               FT_Int    bx,+               FT_Int    by )+  {+    FT_Int32   m, s, hi1, hi2, hi;+    FT_UInt32  l, lo1, lo2, lo;+++    /* compute ax*bx as 64-bit value */+    l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );+    m = ( ax >> 16 ) * bx;++    lo1 = l + (FT_UInt32)( m << 16 );+    hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );++    /* compute ay*by as 64-bit value */+    l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );+    m = ( ay >> 16 ) * by;++    lo2 = l + (FT_UInt32)( m << 16 );+    hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );++    /* add them */+    lo = lo1 + lo2;+    hi = hi1 + hi2 + ( lo < lo1 );++    /* divide the result by 2^14 with rounding */+    s   = hi >> 31;+    l   = lo + (FT_UInt32)s;+    hi += s + ( l < lo );+    lo  = l;++    l   = lo + 0x2000U;+    hi += ( l < lo );++    return ( hi << 18 ) | ( l >> 14 );+  }+++  /* return length of given vector */++#if 0++  static FT_Int32+  TT_VecLen( FT_Int32  x,+             FT_Int32  y )+  {+    FT_Int32   m, hi1, hi2, hi;+    FT_UInt32  l, lo1, lo2, lo;+++    /* compute x*x as 64-bit value */+    lo = (FT_UInt32)( x & 0xFFFFU );+    hi = x >> 16;++    l  = lo * lo;+    m  = hi * lo;+    hi = hi * hi;++    lo1 = l + (FT_UInt32)( m << 17 );+    hi1 = hi + ( m >> 15 ) + ( lo1 < l );++    /* compute y*y as 64-bit value */+    lo = (FT_UInt32)( y & 0xFFFFU );+    hi = y >> 16;++    l  = lo * lo;+    m  = hi * lo;+    hi = hi * hi;++    lo2 = l + (FT_UInt32)( m << 17 );+    hi2 = hi + ( m >> 15 ) + ( lo2 < l );++    /* add them to get 'x*x+y*y' as 64-bit value */+    lo = lo1 + lo2;+    hi = hi1 + hi2 + ( lo < lo1 );++    /* compute the square root of this value */+    {+      FT_UInt32  root, rem, test_div;+      FT_Int     count;+++      root = 0;++      {+        rem   = 0;+        count = 32;+        do+        {+          rem      = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );+          hi       = (  hi << 2 ) | (            lo >> 30 );+          lo     <<= 2;+          root   <<= 1;+          test_div = ( root << 1 ) + 1;++          if ( rem >= test_div )+          {+            rem  -= test_div;+            root += 1;+          }+        } while ( --count );+      }++      return (FT_Int32)root;+    }+  }++#else++  /* this version uses FT_Vector_Length which computes the same value */+  /* much, much faster..                                              */+  /*                                                                  */+  static FT_F26Dot6+  TT_VecLen( FT_F26Dot6  X,+             FT_F26Dot6  Y )+  {+    FT_Vector  v;+++    v.x = X;+    v.y = Y;++    return FT_Vector_Length( &v );+  }++#endif+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Current_Ratio                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Returns the current aspect ratio scaling factor depending on the   */+  /*    projection vector's state and device resolutions.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */+  /*                                                                       */+  static FT_Long+  Current_Ratio( EXEC_OP )+  {+    if ( !CUR.tt_metrics.ratio )+    {+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+      if ( CUR.face->unpatented_hinting )+      {+        if ( CUR.GS.both_x_axis )+          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;+        else+          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;+      }+      else+#endif+      {+        if ( CUR.GS.projVector.y == 0 )+          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;++        else if ( CUR.GS.projVector.x == 0 )+          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;++        else+        {+          FT_Long  x, y;+++          x = TT_MULDIV( CUR.GS.projVector.x,+                         CUR.tt_metrics.x_ratio, 0x4000 );+          y = TT_MULDIV( CUR.GS.projVector.y,+                         CUR.tt_metrics.y_ratio, 0x4000 );+          CUR.tt_metrics.ratio = TT_VecLen( x, y );+        }+      }+    }+    return CUR.tt_metrics.ratio;+  }+++  static FT_Long+  Current_Ppem( EXEC_OP )+  {+    return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Functions related to the control value table (CVT).                   */+  /*                                                                       */+  /*************************************************************************/+++  FT_CALLBACK_DEF( FT_F26Dot6 )+  Read_CVT( EXEC_OP_ FT_ULong  idx )+  {+    return CUR.cvt[idx];+  }+++  FT_CALLBACK_DEF( FT_F26Dot6 )+  Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )+  {+    return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() );+  }+++  FT_CALLBACK_DEF( void )+  Write_CVT( EXEC_OP_ FT_ULong    idx,+                      FT_F26Dot6  value )+  {+    CUR.cvt[idx] = value;+  }+++  FT_CALLBACK_DEF( void )+  Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,+                                FT_F26Dot6  value )+  {+    CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );+  }+++  FT_CALLBACK_DEF( void )+  Move_CVT( EXEC_OP_ FT_ULong    idx,+                     FT_F26Dot6  value )+  {+    CUR.cvt[idx] += value;+  }+++  FT_CALLBACK_DEF( void )+  Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,+                               FT_F26Dot6  value )+  {+    CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    GetShortIns                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Returns a short integer taken from the instruction stream at       */+  /*    address IP.                                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Short read at code[IP].                                            */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This one could become a macro.                                     */+  /*                                                                       */+  static FT_Short+  GetShortIns( EXEC_OP )+  {+    /* Reading a byte stream so there is no endianess (DaveP) */+    CUR.IP += 2;+    return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) ++                         CUR.code[CUR.IP - 1]      );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Ins_Goto_CodeRange                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Goes to a certain code range in the instruction stream.            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    aRange :: The index of the code range.                             */+  /*                                                                       */+  /*    aIP    :: The new IP address in the code range.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    SUCCESS or FAILURE.                                                */+  /*                                                                       */+  static FT_Bool+  Ins_Goto_CodeRange( EXEC_OP_ FT_Int    aRange,+                               FT_ULong  aIP )+  {+    TT_CodeRange*  range;+++    if ( aRange < 1 || aRange > 3 )+    {+      CUR.error = TT_Err_Bad_Argument;+      return FAILURE;+    }++    range = &CUR.codeRangeTable[aRange - 1];++    if ( range->base == NULL )     /* invalid coderange */+    {+      CUR.error = TT_Err_Invalid_CodeRange;+      return FAILURE;+    }++    /* NOTE: Because the last instruction of a program may be a CALL */+    /*       which will return to the first byte *after* the code    */+    /*       range, we test for AIP <= Size, instead of AIP < Size.  */++    if ( aIP > range->size )+    {+      CUR.error = TT_Err_Code_Overflow;+      return FAILURE;+    }++    CUR.code     = range->base;+    CUR.codeSize = range->size;+    CUR.IP       = aIP;+    CUR.curRange = aRange;++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Direct_Move                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Moves a point by a given distance along the freedom vector.  The   */+  /*    point will be `touched'.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    point    :: The index of the point to move.                        */+  /*                                                                       */+  /*    distance :: The distance to apply.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    zone     :: The affected glyph zone.                               */+  /*                                                                       */+  static void+  Direct_Move( EXEC_OP_ TT_GlyphZone  zone,+                        FT_UShort     point,+                        FT_F26Dot6    distance )+  {+    FT_F26Dot6  v;+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    FT_ASSERT( !CUR.face->unpatented_hinting );+#endif++    v = CUR.GS.freeVector.x;++    if ( v != 0 )+    {+      zone->cur[point].x += TT_MULDIV( distance,+                                       v * 0x10000L,+                                       CUR.F_dot_P );++      zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;+    }++    v = CUR.GS.freeVector.y;++    if ( v != 0 )+    {+      zone->cur[point].y += TT_MULDIV( distance,+                                       v * 0x10000L,+                                       CUR.F_dot_P );++      zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Direct_Move_Orig                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Moves the *original* position of a point by a given distance along */+  /*    the freedom vector.  Obviously, the point will not be `touched'.   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    point    :: The index of the point to move.                        */+  /*                                                                       */+  /*    distance :: The distance to apply.                                 */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    zone     :: The affected glyph zone.                               */+  /*                                                                       */+  static void+  Direct_Move_Orig( EXEC_OP_ TT_GlyphZone  zone,+                             FT_UShort     point,+                             FT_F26Dot6    distance )+  {+    FT_F26Dot6  v;+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    FT_ASSERT( !CUR.face->unpatented_hinting );+#endif++    v = CUR.GS.freeVector.x;++    if ( v != 0 )+      zone->org[point].x += TT_MULDIV( distance,+                                       v * 0x10000L,+                                       CUR.F_dot_P );++    v = CUR.GS.freeVector.y;++    if ( v != 0 )+      zone->org[point].y += TT_MULDIV( distance,+                                       v * 0x10000L,+                                       CUR.F_dot_P );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Special versions of Direct_Move()                                     */+  /*                                                                       */+  /*   The following versions are used whenever both vectors are both      */+  /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */+  /*                                                                       */+  /*************************************************************************/+++  static void+  Direct_Move_X( EXEC_OP_ TT_GlyphZone  zone,+                          FT_UShort     point,+                          FT_F26Dot6    distance )+  {+    FT_UNUSED_EXEC;++    zone->cur[point].x += distance;+    zone->tags[point]  |= FT_CURVE_TAG_TOUCH_X;+  }+++  static void+  Direct_Move_Y( EXEC_OP_ TT_GlyphZone  zone,+                          FT_UShort     point,+                          FT_F26Dot6    distance )+  {+    FT_UNUSED_EXEC;++    zone->cur[point].y += distance;+    zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Special versions of Direct_Move_Orig()                                */+  /*                                                                       */+  /*   The following versions are used whenever both vectors are both      */+  /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */+  /*                                                                       */+  /*************************************************************************/+++  static void+  Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone  zone,+                               FT_UShort     point,+                               FT_F26Dot6    distance )+  {+    FT_UNUSED_EXEC;++    zone->org[point].x += distance;+  }+++  static void+  Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone  zone,+                               FT_UShort     point,+                               FT_F26Dot6    distance )+  {+    FT_UNUSED_EXEC;++    zone->org[point].y += distance;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_None                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Does not round, but adds engine compensation.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance (not) to round.                       */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The compensated distance.                                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The TrueType specification says very few about the relationship    */+  /*    between rounding and engine compensation.  However, it seems from  */+  /*    the description of super round that we should add the compensation */+  /*    before rounding.                                                   */+  /*                                                                       */+  static FT_F26Dot6+  Round_None( EXEC_OP_ FT_F26Dot6  distance,+                       FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = distance + compensation;+      if ( distance && val < 0 )+        val = 0;+    }+    else+    {+      val = distance - compensation;+      if ( val > 0 )+        val = 0;+    }+    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_To_Grid                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Rounds value to grid after adding engine compensation.             */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  static FT_F26Dot6+  Round_To_Grid( EXEC_OP_ FT_F26Dot6  distance,+                          FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = distance + compensation + 32;+      if ( distance && val > 0 )+        val &= ~63;+      else+        val = 0;+    }+    else+    {+      val = -FT_PIX_ROUND( compensation - distance );+      if ( val > 0 )+        val = 0;+    }++    return  val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_To_Half_Grid                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Rounds value to half grid after adding engine compensation.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  static FT_F26Dot6+  Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6  distance,+                               FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = FT_PIX_FLOOR( distance + compensation ) + 32;+      if ( distance && val < 0 )+        val = 0;+    }+    else+    {+      val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );+      if ( val > 0 )+        val = 0;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_Down_To_Grid                                                 */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Rounds value down to grid after adding engine compensation.        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  static FT_F26Dot6+  Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6  distance,+                               FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = distance + compensation;+      if ( distance && val > 0 )+        val &= ~63;+      else+        val = 0;+    }+    else+    {+      val = -( ( compensation - distance ) & -64 );+      if ( val > 0 )+        val = 0;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_Up_To_Grid                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Rounds value up to grid after adding engine compensation.          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  static FT_F26Dot6+  Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6  distance,+                             FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = distance + compensation + 63;+      if ( distance && val > 0 )+        val &= ~63;+      else+        val = 0;+    }+    else+    {+      val = - FT_PIX_CEIL( compensation - distance );+      if ( val > 0 )+        val = 0;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_To_Double_Grid                                               */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Rounds value to double grid after adding engine compensation.      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  static FT_F26Dot6+  Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6  distance,+                                 FT_F26Dot6  compensation )+  {+    FT_F26Dot6 val;++    FT_UNUSED_EXEC;+++    if ( distance >= 0 )+    {+      val = distance + compensation + 16;+      if ( distance && val > 0 )+        val &= ~31;+      else+        val = 0;+    }+    else+    {+      val = -FT_PAD_ROUND( compensation - distance, 32 );+      if ( val > 0 )+        val = 0;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_Super                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Super-rounds value to grid after adding engine compensation.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The TrueType specification says very few about the relationship    */+  /*    between rounding and engine compensation.  However, it seems from  */+  /*    the description of super round that we should add the compensation */+  /*    before rounding.                                                   */+  /*                                                                       */+  static FT_F26Dot6+  Round_Super( EXEC_OP_ FT_F26Dot6  distance,+                        FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;+++    if ( distance >= 0 )+    {+      val = ( distance - CUR.phase + CUR.threshold + compensation ) &+              -CUR.period;+      if ( distance && val < 0 )+        val = 0;+      val += CUR.phase;+    }+    else+    {+      val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &+               -CUR.period );+      if ( val > 0 )+        val = 0;+      val -= CUR.phase;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Round_Super_45                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Super-rounds value to grid after adding engine compensation.       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    distance     :: The distance to round.                             */+  /*                                                                       */+  /*    compensation :: The engine compensation.                           */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Rounded distance.                                                  */+  /*                                                                       */+  /* <Note>                                                                */+  /*    There is a separate function for Round_Super_45() as we may need   */+  /*    greater precision.                                                 */+  /*                                                                       */+  static FT_F26Dot6+  Round_Super_45( EXEC_OP_ FT_F26Dot6  distance,+                           FT_F26Dot6  compensation )+  {+    FT_F26Dot6  val;+++    if ( distance >= 0 )+    {+      val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /+                CUR.period ) * CUR.period;+      if ( distance && val < 0 )+        val = 0;+      val += CUR.phase;+    }+    else+    {+      val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /+                   CUR.period ) * CUR.period );+      if ( val > 0 )+        val = 0;+      val -= CUR.phase;+    }++    return val;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Compute_Round                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Sets the rounding mode.                                            */+  /*                                                                       */+  /* <Input>                                                               */+  /*    round_mode :: The rounding mode to be used.                        */+  /*                                                                       */+  static void+  Compute_Round( EXEC_OP_ FT_Byte  round_mode )+  {+    switch ( round_mode )+    {+    case TT_Round_Off:+      CUR.func_round = (TT_Round_Func)Round_None;+      break;++    case TT_Round_To_Grid:+      CUR.func_round = (TT_Round_Func)Round_To_Grid;+      break;++    case TT_Round_Up_To_Grid:+      CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;+      break;++    case TT_Round_Down_To_Grid:+      CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;+      break;++    case TT_Round_To_Half_Grid:+      CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;+      break;++    case TT_Round_To_Double_Grid:+      CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;+      break;++    case TT_Round_Super:+      CUR.func_round = (TT_Round_Func)Round_Super;+      break;++    case TT_Round_Super_45:+      CUR.func_round = (TT_Round_Func)Round_Super_45;+      break;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    SetSuperRound                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Sets Super Round parameters.                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    GridPeriod :: Grid period                                          */+  /*    selector   :: SROUND opcode                                        */+  /*                                                                       */+  static void+  SetSuperRound( EXEC_OP_ FT_F26Dot6  GridPeriod,+                          FT_Long     selector )+  {+    switch ( (FT_Int)( selector & 0xC0 ) )+    {+      case 0:+        CUR.period = GridPeriod / 2;+        break;++      case 0x40:+        CUR.period = GridPeriod;+        break;++      case 0x80:+        CUR.period = GridPeriod * 2;+        break;++      /* This opcode is reserved, but... */++      case 0xC0:+        CUR.period = GridPeriod;+        break;+    }++    switch ( (FT_Int)( selector & 0x30 ) )+    {+    case 0:+      CUR.phase = 0;+      break;++    case 0x10:+      CUR.phase = CUR.period / 4;+      break;++    case 0x20:+      CUR.phase = CUR.period / 2;+      break;++    case 0x30:+      CUR.phase = CUR.period * 3 / 4;+      break;+    }++    if ( ( selector & 0x0F ) == 0 )+      CUR.threshold = CUR.period - 1;+    else+      CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;++    CUR.period    /= 256;+    CUR.phase     /= 256;+    CUR.threshold /= 256;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Project                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the projection of vector given by (v2-v1) along the       */+  /*    current projection vector.                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    v1 :: First input vector.                                          */+  /*    v2 :: Second input vector.                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The distance in F26dot6 format.                                    */+  /*                                                                       */+  static FT_F26Dot6+  Project( EXEC_OP_ FT_Pos  dx,+                    FT_Pos  dy )+  {+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    FT_ASSERT( !CUR.face->unpatented_hinting );+#endif++    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,+                        CUR.GS.projVector.x,+                        CUR.GS.projVector.y );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Dual_Project                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the projection of the vector given by (v2-v1) along the   */+  /*    current dual vector.                                               */+  /*                                                                       */+  /* <Input>                                                               */+  /*    v1 :: First input vector.                                          */+  /*    v2 :: Second input vector.                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The distance in F26dot6 format.                                    */+  /*                                                                       */+  static FT_F26Dot6+  Dual_Project( EXEC_OP_ FT_Pos  dx,+                         FT_Pos  dy )+  {+    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,+                        CUR.GS.dualVector.x,+                        CUR.GS.dualVector.y );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Project_x                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the projection of the vector given by (v2-v1) along the   */+  /*    horizontal axis.                                                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    v1 :: First input vector.                                          */+  /*    v2 :: Second input vector.                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The distance in F26dot6 format.                                    */+  /*                                                                       */+  static FT_F26Dot6+  Project_x( EXEC_OP_ FT_Pos  dx,+                      FT_Pos  dy )+  {+    FT_UNUSED_EXEC;+    FT_UNUSED( dy );++    return dx;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Project_y                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the projection of the vector given by (v2-v1) along the   */+  /*    vertical axis.                                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    v1 :: First input vector.                                          */+  /*    v2 :: Second input vector.                                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    The distance in F26dot6 format.                                    */+  /*                                                                       */+  static FT_F26Dot6+  Project_y( EXEC_OP_ FT_Pos  dx,+                      FT_Pos  dy )+  {+    FT_UNUSED_EXEC;+    FT_UNUSED( dx );++    return dy;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Compute_Funcs                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Computes the projection and movement function pointers according   */+  /*    to the current graphics state.                                     */+  /*                                                                       */+  static void+  Compute_Funcs( EXEC_OP )+  {+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    if ( CUR.face->unpatented_hinting )+    {+      /* If both vectors point rightwards along the x axis, set             */+      /* `both-x-axis' true, otherwise set it false.  The x values only     */+      /* need be tested because the vector has been normalised to a unit    */+      /* vector of length 0x4000 = unity.                                   */+      CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&+                                      CUR.GS.freeVector.x == 0x4000 );++      /* Throw away projection and freedom vector information */+      /* because the patents don't allow them to be stored.   */+      /* The relevant US Patents are 5155805 and 5325479.     */+      CUR.GS.projVector.x = 0;+      CUR.GS.projVector.y = 0;+      CUR.GS.freeVector.x = 0;+      CUR.GS.freeVector.y = 0;++      if ( CUR.GS.both_x_axis )+      {+        CUR.func_project   = Project_x;+        CUR.func_move      = Direct_Move_X;+        CUR.func_move_orig = Direct_Move_Orig_X;+      }+      else+      {+        CUR.func_project   = Project_y;+        CUR.func_move      = Direct_Move_Y;+        CUR.func_move_orig = Direct_Move_Orig_Y;+      }++      if ( CUR.GS.dualVector.x == 0x4000 )+        CUR.func_dualproj = Project_x;+      else+      {+        if ( CUR.GS.dualVector.y == 0x4000 )+          CUR.func_dualproj = Project_y;+        else+          CUR.func_dualproj = Dual_Project;+      }++      /* Force recalculation of cached aspect ratio */+      CUR.tt_metrics.ratio = 0;++      return;+    }+#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */++    if ( CUR.GS.freeVector.x == 0x4000 )+      CUR.F_dot_P       = CUR.GS.projVector.x * 0x10000L;+    else+    {+      if ( CUR.GS.freeVector.y == 0x4000 )+        CUR.F_dot_P       = CUR.GS.projVector.y * 0x10000L;+      else+        CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 ++                      (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;+    }++    if ( CUR.GS.projVector.x == 0x4000 )+      CUR.func_project = (TT_Project_Func)Project_x;+    else+    {+      if ( CUR.GS.projVector.y == 0x4000 )+        CUR.func_project = (TT_Project_Func)Project_y;+      else+        CUR.func_project = (TT_Project_Func)Project;+    }++    if ( CUR.GS.dualVector.x == 0x4000 )+      CUR.func_dualproj = (TT_Project_Func)Project_x;+    else+    {+      if ( CUR.GS.dualVector.y == 0x4000 )+        CUR.func_dualproj = (TT_Project_Func)Project_y;+      else+        CUR.func_dualproj = (TT_Project_Func)Dual_Project;+    }++    CUR.func_move      = (TT_Move_Func)Direct_Move;+    CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;++    if ( CUR.F_dot_P == 0x40000000L )+    {+      if ( CUR.GS.freeVector.x == 0x4000 )+      {+        CUR.func_move      = (TT_Move_Func)Direct_Move_X;+        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;+      }+      else+      {+        if ( CUR.GS.freeVector.y == 0x4000 )+        {+          CUR.func_move      = (TT_Move_Func)Direct_Move_Y;+          CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;+        }+      }+    }++    /* at small sizes, F_dot_P can become too small, resulting   */+    /* in overflows and `spikes' in a number of glyphs like `w'. */++    if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L )+      CUR.F_dot_P = 0x40000000L;++    /* Disable cached aspect ratio */+    CUR.tt_metrics.ratio = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Normalize                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Norms a vector.                                                    */+  /*                                                                       */+  /* <Input>                                                               */+  /*    Vx :: The horizontal input vector coordinate.                      */+  /*    Vy :: The vertical input vector coordinate.                        */+  /*                                                                       */+  /* <Output>                                                              */+  /*    R  :: The normed unit vector.                                      */+  /*                                                                       */+  /* <Return>                                                              */+  /*    Returns FAILURE if a vector parameter is zero.                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */+  /*    R is undefined.                                                    */+  /*                                                                       */+++  static FT_Bool+  Normalize( EXEC_OP_ FT_F26Dot6      Vx,+                      FT_F26Dot6      Vy,+                      FT_UnitVector*  R )+  {+    FT_F26Dot6  W;+    FT_Bool     S1, S2;++    FT_UNUSED_EXEC;+++    if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L )+    {+      Vx *= 0x100;+      Vy *= 0x100;++      W = TT_VecLen( Vx, Vy );++      if ( W == 0 )+      {+        /* XXX: UNDOCUMENTED! It seems that it is possible to try   */+        /*      to normalize the vector (0,0).  Return immediately. */+        return SUCCESS;+      }++      R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W );+      R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W );++      return SUCCESS;+    }++    W = TT_VecLen( Vx, Vy );++    Vx = FT_MulDiv( Vx, 0x4000L, W );+    Vy = FT_MulDiv( Vy, 0x4000L, W );++    W = Vx * Vx + Vy * Vy;++    /* Now, we want that Sqrt( W ) = 0x4000 */+    /* Or 0x10000000 <= W < 0x10004000        */++    if ( Vx < 0 )+    {+      Vx = -Vx;+      S1 = TRUE;+    }+    else+      S1 = FALSE;++    if ( Vy < 0 )+    {+      Vy = -Vy;+      S2 = TRUE;+    }+    else+      S2 = FALSE;++    while ( W < 0x10000000L )+    {+      /* We need to increase W by a minimal amount */+      if ( Vx < Vy )+        Vx++;+      else+        Vy++;++      W = Vx * Vx + Vy * Vy;+    }++    while ( W >= 0x10004000L )+    {+      /* We need to decrease W by a minimal amount */+      if ( Vx < Vy )+        Vx--;+      else+        Vy--;++      W = Vx * Vx + Vy * Vy;+    }++    /* Note that in various cases, we can only  */+    /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */++    if ( S1 )+      Vx = -Vx;++    if ( S2 )+      Vy = -Vy;++    R->x = (FT_F2Dot14)Vx;   /* Type conversion */+    R->y = (FT_F2Dot14)Vy;   /* Type conversion */++    return SUCCESS;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Here we start with the implementation of the various opcodes.         */+  /*                                                                       */+  /*************************************************************************/+++  static FT_Bool+  Ins_SxVTL( EXEC_OP_ FT_UShort       aIdx1,+                      FT_UShort       aIdx2,+                      FT_Int          aOpc,+                      FT_UnitVector*  Vec )+  {+    FT_Long     A, B, C;+    FT_Vector*  p1;+    FT_Vector*  p2;+++    if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||+         BOUNDS( aIdx2, CUR.zp1.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return FAILURE;+    }++    p1 = CUR.zp1.cur + aIdx2;+    p2 = CUR.zp2.cur + aIdx1;++    A = p1->x - p2->x;+    B = p1->y - p2->y;++    if ( ( aOpc & 1 ) != 0 )+    {+      C =  B;   /* counter clockwise rotation */+      B =  A;+      A = -C;+    }++    NORMalize( A, B, Vec );++    return SUCCESS;+  }+++  /* When not using the big switch statements, the interpreter uses a */+  /* call table defined later below in this source.  Each opcode must */+  /* thus have a corresponding function, even trivial ones.           */+  /*                                                                  */+  /* They are all defined there.                                      */++#define DO_SVTCA                            \+  {                                         \+    FT_Short  A, B;                         \+                                            \+                                            \+    A = (FT_Short)( CUR.opcode & 1 ) << 14; \+    B = A ^ (FT_Short)0x4000;               \+                                            \+    CUR.GS.freeVector.x = A;                \+    CUR.GS.projVector.x = A;                \+    CUR.GS.dualVector.x = A;                \+                                            \+    CUR.GS.freeVector.y = B;                \+    CUR.GS.projVector.y = B;                \+    CUR.GS.dualVector.y = B;                \+                                            \+    COMPUTE_Funcs();                        \+  }+++#define DO_SPVTCA                           \+  {                                         \+    FT_Short  A, B;                         \+                                            \+                                            \+    A = (FT_Short)( CUR.opcode & 1 ) << 14; \+    B = A ^ (FT_Short)0x4000;               \+                                            \+    CUR.GS.projVector.x = A;                \+    CUR.GS.dualVector.x = A;                \+                                            \+    CUR.GS.projVector.y = B;                \+    CUR.GS.dualVector.y = B;                \+                                            \+    GUESS_VECTOR( freeVector );             \+                                            \+    COMPUTE_Funcs();                        \+  }+++#define DO_SFVTCA                           \+  {                                         \+    FT_Short  A, B;                         \+                                            \+                                            \+    A = (FT_Short)( CUR.opcode & 1 ) << 14; \+    B = A ^ (FT_Short)0x4000;               \+                                            \+    CUR.GS.freeVector.x = A;                \+    CUR.GS.freeVector.y = B;                \+                                            \+    GUESS_VECTOR( projVector );             \+                                            \+    COMPUTE_Funcs();                        \+  }+++#define DO_SPVTL                                      \+    if ( INS_SxVTL( (FT_UShort)args[1],               \+                    (FT_UShort)args[0],               \+                    CUR.opcode,                       \+                    &CUR.GS.projVector ) == SUCCESS ) \+    {                                                 \+      CUR.GS.dualVector = CUR.GS.projVector;          \+      GUESS_VECTOR( freeVector );                     \+      COMPUTE_Funcs();                                \+    }+++#define DO_SFVTL                                      \+    if ( INS_SxVTL( (FT_UShort)args[1],               \+                    (FT_UShort)args[0],               \+                    CUR.opcode,                       \+                    &CUR.GS.freeVector ) == SUCCESS ) \+    {                                                 \+      GUESS_VECTOR( projVector );                     \+      COMPUTE_Funcs();                                \+    }+++#define DO_SFVTPV                          \+    GUESS_VECTOR( projVector );            \+    CUR.GS.freeVector = CUR.GS.projVector; \+    COMPUTE_Funcs();+++#define DO_SPVFS                                \+  {                                             \+    FT_Short  S;                                \+    FT_Long   X, Y;                             \+                                                \+                                                \+    /* Only use low 16bits, then sign extend */ \+    S = (FT_Short)args[1];                      \+    Y = (FT_Long)S;                             \+    S = (FT_Short)args[0];                      \+    X = (FT_Long)S;                             \+                                                \+    NORMalize( X, Y, &CUR.GS.projVector );      \+                                                \+    CUR.GS.dualVector = CUR.GS.projVector;      \+    GUESS_VECTOR( freeVector );                 \+    COMPUTE_Funcs();                            \+  }+++#define DO_SFVFS                                \+  {                                             \+    FT_Short  S;                                \+    FT_Long   X, Y;                             \+                                                \+                                                \+    /* Only use low 16bits, then sign extend */ \+    S = (FT_Short)args[1];                      \+    Y = (FT_Long)S;                             \+    S = (FT_Short)args[0];                      \+    X = S;                                      \+                                                \+    NORMalize( X, Y, &CUR.GS.freeVector );      \+    GUESS_VECTOR( projVector );                 \+    COMPUTE_Funcs();                            \+  }+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+#define DO_GPV                                   \+    if ( CUR.face->unpatented_hinting )          \+    {                                            \+      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \+      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \+    }                                            \+    else                                         \+    {                                            \+      args[0] = CUR.GS.projVector.x;             \+      args[1] = CUR.GS.projVector.y;             \+    }+#else+#define DO_GPV                                   \+    args[0] = CUR.GS.projVector.x;               \+    args[1] = CUR.GS.projVector.y;+#endif+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+#define DO_GFV                                   \+    if ( CUR.face->unpatented_hinting )          \+    {                                            \+      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \+      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \+    }                                            \+    else                                         \+    {                                            \+      args[0] = CUR.GS.freeVector.x;             \+      args[1] = CUR.GS.freeVector.y;             \+    }+#else+#define DO_GFV                                   \+    args[0] = CUR.GS.freeVector.x;               \+    args[1] = CUR.GS.freeVector.y;+#endif+++#define DO_SRP0                      \+    CUR.GS.rp0 = (FT_UShort)args[0];+++#define DO_SRP1                      \+    CUR.GS.rp1 = (FT_UShort)args[0];+++#define DO_SRP2                      \+    CUR.GS.rp2 = (FT_UShort)args[0];+++#define DO_RTHG                                         \+    CUR.GS.round_state = TT_Round_To_Half_Grid;         \+    CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;+++#define DO_RTG                                     \+    CUR.GS.round_state = TT_Round_To_Grid;         \+    CUR.func_round = (TT_Round_Func)Round_To_Grid;+++#define DO_RTDG                                           \+    CUR.GS.round_state = TT_Round_To_Double_Grid;         \+    CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;+++#define DO_RUTG                                       \+    CUR.GS.round_state = TT_Round_Up_To_Grid;         \+    CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;+++#define DO_RDTG                                         \+    CUR.GS.round_state = TT_Round_Down_To_Grid;         \+    CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;+++#define DO_ROFF                                 \+    CUR.GS.round_state = TT_Round_Off;          \+    CUR.func_round = (TT_Round_Func)Round_None;+++#define DO_SROUND                                \+    SET_SuperRound( 0x4000, args[0] );           \+    CUR.GS.round_state = TT_Round_Super;         \+    CUR.func_round = (TT_Round_Func)Round_Super;+++#define DO_S45ROUND                                 \+    SET_SuperRound( 0x2D41, args[0] );              \+    CUR.GS.round_state = TT_Round_Super_45;         \+    CUR.func_round = (TT_Round_Func)Round_Super_45;+++#define DO_SLOOP                       \+    if ( args[0] < 0 )                 \+      CUR.error = TT_Err_Bad_Argument; \+    else                               \+      CUR.GS.loop = args[0];+++#define DO_SMD                         \+    CUR.GS.minimum_distance = args[0];+++#define DO_SCVTCI                                     \+    CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];+++#define DO_SSWCI                                     \+    CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];+++    /* XXX: UNDOCUMENTED! or bug in the Windows engine?   */+    /*                                                    */+    /*      It seems that the value that is read here is  */+    /*      expressed in 16.16 format rather than in font */+    /*      units.                                        */+    /*                                                    */+#define DO_SSW                                                 \+    CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 );+++#define DO_FLIPON            \+    CUR.GS.auto_flip = TRUE;+++#define DO_FLIPOFF            \+    CUR.GS.auto_flip = FALSE;+++#define DO_SDB                             \+    CUR.GS.delta_base = (FT_Short)args[0];+++#define DO_SDS                              \+    CUR.GS.delta_shift = (FT_Short)args[0];+++#define DO_MD  /* nothing */+++#define DO_MPPEM              \+    args[0] = CURRENT_Ppem();+++  /* Note: The pointSize should be irrelevant in a given font program; */+  /*       we thus decide to return only the ppem.                     */+#if 0++#define DO_MPS                       \+    args[0] = CUR.metrics.pointSize;++#else++#define DO_MPS                \+    args[0] = CURRENT_Ppem();++#endif /* 0 */+++#define DO_DUP         \+    args[1] = args[0];+++#define DO_CLEAR     \+    CUR.new_top = 0;+++#define DO_SWAP        \+  {                    \+    FT_Long  L;        \+                       \+                       \+    L       = args[0]; \+    args[0] = args[1]; \+    args[1] = L;       \+  }+++#define DO_DEPTH       \+    args[0] = CUR.top;+++#define DO_CINDEX                           \+  {                                         \+    FT_Long  L;                             \+                                            \+                                            \+    L = args[0];                            \+                                            \+    if ( L <= 0 || L > CUR.args )           \+      CUR.error = TT_Err_Invalid_Reference; \+    else                                    \+      args[0] = CUR.stack[CUR.args - L];    \+  }+++#define DO_JROT                          \+    if ( args[1] != 0 )                  \+    {                                    \+      CUR.IP      += args[0];            \+      if ( CUR.IP < 0 )                  \+        CUR.error = TT_Err_Bad_Argument; \+      CUR.step_ins = FALSE;              \+    }+++#define DO_JMPR                        \+    CUR.IP      += args[0];            \+    if ( CUR.IP < 0 )                  \+      CUR.error = TT_Err_Bad_Argument; \+    CUR.step_ins = FALSE;+++#define DO_JROF                          \+    if ( args[1] == 0 )                  \+    {                                    \+      CUR.IP      += args[0];            \+      if ( CUR.IP < 0 )                  \+        CUR.error = TT_Err_Bad_Argument; \+      CUR.step_ins = FALSE;              \+    }+++#define DO_LT                        \+    args[0] = ( args[0] < args[1] );+++#define DO_LTEQ                       \+    args[0] = ( args[0] <= args[1] );+++#define DO_GT                        \+    args[0] = ( args[0] > args[1] );+++#define DO_GTEQ                       \+    args[0] = ( args[0] >= args[1] );+++#define DO_EQ                         \+    args[0] = ( args[0] == args[1] );+++#define DO_NEQ                        \+    args[0] = ( args[0] != args[1] );+++#define DO_ODD                                                  \+    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );+++#define DO_EVEN                                                \+    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );+++#define DO_AND                        \+    args[0] = ( args[0] && args[1] );+++#define DO_OR                         \+    args[0] = ( args[0] || args[1] );+++#define DO_NOT          \+    args[0] = !args[0];+++#define DO_ADD          \+    args[0] += args[1];+++#define DO_SUB          \+    args[0] -= args[1];+++#define DO_DIV                                               \+    if ( args[1] == 0 )                                      \+      CUR.error = TT_Err_Divide_By_Zero;                     \+    else                                                     \+      args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] );+++#define DO_MUL                                    \+    args[0] = TT_MULDIV( args[0], args[1], 64L );+++#define DO_ABS                   \+    args[0] = FT_ABS( args[0] );+++#define DO_NEG          \+    args[0] = -args[0];+++#define DO_FLOOR    \+    args[0] = FT_PIX_FLOOR( args[0] );+++#define DO_CEILING                    \+    args[0] = FT_PIX_CEIL( args[0] );+++#define DO_RS                           \+   {                                    \+     FT_ULong  I = (FT_ULong)args[0];   \+                                        \+                                        \+     if ( BOUNDSL( I, CUR.storeSize ) ) \+     {                                  \+       if ( CUR.pedantic_hinting )      \+       {                                \+         ARRAY_BOUND_ERROR;             \+       }                                \+       else                             \+         args[0] = 0;                   \+     }                                  \+     else                               \+       args[0] = CUR.storage[I];        \+   }+++#define DO_WS                           \+   {                                    \+     FT_ULong  I = (FT_ULong)args[0];   \+                                        \+                                        \+     if ( BOUNDSL( I, CUR.storeSize ) ) \+     {                                  \+       if ( CUR.pedantic_hinting )      \+       {                                \+         ARRAY_BOUND_ERROR;             \+       }                                \+     }                                  \+     else                               \+       CUR.storage[I] = args[1];        \+   }+++#define DO_RCVT                          \+   {                                     \+     FT_ULong  I = (FT_ULong)args[0];    \+                                         \+                                         \+     if ( BOUNDSL( I, CUR.cvtSize ) )    \+     {                                   \+       if ( CUR.pedantic_hinting )       \+       {                                 \+         ARRAY_BOUND_ERROR;              \+       }                                 \+       else                              \+         args[0] = 0;                    \+     }                                   \+     else                                \+       args[0] = CUR_Func_read_cvt( I ); \+   }+++#define DO_WCVTP                         \+   {                                     \+     FT_ULong  I = (FT_ULong)args[0];    \+                                         \+                                         \+     if ( BOUNDSL( I, CUR.cvtSize ) )    \+     {                                   \+       if ( CUR.pedantic_hinting )       \+       {                                 \+         ARRAY_BOUND_ERROR;              \+       }                                 \+     }                                   \+     else                                \+       CUR_Func_write_cvt( I, args[1] ); \+   }+++#define DO_WCVTF                                                \+   {                                                            \+     FT_ULong  I = (FT_ULong)args[0];                           \+                                                                \+                                                                \+     if ( BOUNDSL( I, CUR.cvtSize ) )                           \+     {                                                          \+       if ( CUR.pedantic_hinting )                              \+       {                                                        \+         ARRAY_BOUND_ERROR;                                     \+       }                                                        \+     }                                                          \+     else                                                       \+       CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \+   }+++#define DO_DEBUG                     \+    CUR.error = TT_Err_Debug_OpCode;+++#define DO_ROUND                                                   \+    args[0] = CUR_Func_round(                                      \+                args[0],                                           \+                CUR.tt_metrics.compensations[CUR.opcode - 0x68] );+++#define DO_NROUND                                                            \+    args[0] = ROUND_None( args[0],                                           \+                          CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );+++#define DO_MAX               \+    if ( args[1] > args[0] ) \+      args[0] = args[1];+++#define DO_MIN               \+    if ( args[1] < args[0] ) \+      args[0] = args[1];+++#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH+++#undef  ARRAY_BOUND_ERROR+#define ARRAY_BOUND_ERROR                   \+    {                                       \+      CUR.error = TT_Err_Invalid_Reference; \+      return;                               \+    }+++  /*************************************************************************/+  /*                                                                       */+  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */+  /* Opcode range: 0x00-0x01                                               */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_SVTCA( INS_ARG )+  {+    DO_SVTCA+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SPVTCA[a]:    Set PVector to Coordinate Axis                          */+  /* Opcode range: 0x02-0x03                                               */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_SPVTCA( INS_ARG )+  {+    DO_SPVTCA+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SFVTCA[a]:    Set FVector to Coordinate Axis                          */+  /* Opcode range: 0x04-0x05                                               */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_SFVTCA( INS_ARG )+  {+    DO_SFVTCA+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SPVTL[a]:     Set PVector To Line                                     */+  /* Opcode range: 0x06-0x07                                               */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_SPVTL( INS_ARG )+  {+    DO_SPVTL+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SFVTL[a]:     Set FVector To Line                                     */+  /* Opcode range: 0x08-0x09                                               */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_SFVTL( INS_ARG )+  {+    DO_SFVTL+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SFVTPV[]:     Set FVector To PVector                                  */+  /* Opcode range: 0x0E                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_SFVTPV( INS_ARG )+  {+    DO_SFVTPV+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SPVFS[]:      Set PVector From Stack                                  */+  /* Opcode range: 0x0A                                                    */+  /* Stack:        f2.14 f2.14 -->                                         */+  /*                                                                       */+  static void+  Ins_SPVFS( INS_ARG )+  {+    DO_SPVFS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SFVFS[]:      Set FVector From Stack                                  */+  /* Opcode range: 0x0B                                                    */+  /* Stack:        f2.14 f2.14 -->                                         */+  /*                                                                       */+  static void+  Ins_SFVFS( INS_ARG )+  {+    DO_SFVFS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* GPV[]:        Get Projection Vector                                   */+  /* Opcode range: 0x0C                                                    */+  /* Stack:        ef2.14 --> ef2.14                                       */+  /*                                                                       */+  static void+  Ins_GPV( INS_ARG )+  {+    DO_GPV+  }+++  /*************************************************************************/+  /* GFV[]:        Get Freedom Vector                                      */+  /* Opcode range: 0x0D                                                    */+  /* Stack:        ef2.14 --> ef2.14                                       */+  /*                                                                       */+  static void+  Ins_GFV( INS_ARG )+  {+    DO_GFV+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SRP0[]:       Set Reference Point 0                                   */+  /* Opcode range: 0x10                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SRP0( INS_ARG )+  {+    DO_SRP0+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SRP1[]:       Set Reference Point 1                                   */+  /* Opcode range: 0x11                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SRP1( INS_ARG )+  {+    DO_SRP1+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SRP2[]:       Set Reference Point 2                                   */+  /* Opcode range: 0x12                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SRP2( INS_ARG )+  {+    DO_SRP2+  }+++  /*************************************************************************/+  /*                                                                       */+  /* RTHG[]:       Round To Half Grid                                      */+  /* Opcode range: 0x19                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_RTHG( INS_ARG )+  {+    DO_RTHG+  }+++  /*************************************************************************/+  /*                                                                       */+  /* RTG[]:        Round To Grid                                           */+  /* Opcode range: 0x18                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_RTG( INS_ARG )+  {+    DO_RTG+  }+++  /*************************************************************************/+  /* RTDG[]:       Round To Double Grid                                    */+  /* Opcode range: 0x3D                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_RTDG( INS_ARG )+  {+    DO_RTDG+  }+++  /*************************************************************************/+  /* RUTG[]:       Round Up To Grid                                        */+  /* Opcode range: 0x7C                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_RUTG( INS_ARG )+  {+    DO_RUTG+  }+++  /*************************************************************************/+  /*                                                                       */+  /* RDTG[]:       Round Down To Grid                                      */+  /* Opcode range: 0x7D                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_RDTG( INS_ARG )+  {+    DO_RDTG+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ROFF[]:       Round OFF                                               */+  /* Opcode range: 0x7A                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_ROFF( INS_ARG )+  {+    DO_ROFF+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SROUND[]:     Super ROUND                                             */+  /* Opcode range: 0x76                                                    */+  /* Stack:        Eint8 -->                                               */+  /*                                                                       */+  static void+  Ins_SROUND( INS_ARG )+  {+    DO_SROUND+  }+++  /*************************************************************************/+  /*                                                                       */+  /* S45ROUND[]:   Super ROUND 45 degrees                                  */+  /* Opcode range: 0x77                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_S45ROUND( INS_ARG )+  {+    DO_S45ROUND+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SLOOP[]:      Set LOOP variable                                       */+  /* Opcode range: 0x17                                                    */+  /* Stack:        int32? -->                                              */+  /*                                                                       */+  static void+  Ins_SLOOP( INS_ARG )+  {+    DO_SLOOP+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SMD[]:        Set Minimum Distance                                    */+  /* Opcode range: 0x1A                                                    */+  /* Stack:        f26.6 -->                                               */+  /*                                                                       */+  static void+  Ins_SMD( INS_ARG )+  {+    DO_SMD+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SCVTCI[]:     Set Control Value Table Cut In                          */+  /* Opcode range: 0x1D                                                    */+  /* Stack:        f26.6 -->                                               */+  /*                                                                       */+  static void+  Ins_SCVTCI( INS_ARG )+  {+    DO_SCVTCI+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SSWCI[]:      Set Single Width Cut In                                 */+  /* Opcode range: 0x1E                                                    */+  /* Stack:        f26.6 -->                                               */+  /*                                                                       */+  static void+  Ins_SSWCI( INS_ARG )+  {+    DO_SSWCI+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SSW[]:        Set Single Width                                        */+  /* Opcode range: 0x1F                                                    */+  /* Stack:        int32? -->                                              */+  /*                                                                       */+  static void+  Ins_SSW( INS_ARG )+  {+    DO_SSW+  }+++  /*************************************************************************/+  /*                                                                       */+  /* FLIPON[]:     Set auto-FLIP to ON                                     */+  /* Opcode range: 0x4D                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_FLIPON( INS_ARG )+  {+    DO_FLIPON+  }+++  /*************************************************************************/+  /*                                                                       */+  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */+  /* Opcode range: 0x4E                                                    */+  /* Stack: -->                                                            */+  /*                                                                       */+  static void+  Ins_FLIPOFF( INS_ARG )+  {+    DO_FLIPOFF+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SANGW[]:      Set ANGle Weight                                        */+  /* Opcode range: 0x7E                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SANGW( INS_ARG )+  {+    /* instruction not supported anymore */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SDB[]:        Set Delta Base                                          */+  /* Opcode range: 0x5E                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SDB( INS_ARG )+  {+    DO_SDB+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SDS[]:        Set Delta Shift                                         */+  /* Opcode range: 0x5F                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SDS( INS_ARG )+  {+    DO_SDS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MPPEM[]:      Measure Pixel Per EM                                    */+  /* Opcode range: 0x4B                                                    */+  /* Stack:        --> Euint16                                             */+  /*                                                                       */+  static void+  Ins_MPPEM( INS_ARG )+  {+    DO_MPPEM+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MPS[]:        Measure Point Size                                      */+  /* Opcode range: 0x4C                                                    */+  /* Stack:        --> Euint16                                             */+  /*                                                                       */+  static void+  Ins_MPS( INS_ARG )+  {+    DO_MPS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DUP[]:        DUPlicate the top stack's element                       */+  /* Opcode range: 0x20                                                    */+  /* Stack:        StkElt --> StkElt StkElt                                */+  /*                                                                       */+  static void+  Ins_DUP( INS_ARG )+  {+    DO_DUP+  }+++  /*************************************************************************/+  /*                                                                       */+  /* POP[]:        POP the stack's top element                             */+  /* Opcode range: 0x21                                                    */+  /* Stack:        StkElt -->                                              */+  /*                                                                       */+  static void+  Ins_POP( INS_ARG )+  {+    /* nothing to do */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* CLEAR[]:      CLEAR the entire stack                                  */+  /* Opcode range: 0x22                                                    */+  /* Stack:        StkElt... -->                                           */+  /*                                                                       */+  static void+  Ins_CLEAR( INS_ARG )+  {+    DO_CLEAR+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SWAP[]:       SWAP the stack's top two elements                       */+  /* Opcode range: 0x23                                                    */+  /* Stack:        2 * StkElt --> 2 * StkElt                               */+  /*                                                                       */+  static void+  Ins_SWAP( INS_ARG )+  {+    DO_SWAP+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DEPTH[]:      return the stack DEPTH                                  */+  /* Opcode range: 0x24                                                    */+  /* Stack:        --> uint32                                              */+  /*                                                                       */+  static void+  Ins_DEPTH( INS_ARG )+  {+    DO_DEPTH+  }+++  /*************************************************************************/+  /*                                                                       */+  /* CINDEX[]:     Copy INDEXed element                                    */+  /* Opcode range: 0x25                                                    */+  /* Stack:        int32 --> StkElt                                        */+  /*                                                                       */+  static void+  Ins_CINDEX( INS_ARG )+  {+    DO_CINDEX+  }+++  /*************************************************************************/+  /*                                                                       */+  /* EIF[]:        End IF                                                  */+  /* Opcode range: 0x59                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_EIF( INS_ARG )+  {+    /* nothing to do */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* JROT[]:       Jump Relative On True                                   */+  /* Opcode range: 0x78                                                    */+  /* Stack:        StkElt int32 -->                                        */+  /*                                                                       */+  static void+  Ins_JROT( INS_ARG )+  {+    DO_JROT+  }+++  /*************************************************************************/+  /*                                                                       */+  /* JMPR[]:       JuMP Relative                                           */+  /* Opcode range: 0x1C                                                    */+  /* Stack:        int32 -->                                               */+  /*                                                                       */+  static void+  Ins_JMPR( INS_ARG )+  {+    DO_JMPR+  }+++  /*************************************************************************/+  /*                                                                       */+  /* JROF[]:       Jump Relative On False                                  */+  /* Opcode range: 0x79                                                    */+  /* Stack:        StkElt int32 -->                                        */+  /*                                                                       */+  static void+  Ins_JROF( INS_ARG )+  {+    DO_JROF+  }+++  /*************************************************************************/+  /*                                                                       */+  /* LT[]:         Less Than                                               */+  /* Opcode range: 0x50                                                    */+  /* Stack:        int32? int32? --> bool                                  */+  /*                                                                       */+  static void+  Ins_LT( INS_ARG )+  {+    DO_LT+  }+++  /*************************************************************************/+  /*                                                                       */+  /* LTEQ[]:       Less Than or EQual                                      */+  /* Opcode range: 0x51                                                    */+  /* Stack:        int32? int32? --> bool                                  */+  /*                                                                       */+  static void+  Ins_LTEQ( INS_ARG )+  {+    DO_LTEQ+  }+++  /*************************************************************************/+  /*                                                                       */+  /* GT[]:         Greater Than                                            */+  /* Opcode range: 0x52                                                    */+  /* Stack:        int32? int32? --> bool                                  */+  /*                                                                       */+  static void+  Ins_GT( INS_ARG )+  {+    DO_GT+  }+++  /*************************************************************************/+  /*                                                                       */+  /* GTEQ[]:       Greater Than or EQual                                   */+  /* Opcode range: 0x53                                                    */+  /* Stack:        int32? int32? --> bool                                  */+  /*                                                                       */+  static void+  Ins_GTEQ( INS_ARG )+  {+    DO_GTEQ+  }+++  /*************************************************************************/+  /*                                                                       */+  /* EQ[]:         EQual                                                   */+  /* Opcode range: 0x54                                                    */+  /* Stack:        StkElt StkElt --> bool                                  */+  /*                                                                       */+  static void+  Ins_EQ( INS_ARG )+  {+    DO_EQ+  }+++  /*************************************************************************/+  /*                                                                       */+  /* NEQ[]:        Not EQual                                               */+  /* Opcode range: 0x55                                                    */+  /* Stack:        StkElt StkElt --> bool                                  */+  /*                                                                       */+  static void+  Ins_NEQ( INS_ARG )+  {+    DO_NEQ+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ODD[]:        Is ODD                                                  */+  /* Opcode range: 0x56                                                    */+  /* Stack:        f26.6 --> bool                                          */+  /*                                                                       */+  static void+  Ins_ODD( INS_ARG )+  {+    DO_ODD+  }+++  /*************************************************************************/+  /*                                                                       */+  /* EVEN[]:       Is EVEN                                                 */+  /* Opcode range: 0x57                                                    */+  /* Stack:        f26.6 --> bool                                          */+  /*                                                                       */+  static void+  Ins_EVEN( INS_ARG )+  {+    DO_EVEN+  }+++  /*************************************************************************/+  /*                                                                       */+  /* AND[]:        logical AND                                             */+  /* Opcode range: 0x5A                                                    */+  /* Stack:        uint32 uint32 --> uint32                                */+  /*                                                                       */+  static void+  Ins_AND( INS_ARG )+  {+    DO_AND+  }+++  /*************************************************************************/+  /*                                                                       */+  /* OR[]:         logical OR                                              */+  /* Opcode range: 0x5B                                                    */+  /* Stack:        uint32 uint32 --> uint32                                */+  /*                                                                       */+  static void+  Ins_OR( INS_ARG )+  {+    DO_OR+  }+++  /*************************************************************************/+  /*                                                                       */+  /* NOT[]:        logical NOT                                             */+  /* Opcode range: 0x5C                                                    */+  /* Stack:        StkElt --> uint32                                       */+  /*                                                                       */+  static void+  Ins_NOT( INS_ARG )+  {+    DO_NOT+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ADD[]:        ADD                                                     */+  /* Opcode range: 0x60                                                    */+  /* Stack:        f26.6 f26.6 --> f26.6                                   */+  /*                                                                       */+  static void+  Ins_ADD( INS_ARG )+  {+    DO_ADD+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SUB[]:        SUBtract                                                */+  /* Opcode range: 0x61                                                    */+  /* Stack:        f26.6 f26.6 --> f26.6                                   */+  /*                                                                       */+  static void+  Ins_SUB( INS_ARG )+  {+    DO_SUB+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DIV[]:        DIVide                                                  */+  /* Opcode range: 0x62                                                    */+  /* Stack:        f26.6 f26.6 --> f26.6                                   */+  /*                                                                       */+  static void+  Ins_DIV( INS_ARG )+  {+    DO_DIV+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MUL[]:        MULtiply                                                */+  /* Opcode range: 0x63                                                    */+  /* Stack:        f26.6 f26.6 --> f26.6                                   */+  /*                                                                       */+  static void+  Ins_MUL( INS_ARG )+  {+    DO_MUL+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ABS[]:        ABSolute value                                          */+  /* Opcode range: 0x64                                                    */+  /* Stack:        f26.6 --> f26.6                                         */+  /*                                                                       */+  static void+  Ins_ABS( INS_ARG )+  {+    DO_ABS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* NEG[]:        NEGate                                                  */+  /* Opcode range: 0x65                                                    */+  /* Stack: f26.6 --> f26.6                                                */+  /*                                                                       */+  static void+  Ins_NEG( INS_ARG )+  {+    DO_NEG+  }+++  /*************************************************************************/+  /*                                                                       */+  /* FLOOR[]:      FLOOR                                                   */+  /* Opcode range: 0x66                                                    */+  /* Stack:        f26.6 --> f26.6                                         */+  /*                                                                       */+  static void+  Ins_FLOOR( INS_ARG )+  {+    DO_FLOOR+  }+++  /*************************************************************************/+  /*                                                                       */+  /* CEILING[]:    CEILING                                                 */+  /* Opcode range: 0x67                                                    */+  /* Stack:        f26.6 --> f26.6                                         */+  /*                                                                       */+  static void+  Ins_CEILING( INS_ARG )+  {+    DO_CEILING+  }+++  /*************************************************************************/+  /*                                                                       */+  /* RS[]:         Read Store                                              */+  /* Opcode range: 0x43                                                    */+  /* Stack:        uint32 --> uint32                                       */+  /*                                                                       */+  static void+  Ins_RS( INS_ARG )+  {+    DO_RS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* WS[]:         Write Store                                             */+  /* Opcode range: 0x42                                                    */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_WS( INS_ARG )+  {+    DO_WS+  }+++  /*************************************************************************/+  /*                                                                       */+  /* WCVTP[]:      Write CVT in Pixel units                                */+  /* Opcode range: 0x44                                                    */+  /* Stack:        f26.6 uint32 -->                                        */+  /*                                                                       */+  static void+  Ins_WCVTP( INS_ARG )+  {+    DO_WCVTP+  }+++  /*************************************************************************/+  /*                                                                       */+  /* WCVTF[]:      Write CVT in Funits                                     */+  /* Opcode range: 0x70                                                    */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_WCVTF( INS_ARG )+  {+    DO_WCVTF+  }+++  /*************************************************************************/+  /*                                                                       */+  /* RCVT[]:       Read CVT                                                */+  /* Opcode range: 0x45                                                    */+  /* Stack:        uint32 --> f26.6                                        */+  /*                                                                       */+  static void+  Ins_RCVT( INS_ARG )+  {+    DO_RCVT+  }+++  /*************************************************************************/+  /*                                                                       */+  /* AA[]:         Adjust Angle                                            */+  /* Opcode range: 0x7F                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_AA( INS_ARG )+  {+    /* intentionally no longer supported */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DEBUG[]:      DEBUG.  Unsupported.                                    */+  /* Opcode range: 0x4F                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  /* Note: The original instruction pops a value from the stack.           */+  /*                                                                       */+  static void+  Ins_DEBUG( INS_ARG )+  {+    DO_DEBUG+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ROUND[ab]:    ROUND value                                             */+  /* Opcode range: 0x68-0x6B                                               */+  /* Stack:        f26.6 --> f26.6                                         */+  /*                                                                       */+  static void+  Ins_ROUND( INS_ARG )+  {+    DO_ROUND+  }+++  /*************************************************************************/+  /*                                                                       */+  /* NROUND[ab]:   No ROUNDing of value                                    */+  /* Opcode range: 0x6C-0x6F                                               */+  /* Stack:        f26.6 --> f26.6                                         */+  /*                                                                       */+  static void+  Ins_NROUND( INS_ARG )+  {+    DO_NROUND+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MAX[]:        MAXimum                                                 */+  /* Opcode range: 0x68                                                    */+  /* Stack:        int32? int32? --> int32                                 */+  /*                                                                       */+  static void+  Ins_MAX( INS_ARG )+  {+    DO_MAX+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MIN[]:        MINimum                                                 */+  /* Opcode range: 0x69                                                    */+  /* Stack:        int32? int32? --> int32                                 */+  /*                                                                       */+  static void+  Ins_MIN( INS_ARG )+  {+    DO_MIN+  }+++#endif  /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */+++  /*************************************************************************/+  /*                                                                       */+  /* The following functions are called as is within the switch statement. */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* MINDEX[]:     Move INDEXed element                                    */+  /* Opcode range: 0x26                                                    */+  /* Stack:        int32? --> StkElt                                       */+  /*                                                                       */+  static void+  Ins_MINDEX( INS_ARG )+  {+    FT_Long  L, K;+++    L = args[0];++    if ( L <= 0 || L > CUR.args )+    {+      CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    K = CUR.stack[CUR.args - L];++    FT_ARRAY_MOVE( &CUR.stack[CUR.args - L    ],+                   &CUR.stack[CUR.args - L + 1],+                   ( L - 1 ) );++    CUR.stack[CUR.args - 1] = K;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ROLL[]:       ROLL top three elements                                 */+  /* Opcode range: 0x8A                                                    */+  /* Stack:        3 * StkElt --> 3 * StkElt                               */+  /*                                                                       */+  static void+  Ins_ROLL( INS_ARG )+  {+    FT_Long  A, B, C;++    FT_UNUSED_EXEC;+++    A = args[2];+    B = args[1];+    C = args[0];++    args[2] = C;+    args[1] = A;+    args[0] = B;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MANAGING THE FLOW OF CONTROL                                          */+  /*                                                                       */+  /*   Instructions appear in the specification's order.                   */+  /*                                                                       */+  /*************************************************************************/+++  static FT_Bool+  SkipCode( EXEC_OP )+  {+    CUR.IP += CUR.length;++    if ( CUR.IP < CUR.codeSize )+    {+      CUR.opcode = CUR.code[CUR.IP];++      CUR.length = opcode_length[CUR.opcode];+      if ( CUR.length < 0 )+      {+        if ( CUR.IP + 1 > CUR.codeSize )+          goto Fail_Overflow;+        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];+      }++      if ( CUR.IP + CUR.length <= CUR.codeSize )+        return SUCCESS;+    }++  Fail_Overflow:+    CUR.error = TT_Err_Code_Overflow;+    return FAILURE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* IF[]:         IF test                                                 */+  /* Opcode range: 0x58                                                    */+  /* Stack:        StkElt -->                                              */+  /*                                                                       */+  static void+  Ins_IF( INS_ARG )+  {+    FT_Int   nIfs;+    FT_Bool  Out;+++    if ( args[0] != 0 )+      return;++    nIfs = 1;+    Out = 0;++    do+    {+      if ( SKIP_Code() == FAILURE )+        return;++      switch ( CUR.opcode )+      {+      case 0x58:      /* IF */+        nIfs++;+        break;++      case 0x1B:      /* ELSE */+        Out = FT_BOOL( nIfs == 1 );+        break;++      case 0x59:      /* EIF */+        nIfs--;+        Out = FT_BOOL( nIfs == 0 );+        break;+      }+    } while ( Out == 0 );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ELSE[]:       ELSE                                                    */+  /* Opcode range: 0x1B                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_ELSE( INS_ARG )+  {+    FT_Int  nIfs;++    FT_UNUSED_ARG;+++    nIfs = 1;++    do+    {+      if ( SKIP_Code() == FAILURE )+        return;++      switch ( CUR.opcode )+      {+      case 0x58:    /* IF */+        nIfs++;+        break;++      case 0x59:    /* EIF */+        nIfs--;+        break;+      }+    } while ( nIfs != 0 );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */+  /*                                                                       */+  /*   Instructions appear in the specification's order.                   */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* FDEF[]:       Function DEFinition                                     */+  /* Opcode range: 0x2C                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_FDEF( INS_ARG )+  {+    FT_ULong       n;+    TT_DefRecord*  rec;+    TT_DefRecord*  limit;+++    /* some font programs are broken enough to redefine functions! */+    /* We will then parse the current table.                       */++    rec   = CUR.FDefs;+    limit = rec + CUR.numFDefs;+    n     = args[0];++    for ( ; rec < limit; rec++ )+    {+      if ( rec->opc == n )+        break;+    }++    if ( rec == limit )+    {+      /* check that there is enough room for new functions */+      if ( CUR.numFDefs >= CUR.maxFDefs )+      {+        CUR.error = TT_Err_Too_Many_Function_Defs;+        return;+      }+      CUR.numFDefs++;+    }++    /* Although FDEF takes unsigned 32-bit integer,  */+    /* func # must be within unsigned 16-bit integer */+    if ( n > 0xFFFFU )+    {+      CUR.error = TT_Err_Too_Many_Function_Defs;+      return;+    }++    rec->range  = CUR.curRange;+    rec->opc    = (FT_UInt16)n;+    rec->start  = CUR.IP + 1;+    rec->active = TRUE;++    if ( n > CUR.maxFunc )+      CUR.maxFunc = (FT_UInt16)n;++    /* Now skip the whole function definition. */+    /* We don't allow nested IDEFS & FDEFs.    */++    while ( SKIP_Code() == SUCCESS )+    {+      switch ( CUR.opcode )+      {+      case 0x89:    /* IDEF */+      case 0x2C:    /* FDEF */+        CUR.error = TT_Err_Nested_DEFS;+        return;++      case 0x2D:   /* ENDF */+        return;+      }+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ENDF[]:       END Function definition                                 */+  /* Opcode range: 0x2D                                                    */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_ENDF( INS_ARG )+  {+    TT_CallRec*  pRec;++    FT_UNUSED_ARG;+++    if ( CUR.callTop <= 0 )     /* We encountered an ENDF without a call */+    {+      CUR.error = TT_Err_ENDF_In_Exec_Stream;+      return;+    }++    CUR.callTop--;++    pRec = &CUR.callStack[CUR.callTop];++    pRec->Cur_Count--;++    CUR.step_ins = FALSE;++    if ( pRec->Cur_Count > 0 )+    {+      CUR.callTop++;+      CUR.IP = pRec->Cur_Restart;+    }+    else+      /* Loop through the current function */+      INS_Goto_CodeRange( pRec->Caller_Range,+                          pRec->Caller_IP );++    /* Exit the current call frame.                      */++    /* NOTE: If the last instruction of a program is a   */+    /*       CALL or LOOPCALL, the return address is     */+    /*       always out of the code range.  This is a    */+    /*       valid address, and it is why we do not test */+    /*       the result of Ins_Goto_CodeRange() here!    */+  }+++  /*************************************************************************/+  /*                                                                       */+  /* CALL[]:       CALL function                                           */+  /* Opcode range: 0x2B                                                    */+  /* Stack:        uint32? -->                                             */+  /*                                                                       */+  static void+  Ins_CALL( INS_ARG )+  {+    FT_ULong       F;+    TT_CallRec*    pCrec;+    TT_DefRecord*  def;+++    /* first of all, check the index */++    F = args[0];+    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )+      goto Fail;++    /* Except for some old Apple fonts, all functions in a TrueType */+    /* font are defined in increasing order, starting from 0.  This */+    /* means that we normally have                                  */+    /*                                                              */+    /*    CUR.maxFunc+1 == CUR.numFDefs                             */+    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */+    /*                                                              */+    /* If this isn't true, we need to look up the function table.   */++    def = CUR.FDefs + F;+    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )+    {+      /* look up the FDefs table */+      TT_DefRecord*  limit;+++      def   = CUR.FDefs;+      limit = def + CUR.numFDefs;++      while ( def < limit && def->opc != F )+        def++;++      if ( def == limit )+        goto Fail;+    }++    /* check that the function is active */+    if ( !def->active )+      goto Fail;++    /* check the call stack */+    if ( CUR.callTop >= CUR.callSize )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    pCrec = CUR.callStack + CUR.callTop;++    pCrec->Caller_Range = CUR.curRange;+    pCrec->Caller_IP    = CUR.IP + 1;+    pCrec->Cur_Count    = 1;+    pCrec->Cur_Restart  = def->start;++    CUR.callTop++;++    INS_Goto_CodeRange( def->range,+                        def->start );++    CUR.step_ins = FALSE;+    return;++  Fail:+    CUR.error = TT_Err_Invalid_Reference;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* LOOPCALL[]:   LOOP and CALL function                                  */+  /* Opcode range: 0x2A                                                    */+  /* Stack:        uint32? Eint16? -->                                     */+  /*                                                                       */+  static void+  Ins_LOOPCALL( INS_ARG )+  {+    FT_ULong       F;+    TT_CallRec*    pCrec;+    TT_DefRecord*  def;+++    /* first of all, check the index */+    F = args[1];+    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )+      goto Fail;++    /* Except for some old Apple fonts, all functions in a TrueType */+    /* font are defined in increasing order, starting from 0.  This */+    /* means that we normally have                                  */+    /*                                                              */+    /*    CUR.maxFunc+1 == CUR.numFDefs                             */+    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */+    /*                                                              */+    /* If this isn't true, we need to look up the function table.   */++    def = CUR.FDefs + F;+    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )+    {+      /* look up the FDefs table */+      TT_DefRecord*  limit;+++      def   = CUR.FDefs;+      limit = def + CUR.numFDefs;++      while ( def < limit && def->opc != F )+        def++;++      if ( def == limit )+        goto Fail;+    }++    /* check that the function is active */+    if ( !def->active )+      goto Fail;++    /* check stack */+    if ( CUR.callTop >= CUR.callSize )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    if ( args[0] > 0 )+    {+      pCrec = CUR.callStack + CUR.callTop;++      pCrec->Caller_Range = CUR.curRange;+      pCrec->Caller_IP    = CUR.IP + 1;+      pCrec->Cur_Count    = (FT_Int)args[0];+      pCrec->Cur_Restart  = def->start;++      CUR.callTop++;++      INS_Goto_CodeRange( def->range, def->start );++      CUR.step_ins = FALSE;+    }+    return;++  Fail:+    CUR.error = TT_Err_Invalid_Reference;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* IDEF[]:       Instruction DEFinition                                  */+  /* Opcode range: 0x89                                                    */+  /* Stack:        Eint8 -->                                               */+  /*                                                                       */+  static void+  Ins_IDEF( INS_ARG )+  {+    TT_DefRecord*  def;+    TT_DefRecord*  limit;+++    /*  First of all, look for the same function in our table */++    def   = CUR.IDefs;+    limit = def + CUR.numIDefs;++    for ( ; def < limit; def++ )+      if ( def->opc == (FT_ULong)args[0] )+        break;++    if ( def == limit )+    {+      /* check that there is enough room for a new instruction */+      if ( CUR.numIDefs >= CUR.maxIDefs )+      {+        CUR.error = TT_Err_Too_Many_Instruction_Defs;+        return;+      }+      CUR.numIDefs++;+    }++    /* opcode must be unsigned 8-bit integer */+    if ( 0 > args[0] || args[0] > 0x00FF )+    {+      CUR.error = TT_Err_Too_Many_Instruction_Defs;+      return;+    }++    def->opc    = (FT_Byte)args[0];+    def->start  = CUR.IP + 1;+    def->range  = CUR.curRange;+    def->active = TRUE;++    if ( (FT_ULong)args[0] > CUR.maxIns )+      CUR.maxIns = (FT_Byte)args[0];++    /* Now skip the whole function definition. */+    /* We don't allow nested IDEFs & FDEFs.    */++    while ( SKIP_Code() == SUCCESS )+    {+      switch ( CUR.opcode )+      {+      case 0x89:   /* IDEF */+      case 0x2C:   /* FDEF */+        CUR.error = TT_Err_Nested_DEFS;+        return;+      case 0x2D:   /* ENDF */+        return;+      }+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* PUSHING DATA ONTO THE INTERPRETER STACK                               */+  /*                                                                       */+  /*   Instructions appear in the specification's order.                   */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* NPUSHB[]:     PUSH N Bytes                                            */+  /* Opcode range: 0x40                                                    */+  /* Stack:        --> uint32...                                           */+  /*                                                                       */+  static void+  Ins_NPUSHB( INS_ARG )+  {+    FT_UShort  L, K;+++    L = (FT_UShort)CUR.code[CUR.IP + 1];++    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    for ( K = 1; K <= L; K++ )+      args[K - 1] = CUR.code[CUR.IP + K + 1];++    CUR.new_top += L;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* NPUSHW[]:     PUSH N Words                                            */+  /* Opcode range: 0x41                                                    */+  /* Stack:        --> int32...                                            */+  /*                                                                       */+  static void+  Ins_NPUSHW( INS_ARG )+  {+    FT_UShort  L, K;+++    L = (FT_UShort)CUR.code[CUR.IP + 1];++    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    CUR.IP += 2;++    for ( K = 0; K < L; K++ )+      args[K] = GET_ShortIns();++    CUR.step_ins = FALSE;+    CUR.new_top += L;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* PUSHB[abc]:   PUSH Bytes                                              */+  /* Opcode range: 0xB0-0xB7                                               */+  /* Stack:        --> uint32...                                           */+  /*                                                                       */+  static void+  Ins_PUSHB( INS_ARG )+  {+    FT_UShort  L, K;+++    L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );++    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    for ( K = 1; K <= L; K++ )+      args[K - 1] = CUR.code[CUR.IP + K];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* PUSHW[abc]:   PUSH Words                                              */+  /* Opcode range: 0xB8-0xBF                                               */+  /* Stack:        --> int32...                                            */+  /*                                                                       */+  static void+  Ins_PUSHW( INS_ARG )+  {+    FT_UShort  L, K;+++    L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );++    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )+    {+      CUR.error = TT_Err_Stack_Overflow;+      return;+    }++    CUR.IP++;++    for ( K = 0; K < L; K++ )+      args[K] = GET_ShortIns();++    CUR.step_ins = FALSE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MANAGING THE GRAPHICS STATE                                           */+  /*                                                                       */+  /*  Instructions appear in the specs' order.                             */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* GC[a]:        Get Coordinate projected onto                           */+  /* Opcode range: 0x46-0x47                                               */+  /* Stack:        uint32 --> f26.6                                        */+  /*                                                                       */+  /* BULLSHIT: Measures from the original glyph must be taken along the    */+  /*           dual projection vector!                                     */+  /*                                                                       */+  static void+  Ins_GC( INS_ARG )+  {+    FT_ULong    L;+    FT_F26Dot6  R;+++    L = (FT_ULong)args[0];++    if ( BOUNDSL( L, CUR.zp2.n_points ) )+    {+      if ( CUR.pedantic_hinting )+      {+        CUR.error = TT_Err_Invalid_Reference;+        return;+      }+      else+        R = 0;+    }+    else+    {+      if ( CUR.opcode & 1 )+        R = CUR_fast_dualproj( &CUR.zp2.org[L] );+      else+        R = CUR_fast_project( &CUR.zp2.cur[L] );+    }++    args[0] = R;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SCFS[]:       Set Coordinate From Stack                               */+  /* Opcode range: 0x48                                                    */+  /* Stack:        f26.6 uint32 -->                                        */+  /*                                                                       */+  /* Formula:                                                              */+  /*                                                                       */+  /*   OA := OA + ( value - OA.p )/( f.p ) * f                             */+  /*                                                                       */+  static void+  Ins_SCFS( INS_ARG )+  {+    FT_Long    K;+    FT_UShort  L;+++    L = (FT_UShort)args[0];++    if ( BOUNDS( L, CUR.zp2.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    K = CUR_fast_project( &CUR.zp2.cur[L] );++    CUR_Func_move( &CUR.zp2, L, args[1] - K );++    /* not part of the specs, but here for safety */++    if ( CUR.GS.gep2 == 0 )+      CUR.zp2.org[L] = CUR.zp2.cur[L];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MD[a]:        Measure Distance                                        */+  /* Opcode range: 0x49-0x4A                                               */+  /* Stack:        uint32 uint32 --> f26.6                                 */+  /*                                                                       */+  /* BULLSHIT: Measure taken in the original glyph must be along the dual  */+  /*           projection vector.                                          */+  /*                                                                       */+  /* Second BULLSHIT: Flag attributes are inverted!                        */+  /*                  0 => measure distance in original outline            */+  /*                  1 => measure distance in grid-fitted outline         */+  /*                                                                       */+  /* Third one: `zp0 - zp1', and not `zp2 - zp1!                           */+  /*                                                                       */+  static void+  Ins_MD( INS_ARG )+  {+    FT_UShort   K, L;+    FT_F26Dot6  D;+++    K = (FT_UShort)args[1];+    L = (FT_UShort)args[0];++    if ( BOUNDS( L, CUR.zp0.n_points ) ||+         BOUNDS( K, CUR.zp1.n_points ) )+    {+      if ( CUR.pedantic_hinting )+      {+        CUR.error = TT_Err_Invalid_Reference;+        return;+      }+      D = 0;+    }+    else+    {+      if ( CUR.opcode & 1 )+        D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );+      else+      {+        FT_Vector*  vec1 = CUR.zp0.orus + L;+        FT_Vector*  vec2 = CUR.zp1.orus + K;+++        if ( CUR.metrics.x_scale == CUR.metrics.y_scale )+        {+          /* this should be faster */+          D = CUR_Func_dualproj( vec1, vec2 );+          D = TT_MULFIX( D, CUR.metrics.x_scale );+        }+        else+        {+          FT_Vector  vec;+++          vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );+          vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );++          D = CUR_fast_dualproj( &vec );+        }+      }+    }++    args[0] = D;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SDPVTL[a]:    Set Dual PVector to Line                                */+  /* Opcode range: 0x86-0x87                                               */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_SDPVTL( INS_ARG )+  {+    FT_Long    A, B, C;+    FT_UShort  p1, p2;   /* was FT_Int in pas type ERROR */+++    p1 = (FT_UShort)args[1];+    p2 = (FT_UShort)args[0];++    if ( BOUNDS( p2, CUR.zp1.n_points ) ||+         BOUNDS( p1, CUR.zp2.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    {+      FT_Vector* v1 = CUR.zp1.org + p2;+      FT_Vector* v2 = CUR.zp2.org + p1;+++      A = v1->x - v2->x;+      B = v1->y - v2->y;+    }++    if ( ( CUR.opcode & 1 ) != 0 )+    {+      C =  B;   /* counter clockwise rotation */+      B =  A;+      A = -C;+    }++    NORMalize( A, B, &CUR.GS.dualVector );++    {+      FT_Vector*  v1 = CUR.zp1.cur + p2;+      FT_Vector*  v2 = CUR.zp2.cur + p1;+++      A = v1->x - v2->x;+      B = v1->y - v2->y;+    }++    if ( ( CUR.opcode & 1 ) != 0 )+    {+      C =  B;   /* counter clockwise rotation */+      B =  A;+      A = -C;+    }++    NORMalize( A, B, &CUR.GS.projVector );++    GUESS_VECTOR( freeVector );++    COMPUTE_Funcs();+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SZP0[]:       Set Zone Pointer 0                                      */+  /* Opcode range: 0x13                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SZP0( INS_ARG )+  {+    switch ( (FT_Int)args[0] )+    {+    case 0:+      CUR.zp0 = CUR.twilight;+      break;++    case 1:+      CUR.zp0 = CUR.pts;+      break;++    default:+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    CUR.GS.gep0 = (FT_UShort)args[0];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SZP1[]:       Set Zone Pointer 1                                      */+  /* Opcode range: 0x14                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SZP1( INS_ARG )+  {+    switch ( (FT_Int)args[0] )+    {+    case 0:+      CUR.zp1 = CUR.twilight;+      break;++    case 1:+      CUR.zp1 = CUR.pts;+      break;++    default:+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    CUR.GS.gep1 = (FT_UShort)args[0];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SZP2[]:       Set Zone Pointer 2                                      */+  /* Opcode range: 0x15                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SZP2( INS_ARG )+  {+    switch ( (FT_Int)args[0] )+    {+    case 0:+      CUR.zp2 = CUR.twilight;+      break;++    case 1:+      CUR.zp2 = CUR.pts;+      break;++    default:+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    CUR.GS.gep2 = (FT_UShort)args[0];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SZPS[]:       Set Zone PointerS                                       */+  /* Opcode range: 0x16                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SZPS( INS_ARG )+  {+    switch ( (FT_Int)args[0] )+    {+    case 0:+      CUR.zp0 = CUR.twilight;+      break;++    case 1:+      CUR.zp0 = CUR.pts;+      break;++    default:+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    CUR.zp1 = CUR.zp0;+    CUR.zp2 = CUR.zp0;++    CUR.GS.gep0 = (FT_UShort)args[0];+    CUR.GS.gep1 = (FT_UShort)args[0];+    CUR.GS.gep2 = (FT_UShort)args[0];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* INSTCTRL[]:   INSTruction ConTRoL                                     */+  /* Opcode range: 0x8e                                                    */+  /* Stack:        int32 int32 -->                                         */+  /*                                                                       */+  static void+  Ins_INSTCTRL( INS_ARG )+  {+    FT_Long  K, L;+++    K = args[1];+    L = args[0];++    if ( K < 1 || K > 2 )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( L != 0 )+        L = K;++    CUR.GS.instruct_control = FT_BOOL(+      ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SCANCTRL[]:   SCAN ConTRoL                                            */+  /* Opcode range: 0x85                                                    */+  /* Stack:        uint32? -->                                             */+  /*                                                                       */+  static void+  Ins_SCANCTRL( INS_ARG )+  {+    FT_Int  A;+++    /* Get Threshold */+    A = (FT_Int)( args[0] & 0xFF );++    if ( A == 0xFF )+    {+      CUR.GS.scan_control = TRUE;+      return;+    }+    else if ( A == 0 )+    {+      CUR.GS.scan_control = FALSE;+      return;+    }++    if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )+      CUR.GS.scan_control = TRUE;++    if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )+      CUR.GS.scan_control = TRUE;++    if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )+      CUR.GS.scan_control = TRUE;++    if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )+      CUR.GS.scan_control = FALSE;++    if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )+      CUR.GS.scan_control = FALSE;++    if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )+      CUR.GS.scan_control = FALSE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SCANTYPE[]:   SCAN TYPE                                               */+  /* Opcode range: 0x8D                                                    */+  /* Stack:        uint32? -->                                             */+  /*                                                                       */+  static void+  Ins_SCANTYPE( INS_ARG )+  {+    if ( args[0] >= 0 )+      CUR.GS.scan_type = (FT_Int)args[0];+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MANAGING OUTLINES                                                     */+  /*                                                                       */+  /*   Instructions appear in the specification's order.                   */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* FLIPPT[]:     FLIP PoinT                                              */+  /* Opcode range: 0x80                                                    */+  /* Stack:        uint32... -->                                           */+  /*                                                                       */+  static void+  Ins_FLIPPT( INS_ARG )+  {+    FT_UShort  point;++    FT_UNUSED_ARG;+++    if ( CUR.top < CUR.GS.loop )+    {+      CUR.error = TT_Err_Too_Few_Arguments;+      return;+    }++    while ( CUR.GS.loop > 0 )+    {+      CUR.args--;++      point = (FT_UShort)CUR.stack[CUR.args];++      if ( BOUNDS( point, CUR.pts.n_points ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+      }+      else+        CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;++      CUR.GS.loop--;+    }++    CUR.GS.loop = 1;+    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* FLIPRGON[]:   FLIP RanGe ON                                           */+  /* Opcode range: 0x81                                                    */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_FLIPRGON( INS_ARG )+  {+    FT_UShort  I, K, L;+++    K = (FT_UShort)args[1];+    L = (FT_UShort)args[0];++    if ( BOUNDS( K, CUR.pts.n_points ) ||+         BOUNDS( L, CUR.pts.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    for ( I = L; I <= K; I++ )+      CUR.pts.tags[I] |= FT_CURVE_TAG_ON;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* FLIPRGOFF:    FLIP RanGe OFF                                          */+  /* Opcode range: 0x82                                                    */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_FLIPRGOFF( INS_ARG )+  {+    FT_UShort  I, K, L;+++    K = (FT_UShort)args[1];+    L = (FT_UShort)args[0];++    if ( BOUNDS( K, CUR.pts.n_points ) ||+         BOUNDS( L, CUR.pts.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    for ( I = L; I <= K; I++ )+      CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;+  }+++  static FT_Bool+  Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6*   x,+                                       FT_F26Dot6*   y,+                                       TT_GlyphZone  zone,+                                       FT_UShort*    refp )+  {+    TT_GlyphZoneRec  zp;+    FT_UShort        p;+    FT_F26Dot6       d;+++    if ( CUR.opcode & 1 )+    {+      zp = CUR.zp0;+      p  = CUR.GS.rp1;+    }+    else+    {+      zp = CUR.zp1;+      p  = CUR.GS.rp2;+    }++    if ( BOUNDS( p, zp.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      *refp = 0;+      return FAILURE;+    }++    *zone = zp;+    *refp = p;++    d = CUR_Func_project( zp.cur + p, zp.org + p );++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    if ( CUR.face->unpatented_hinting )+    {+      if ( CUR.GS.both_x_axis )+      {+        *x = d;+        *y = 0;+      }+      else+      {+        *x = 0;+        *y = d;+      }+    }+    else+#endif+    {+      *x = TT_MULDIV( d,+                      (FT_Long)CUR.GS.freeVector.x * 0x10000L,+                      CUR.F_dot_P );+      *y = TT_MULDIV( d,+                      (FT_Long)CUR.GS.freeVector.y * 0x10000L,+                      CUR.F_dot_P );+    }++    return SUCCESS;+  }+++  static void+  Move_Zp2_Point( EXEC_OP_ FT_UShort   point,+                           FT_F26Dot6  dx,+                           FT_F26Dot6  dy,+                           FT_Bool     touch )+  {+#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    if ( CUR.face->unpatented_hinting )+    {+      if ( CUR.GS.both_x_axis )+      {+        CUR.zp2.cur[point].x += dx;+        if ( touch )+          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;+      }+      else+      {+        CUR.zp2.cur[point].y += dy;+        if ( touch )+          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;+      }+      return;+    }+#endif++    if ( CUR.GS.freeVector.x != 0 )+    {+      CUR.zp2.cur[point].x += dx;+      if ( touch )+        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;+    }++    if ( CUR.GS.freeVector.y != 0 )+    {+      CUR.zp2.cur[point].y += dy;+      if ( touch )+        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SHP[a]:       SHift Point by the last point                           */+  /* Opcode range: 0x32-0x33                                               */+  /* Stack:        uint32... -->                                           */+  /*                                                                       */+  static void+  Ins_SHP( INS_ARG )+  {+    TT_GlyphZoneRec  zp;+    FT_UShort        refp;++    FT_F26Dot6       dx,+                     dy;+    FT_UShort        point;++    FT_UNUSED_ARG;+++    if ( CUR.top < CUR.GS.loop )+    {+      CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )+      return;++    while ( CUR.GS.loop > 0 )+    {+      CUR.args--;+      point = (FT_UShort)CUR.stack[CUR.args];++      if ( BOUNDS( point, CUR.zp2.n_points ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+      }+      else+        /* XXX: UNDOCUMENTED! SHP touches the points */+        MOVE_Zp2_Point( point, dx, dy, TRUE );++      CUR.GS.loop--;+    }++    CUR.GS.loop = 1;+    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SHC[a]:       SHift Contour                                           */+  /* Opcode range: 0x34-35                                                 */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SHC( INS_ARG )+  {+    TT_GlyphZoneRec zp;+    FT_UShort       refp;+    FT_F26Dot6      dx,+                    dy;++    FT_Short        contour;+    FT_UShort       first_point, last_point, i;+++    contour = (FT_UShort)args[0];++    if ( BOUNDS( contour, CUR.pts.n_contours ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )+      return;++    if ( contour == 0 )+      first_point = 0;+    else+      first_point = (FT_UShort)( CUR.pts.contours[contour - 1] + 1 -+                                 CUR.pts.first_point );++    last_point = (FT_UShort)( CUR.pts.contours[contour] -+                              CUR.pts.first_point );++    /* XXX: this is probably wrong... at least it prevents memory */+    /*      corruption when zp2 is the twilight zone              */+    if ( BOUNDS( last_point, CUR.zp2.n_points ) )+    {+      if ( CUR.zp2.n_points > 0 )+        last_point = (FT_UShort)(CUR.zp2.n_points - 1);+      else+        last_point = 0;+    }++    /* XXX: UNDOCUMENTED! SHC touches the points */+    for ( i = first_point; i <= last_point; i++ )+    {+      if ( zp.cur != CUR.zp2.cur || refp != i )+        MOVE_Zp2_Point( i, dx, dy, TRUE );+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SHZ[a]:       SHift Zone                                              */+  /* Opcode range: 0x36-37                                                 */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_SHZ( INS_ARG )+  {+    TT_GlyphZoneRec  zp;+    FT_UShort        refp;+    FT_F26Dot6       dx,+                     dy;++    FT_UShort        last_point, i;+++    if ( BOUNDS( args[0], 2 ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )+      return;++    /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points.  */+    /*      Twilight zone has no contours, so use `n_points'.   */+    /*      Normal zone's `n_points' includes phantoms, so must */+    /*      use end of last contour.                            */+    if ( CUR.GS.gep2 == 0 && CUR.zp2.n_points > 0 )+      last_point = (FT_UShort)( CUR.zp2.n_points - 1 );+    else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )+    {+      last_point = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] );++      if ( BOUNDS( last_point, CUR.zp2.n_points ) )+      {+        if ( CUR.pedantic_hinting )+          CUR.error = TT_Err_Invalid_Reference;+        return;+      }+    }+    else+      last_point = 0;++    /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */+    for ( i = 0; i <= last_point; i++ )+    {+      if ( zp.cur != CUR.zp2.cur || refp != i )+        MOVE_Zp2_Point( i, dx, dy, FALSE );+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* SHPIX[]:      SHift points by a PIXel amount                          */+  /* Opcode range: 0x38                                                    */+  /* Stack:        f26.6 uint32... -->                                     */+  /*                                                                       */+  static void+  Ins_SHPIX( INS_ARG )+  {+    FT_F26Dot6  dx, dy;+    FT_UShort   point;+++    if ( CUR.top < CUR.GS.loop + 1 )+    {+      CUR.error = TT_Err_Invalid_Reference;+      return;+    }++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    if ( CUR.face->unpatented_hinting )+    {+      if ( CUR.GS.both_x_axis )+      {+        dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );+        dy = 0;+      }+      else+      {+        dx = 0;+        dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );+      }+    }+    else+#endif+    {+      dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );+      dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );+    }++    while ( CUR.GS.loop > 0 )+    {+      CUR.args--;++      point = (FT_UShort)CUR.stack[CUR.args];++      if ( BOUNDS( point, CUR.zp2.n_points ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+      }+      else+        MOVE_Zp2_Point( point, dx, dy, TRUE );++      CUR.GS.loop--;+    }++    CUR.GS.loop = 1;+    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MSIRP[a]:     Move Stack Indirect Relative Position                   */+  /* Opcode range: 0x3A-0x3B                                               */+  /* Stack:        f26.6 uint32 -->                                        */+  /*                                                                       */+  static void+  Ins_MSIRP( INS_ARG )+  {+    FT_UShort   point;+    FT_F26Dot6  distance;+++    point = (FT_UShort)args[0];++    if ( BOUNDS( point,      CUR.zp1.n_points ) ||+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    /* XXX: UNDOCUMENTED! behaviour */+    if ( CUR.GS.gep1 == 0 )   /* if the point that is to be moved */+                              /* is in twilight zone              */+    {+      CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];+      CUR_Func_move_orig( &CUR.zp1, point, args[1] );+      CUR.zp1.cur[point] = CUR.zp1.org[point];+    }++    distance = CUR_Func_project( CUR.zp1.cur + point,+                                 CUR.zp0.cur + CUR.GS.rp0 );++    CUR_Func_move( &CUR.zp1, point, args[1] - distance );++    CUR.GS.rp1 = CUR.GS.rp0;+    CUR.GS.rp2 = point;++    if ( ( CUR.opcode & 1 ) != 0 )+      CUR.GS.rp0 = point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MDAP[a]:      Move Direct Absolute Point                              */+  /* Opcode range: 0x2E-0x2F                                               */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_MDAP( INS_ARG )+  {+    FT_UShort   point;+    FT_F26Dot6  cur_dist,+                distance;+++    point = (FT_UShort)args[0];++    if ( BOUNDS( point, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    /* XXX: Is there some undocumented feature while in the */+    /*      twilight zone? ?                                */+    if ( ( CUR.opcode & 1 ) != 0 )+    {+      cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );+      distance = CUR_Func_round( cur_dist,+                                 CUR.tt_metrics.compensations[0] ) - cur_dist;+    }+    else+      distance = 0;++    CUR_Func_move( &CUR.zp0, point, distance );++    CUR.GS.rp0 = point;+    CUR.GS.rp1 = point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MIAP[a]:      Move Indirect Absolute Point                            */+  /* Opcode range: 0x3E-0x3F                                               */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_MIAP( INS_ARG )+  {+    FT_ULong    cvtEntry;+    FT_UShort   point;+    FT_F26Dot6  distance,+                org_dist;+++    cvtEntry = (FT_ULong)args[1];+    point    = (FT_UShort)args[0];++    if ( BOUNDS( point,     CUR.zp0.n_points ) ||+         BOUNDSL( cvtEntry, CUR.cvtSize )      )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    /* XXX: UNDOCUMENTED!                                */+    /*                                                   */+    /* The behaviour of an MIAP instruction is quite     */+    /* different when used in the twilight zone.         */+    /*                                                   */+    /* First, no control value cut-in test is performed  */+    /* as it would fail anyway.  Second, the original    */+    /* point, i.e. (org_x,org_y) of zp0.point, is set    */+    /* to the absolute, unrounded distance found in      */+    /* the CVT.                                          */+    /*                                                   */+    /* This is used in the CVT programs of the Microsoft */+    /* fonts Arial, Times, etc., in order to re-adjust   */+    /* some key font heights.  It allows the use of the  */+    /* IP instruction in the twilight zone, which        */+    /* otherwise would be `illegal' according to the     */+    /* specification.                                    */+    /*                                                   */+    /* We implement it with a special sequence for the   */+    /* twilight zone.  This is a bad hack, but it seems  */+    /* to work.                                          */++    distance = CUR_Func_read_cvt( cvtEntry );++    if ( CUR.GS.gep0 == 0 )   /* If in twilight zone */+    {+      CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.x );+      CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, CUR.GS.freeVector.y ),+      CUR.zp0.cur[point]   = CUR.zp0.org[point];+    }++    org_dist = CUR_fast_project( &CUR.zp0.cur[point] );++    if ( ( CUR.opcode & 1 ) != 0 )   /* rounding and control cutin flag */+    {+      if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin )+        distance = org_dist;++      distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );+    }++    CUR_Func_move( &CUR.zp0, point, distance - org_dist );++    CUR.GS.rp0 = point;+    CUR.GS.rp1 = point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MDRP[abcde]:  Move Direct Relative Point                              */+  /* Opcode range: 0xC0-0xDF                                               */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_MDRP( INS_ARG )+  {+    FT_UShort   point;+    FT_F26Dot6  org_dist, distance;+++    point = (FT_UShort)args[0];++    if ( BOUNDS( point,      CUR.zp1.n_points ) ||+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    /* XXX: Is there some undocumented feature while in the */+    /*      twilight zone?                                  */++    /* XXX: UNDOCUMENTED: twilight zone special case */++    if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )+    {+      FT_Vector*  vec1 = &CUR.zp1.org[point];+      FT_Vector*  vec2 = &CUR.zp0.org[CUR.GS.rp0];+++      org_dist = CUR_Func_dualproj( vec1, vec2 );+    }+    else+    {+      FT_Vector*  vec1 = &CUR.zp1.orus[point];+      FT_Vector*  vec2 = &CUR.zp0.orus[CUR.GS.rp0];+++      if ( CUR.metrics.x_scale == CUR.metrics.y_scale )+      {+        /* this should be faster */+        org_dist = CUR_Func_dualproj( vec1, vec2 );+        org_dist = TT_MULFIX( org_dist, CUR.metrics.x_scale );+      }+      else+      {+        FT_Vector  vec;+++        vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );+        vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );++        org_dist = CUR_fast_dualproj( &vec );+      }+    }++    /* single width cut-in test */++    if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <+         CUR.GS.single_width_cutin )+    {+      if ( org_dist >= 0 )+        org_dist = CUR.GS.single_width_value;+      else+        org_dist = -CUR.GS.single_width_value;+    }++    /* round flag */++    if ( ( CUR.opcode & 4 ) != 0 )+      distance = CUR_Func_round(+                   org_dist,+                   CUR.tt_metrics.compensations[CUR.opcode & 3] );+    else+      distance = ROUND_None(+                   org_dist,+                   CUR.tt_metrics.compensations[CUR.opcode & 3] );++    /* minimum distance flag */++    if ( ( CUR.opcode & 8 ) != 0 )+    {+      if ( org_dist >= 0 )+      {+        if ( distance < CUR.GS.minimum_distance )+          distance = CUR.GS.minimum_distance;+      }+      else+      {+        if ( distance > -CUR.GS.minimum_distance )+          distance = -CUR.GS.minimum_distance;+      }+    }++    /* now move the point */++    org_dist = CUR_Func_project( CUR.zp1.cur + point,+                                 CUR.zp0.cur + CUR.GS.rp0 );++    CUR_Func_move( &CUR.zp1, point, distance - org_dist );++    CUR.GS.rp1 = CUR.GS.rp0;+    CUR.GS.rp2 = point;++    if ( ( CUR.opcode & 16 ) != 0 )+      CUR.GS.rp0 = point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MIRP[abcde]:  Move Indirect Relative Point                            */+  /* Opcode range: 0xE0-0xFF                                               */+  /* Stack:        int32? uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_MIRP( INS_ARG )+  {+    FT_UShort   point;+    FT_ULong    cvtEntry;++    FT_F26Dot6  cvt_dist,+                distance,+                cur_dist,+                org_dist;+++    point    = (FT_UShort)args[0];+    cvtEntry = (FT_ULong)( args[1] + 1 );++    /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */++    if ( BOUNDS( point,      CUR.zp1.n_points ) ||+         BOUNDSL( cvtEntry,  CUR.cvtSize + 1 )  ||+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( !cvtEntry )+      cvt_dist = 0;+    else+      cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );++    /* single width test */++    if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <+         CUR.GS.single_width_cutin )+    {+      if ( cvt_dist >= 0 )+        cvt_dist =  CUR.GS.single_width_value;+      else+        cvt_dist = -CUR.GS.single_width_value;+    }++    /* XXX: UNDOCUMENTED! -- twilight zone */++    if ( CUR.GS.gep1 == 0 )+    {+      CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x ++                             TT_MulFix14( (FT_UInt32)cvt_dist,+                                          CUR.GS.freeVector.x );++      CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y ++                             TT_MulFix14( (FT_UInt32)cvt_dist,+                                          CUR.GS.freeVector.y );++      CUR.zp1.cur[point] = CUR.zp0.cur[point];+    }++    org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],+                                  &CUR.zp0.org[CUR.GS.rp0] );+    cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],+                                  &CUR.zp0.cur[CUR.GS.rp0] );++    /* auto-flip test */++    if ( CUR.GS.auto_flip )+    {+      if ( ( org_dist ^ cvt_dist ) < 0 )+        cvt_dist = -cvt_dist;+    }++    /* control value cutin and round */++    if ( ( CUR.opcode & 4 ) != 0 )+    {+      /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */+      /*      refer to the same zone.                                  */++      if ( CUR.GS.gep0 == CUR.GS.gep1 )+        if ( FT_ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin )+          cvt_dist = org_dist;++      distance = CUR_Func_round(+                   cvt_dist,+                   CUR.tt_metrics.compensations[CUR.opcode & 3] );+    }+    else+      distance = ROUND_None(+                   cvt_dist,+                   CUR.tt_metrics.compensations[CUR.opcode & 3] );++    /* minimum distance test */++    if ( ( CUR.opcode & 8 ) != 0 )+    {+      if ( org_dist >= 0 )+      {+        if ( distance < CUR.GS.minimum_distance )+          distance = CUR.GS.minimum_distance;+      }+      else+      {+        if ( distance > -CUR.GS.minimum_distance )+          distance = -CUR.GS.minimum_distance;+      }+    }++    CUR_Func_move( &CUR.zp1, point, distance - cur_dist );++    CUR.GS.rp1 = CUR.GS.rp0;++    if ( ( CUR.opcode & 16 ) != 0 )+      CUR.GS.rp0 = point;++    /* XXX: UNDOCUMENTED! */+    CUR.GS.rp2 = point;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ALIGNRP[]:    ALIGN Relative Point                                    */+  /* Opcode range: 0x3C                                                    */+  /* Stack:        uint32 uint32... -->                                    */+  /*                                                                       */+  static void+  Ins_ALIGNRP( INS_ARG )+  {+    FT_UShort   point;+    FT_F26Dot6  distance;++    FT_UNUSED_ARG;+++    if ( CUR.top < CUR.GS.loop ||+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    while ( CUR.GS.loop > 0 )+    {+      CUR.args--;++      point = (FT_UShort)CUR.stack[CUR.args];++      if ( BOUNDS( point, CUR.zp1.n_points ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+      }+      else+      {+        distance = CUR_Func_project( CUR.zp1.cur + point,+                                     CUR.zp0.cur + CUR.GS.rp0 );++        CUR_Func_move( &CUR.zp1, point, -distance );+      }++      CUR.GS.loop--;+    }++    CUR.GS.loop = 1;+    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ISECT[]:      moves point to InterSECTion                             */+  /* Opcode range: 0x0F                                                    */+  /* Stack:        5 * uint32 -->                                          */+  /*                                                                       */+  static void+  Ins_ISECT( INS_ARG )+  {+    FT_UShort   point,+                a0, a1,+                b0, b1;++    FT_F26Dot6  discriminant;++    FT_F26Dot6  dx,  dy,+                dax, day,+                dbx, dby;++    FT_F26Dot6  val;++    FT_Vector   R;+++    point = (FT_UShort)args[0];++    a0 = (FT_UShort)args[1];+    a1 = (FT_UShort)args[2];+    b0 = (FT_UShort)args[3];+    b1 = (FT_UShort)args[4];++    if ( BOUNDS( b0, CUR.zp0.n_points )  ||+         BOUNDS( b1, CUR.zp0.n_points )  ||+         BOUNDS( a0, CUR.zp1.n_points )  ||+         BOUNDS( a1, CUR.zp1.n_points )  ||+         BOUNDS( point, CUR.zp2.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;+    dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;++    dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;+    day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;++    dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;+    dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;++    CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;++    discriminant = TT_MULDIV( dax, -dby, 0x40 ) ++                   TT_MULDIV( day, dbx, 0x40 );++    if ( FT_ABS( discriminant ) >= 0x40 )+    {+      val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 );++      R.x = TT_MULDIV( val, dax, discriminant );+      R.y = TT_MULDIV( val, day, discriminant );++      CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;+      CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;+    }+    else+    {+      /* else, take the middle of the middles of A and B */++      CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x ++                               CUR.zp1.cur[a1].x ++                               CUR.zp0.cur[b0].x ++                               CUR.zp0.cur[b1].x ) / 4;+      CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y ++                               CUR.zp1.cur[a1].y ++                               CUR.zp0.cur[b0].y ++                               CUR.zp0.cur[b1].y ) / 4;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* ALIGNPTS[]:   ALIGN PoinTS                                            */+  /* Opcode range: 0x27                                                    */+  /* Stack:        uint32 uint32 -->                                       */+  /*                                                                       */+  static void+  Ins_ALIGNPTS( INS_ARG )+  {+    FT_UShort   p1, p2;+    FT_F26Dot6  distance;+++    p1 = (FT_UShort)args[0];+    p2 = (FT_UShort)args[1];++    if ( BOUNDS( p1, CUR.zp1.n_points ) ||+         BOUNDS( p2, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    distance = CUR_Func_project( CUR.zp0.cur + p2,+                                 CUR.zp1.cur + p1 ) / 2;++    CUR_Func_move( &CUR.zp1, p1, distance );+    CUR_Func_move( &CUR.zp0, p2, -distance );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* IP[]:         Interpolate Point                                       */+  /* Opcode range: 0x39                                                    */+  /* Stack:        uint32... -->                                           */+  /*                                                                       */++  /* SOMETIMES, DUMBER CODE IS BETTER CODE */++  static void+  Ins_IP( INS_ARG )+  {+    FT_F26Dot6  old_range, cur_range;+    FT_Vector*  orus_base;+    FT_Vector*  cur_base;+    FT_Int      twilight;++    FT_UNUSED_ARG;+++    if ( CUR.top < CUR.GS.loop )+    {+      CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    /*+     * We need to deal in a special way with the twilight zone.+     * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),+     * for every n.+     */+    twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;++    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    if ( twilight )+      orus_base = &CUR.zp0.org[CUR.GS.rp1];+    else+      orus_base = &CUR.zp0.orus[CUR.GS.rp1];++    cur_base = &CUR.zp0.cur[CUR.GS.rp1];++    /* XXX: There are some glyphs in some braindead but popular */+    /*      fonts out there (e.g. [aeu]grave in monotype.ttf)   */+    /*      calling IP[] with bad values of rp[12].             */+    /*      Do something sane when this odd thing happens.      */+    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||+         BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )+    {+      old_range = 0;+      cur_range = 0;+    }+    else+    {+      if ( twilight )+        old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],+                                       orus_base );+      else+        old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],+                                       orus_base );++      cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );+    }++    for ( ; CUR.GS.loop > 0; --CUR.GS.loop )+    {+      FT_UInt     point = (FT_UInt)CUR.stack[--CUR.args];+      FT_F26Dot6  org_dist, cur_dist, new_dist;+++      /* check point bounds */+      if ( BOUNDS( point, CUR.zp2.n_points ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+        continue;+      }++      if ( twilight )+        org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );+      else+        org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );++      cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );++      if ( org_dist )+        new_dist = ( old_range != 0 )+                     ? TT_MULDIV( org_dist, cur_range, old_range )+                     : cur_dist;+      else+        new_dist = 0;++      CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );+    }+    CUR.GS.loop = 1;+    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* UTP[a]:       UnTouch Point                                           */+  /* Opcode range: 0x29                                                    */+  /* Stack:        uint32 -->                                              */+  /*                                                                       */+  static void+  Ins_UTP( INS_ARG )+  {+    FT_UShort  point;+    FT_Byte    mask;+++    point = (FT_UShort)args[0];++    if ( BOUNDS( point, CUR.zp0.n_points ) )+    {+      if ( CUR.pedantic_hinting )+        CUR.error = TT_Err_Invalid_Reference;+      return;+    }++    mask = 0xFF;++    if ( CUR.GS.freeVector.x != 0 )+      mask &= ~FT_CURVE_TAG_TOUCH_X;++    if ( CUR.GS.freeVector.y != 0 )+      mask &= ~FT_CURVE_TAG_TOUCH_Y;++    CUR.zp0.tags[point] &= mask;+  }+++  /* Local variables for Ins_IUP: */+  typedef struct  IUP_WorkerRec_+  {+    FT_Vector*  orgs;   /* original and current coordinate */+    FT_Vector*  curs;   /* arrays                          */+    FT_Vector*  orus;+    FT_UInt     max_points;++  } IUP_WorkerRec, *IUP_Worker;+++  static void+  _iup_worker_shift( IUP_Worker  worker,+                     FT_UInt     p1,+                     FT_UInt     p2,+                     FT_UInt     p )+  {+    FT_UInt     i;+    FT_F26Dot6  dx;+++    dx = worker->curs[p].x - worker->orgs[p].x;+    if ( dx != 0 )+    {+      for ( i = p1; i < p; i++ )+        worker->curs[i].x += dx;++      for ( i = p + 1; i <= p2; i++ )+        worker->curs[i].x += dx;+    }+  }+++  static void+  _iup_worker_interpolate( IUP_Worker  worker,+                           FT_UInt     p1,+                           FT_UInt     p2,+                           FT_UInt     ref1,+                           FT_UInt     ref2 )+  {+    FT_UInt     i;+    FT_F26Dot6  orus1, orus2, org1, org2, delta1, delta2;+++    if ( p1 > p2 )+      return;++    if ( BOUNDS( ref1, worker->max_points ) ||+         BOUNDS( ref2, worker->max_points ) )+      return;++    orus1 = worker->orus[ref1].x;+    orus2 = worker->orus[ref2].x;++    if ( orus1 > orus2 )+    {+      FT_F26Dot6  tmp_o;+      FT_UInt     tmp_r;+++      tmp_o = orus1;+      orus1 = orus2;+      orus2 = tmp_o;++      tmp_r = ref1;+      ref1  = ref2;+      ref2  = tmp_r;+    }++    org1   = worker->orgs[ref1].x;+    org2   = worker->orgs[ref2].x;+    delta1 = worker->curs[ref1].x - org1;+    delta2 = worker->curs[ref2].x - org2;++    if ( orus1 == orus2 )+    {+      /* simple shift of untouched points */+      for ( i = p1; i <= p2; i++ )+      {+        FT_F26Dot6  x = worker->orgs[i].x;+++        if ( x <= org1 )+          x += delta1;+        else+          x += delta2;++        worker->curs[i].x = x;+      }+    }+    else+    {+      FT_Fixed  scale       = 0;+      FT_Bool   scale_valid = 0;+++      /* interpolation */+      for ( i = p1; i <= p2; i++ )+      {+        FT_F26Dot6  x = worker->orgs[i].x;+++        if ( x <= org1 )+          x += delta1;++        else if ( x >= org2 )+          x += delta2;++        else+        {+          if ( !scale_valid )+          {+            scale_valid = 1;+            scale       = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ),+                                     0x10000L, orus2 - orus1 );+          }++          x = ( org1 + delta1 ) ++              TT_MULFIX( worker->orus[i].x - orus1, scale );+        }+        worker->curs[i].x = x;+      }+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* IUP[a]:       Interpolate Untouched Points                            */+  /* Opcode range: 0x30-0x31                                               */+  /* Stack:        -->                                                     */+  /*                                                                       */+  static void+  Ins_IUP( INS_ARG )+  {+    IUP_WorkerRec  V;+    FT_Byte        mask;++    FT_UInt   first_point;   /* first point of contour        */+    FT_UInt   end_point;     /* end point (last+1) of contour */++    FT_UInt   first_touched; /* first touched point in contour   */+    FT_UInt   cur_touched;   /* current touched point in contour */++    FT_UInt   point;         /* current point   */+    FT_Short  contour;       /* current contour */++    FT_UNUSED_ARG;+++    /* ignore empty outlines */+    if ( CUR.pts.n_contours == 0 )+      return;++    if ( CUR.opcode & 1 )+    {+      mask   = FT_CURVE_TAG_TOUCH_X;+      V.orgs = CUR.pts.org;+      V.curs = CUR.pts.cur;+      V.orus = CUR.pts.orus;+    }+    else+    {+      mask   = FT_CURVE_TAG_TOUCH_Y;+      V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );+      V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );+      V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );+    }+    V.max_points = CUR.pts.n_points;++    contour = 0;+    point   = 0;++    do+    {+      end_point   = CUR.pts.contours[contour] - CUR.pts.first_point;+      first_point = point;++      if ( BOUNDS ( end_point, CUR.pts.n_points ) )+        end_point = CUR.pts.n_points - 1;++      while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )+        point++;++      if ( point <= end_point )+      {+        first_touched = point;+        cur_touched   = point;++        point++;++        while ( point <= end_point )+        {+          if ( ( CUR.pts.tags[point] & mask ) != 0 )+          {+            _iup_worker_interpolate( &V,+                                     cur_touched + 1,+                                     point - 1,+                                     cur_touched,+                                     point );+            cur_touched = point;+          }++          point++;+        }++        if ( cur_touched == first_touched )+          _iup_worker_shift( &V, first_point, end_point, cur_touched );+        else+        {+          _iup_worker_interpolate( &V,+                                   (FT_UShort)( cur_touched + 1 ),+                                   end_point,+                                   cur_touched,+                                   first_touched );++          if ( first_touched > 0 )+            _iup_worker_interpolate( &V,+                                     first_point,+                                     first_touched - 1,+                                     cur_touched,+                                     first_touched );+        }+      }+      contour++;+    } while ( contour < CUR.pts.n_contours );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DELTAPn[]:    DELTA exceptions P1, P2, P3                             */+  /* Opcode range: 0x5D,0x71,0x72                                          */+  /* Stack:        uint32 (2 * uint32)... -->                              */+  /*                                                                       */+  static void+  Ins_DELTAP( INS_ARG )+  {+    FT_ULong   k, nump;+    FT_UShort  A;+    FT_ULong   C;+    FT_Long    B;+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    /* Delta hinting is covered by US Patent 5159668. */+    if ( CUR.face->unpatented_hinting )+    {+      FT_Long  n = args[0] * 2;+++      if ( CUR.args < n )+      {+        CUR.error = TT_Err_Too_Few_Arguments;+        return;+      }++      CUR.args -= n;+      CUR.new_top = CUR.args;+      return;+    }+#endif++    nump = (FT_ULong)args[0];   /* some points theoretically may occur more+                                   than once, thus UShort isn't enough */++    for ( k = 1; k <= nump; k++ )+    {+      if ( CUR.args < 2 )+      {+        CUR.error = TT_Err_Too_Few_Arguments;+        return;+      }++      CUR.args -= 2;++      A = (FT_UShort)CUR.stack[CUR.args + 1];+      B = CUR.stack[CUR.args];++      /* XXX: Because some popular fonts contain some invalid DeltaP */+      /*      instructions, we simply ignore them when the stacked   */+      /*      point reference is off limit, rather than returning an */+      /*      error.  As a delta instruction doesn't change a glyph  */+      /*      in great ways, this shouldn't be a problem.            */++      if ( !BOUNDS( A, CUR.zp0.n_points ) )+      {+        C = ( (FT_ULong)B & 0xF0 ) >> 4;++        switch ( CUR.opcode )+        {+        case 0x5D:+          break;++        case 0x71:+          C += 16;+          break;++        case 0x72:+          C += 32;+          break;+        }++        C += CUR.GS.delta_base;++        if ( CURRENT_Ppem() == (FT_Long)C )+        {+          B = ( (FT_ULong)B & 0xF ) - 8;+          if ( B >= 0 )+            B++;+          B = B * 64 / ( 1L << CUR.GS.delta_shift );++          CUR_Func_move( &CUR.zp0, A, B );+        }+      }+      else+        if ( CUR.pedantic_hinting )+          CUR.error = TT_Err_Invalid_Reference;+    }++    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* DELTACn[]:    DELTA exceptions C1, C2, C3                             */+  /* Opcode range: 0x73,0x74,0x75                                          */+  /* Stack:        uint32 (2 * uint32)... -->                              */+  /*                                                                       */+  static void+  Ins_DELTAC( INS_ARG )+  {+    FT_ULong  nump, k;+    FT_ULong  A, C;+    FT_Long   B;+++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    /* Delta hinting is covered by US Patent 5159668. */+    if ( CUR.face->unpatented_hinting )+    {+      FT_Long  n = args[0] * 2;+++      if ( CUR.args < n )+      {+        CUR.error = TT_Err_Too_Few_Arguments;+        return;+      }++      CUR.args -= n;+      CUR.new_top = CUR.args;+      return;+    }+#endif++    nump = (FT_ULong)args[0];++    for ( k = 1; k <= nump; k++ )+    {+      if ( CUR.args < 2 )+      {+        CUR.error = TT_Err_Too_Few_Arguments;+        return;+      }++      CUR.args -= 2;++      A = (FT_ULong)CUR.stack[CUR.args + 1];+      B = CUR.stack[CUR.args];++      if ( BOUNDSL( A, CUR.cvtSize ) )+      {+        if ( CUR.pedantic_hinting )+        {+          CUR.error = TT_Err_Invalid_Reference;+          return;+        }+      }+      else+      {+        C = ( (FT_ULong)B & 0xF0 ) >> 4;++        switch ( CUR.opcode )+        {+        case 0x73:+          break;++        case 0x74:+          C += 16;+          break;++        case 0x75:+          C += 32;+          break;+        }++        C += CUR.GS.delta_base;++        if ( CURRENT_Ppem() == (FT_Long)C )+        {+          B = ( (FT_ULong)B & 0xF ) - 8;+          if ( B >= 0 )+            B++;+          B = B * 64 / ( 1L << CUR.GS.delta_shift );++          CUR_Func_move_cvt( A, B );+        }+      }+    }++    CUR.new_top = CUR.args;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* MISC. INSTRUCTIONS                                                    */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* GETINFO[]:    GET INFOrmation                                         */+  /* Opcode range: 0x88                                                    */+  /* Stack:        uint32 --> uint32                                       */+  /*                                                                       */+  static void+  Ins_GETINFO( INS_ARG )+  {+    FT_Long  K;+++    K = 0;++    /* We return MS rasterizer version 1.7 for the font scaler. */+    if ( ( args[0] & 1 ) != 0 )+      K = 35;++    /* Has the glyph been rotated? */+    if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )+      K |= 0x80;++    /* Has the glyph been stretched? */+    if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )+      K |= 1 << 8;++    /* Are we hinting for grayscale? */+    if ( ( args[0] & 32 ) != 0 && CUR.grayscale )+      K |= 1 << 12;++    args[0] = K;+  }+++  static void+  Ins_UNKNOWN( INS_ARG )+  {+    TT_DefRecord*  def   = CUR.IDefs;+    TT_DefRecord*  limit = def + CUR.numIDefs;++    FT_UNUSED_ARG;+++    for ( ; def < limit; def++ )+    {+      if ( (FT_Byte)def->opc == CUR.opcode && def->active )+      {+        TT_CallRec*  call;+++        if ( CUR.callTop >= CUR.callSize )+        {+          CUR.error = TT_Err_Stack_Overflow;+          return;+        }++        call = CUR.callStack + CUR.callTop++;++        call->Caller_Range = CUR.curRange;+        call->Caller_IP    = CUR.IP + 1;+        call->Cur_Count    = 1;+        call->Cur_Restart  = def->start;++        INS_Goto_CodeRange( def->range, def->start );++        CUR.step_ins = FALSE;+        return;+      }+    }++    CUR.error = TT_Err_Invalid_Opcode;+  }+++#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH+++  static+  TInstruction_Function  Instruct_Dispatch[256] =+  {+    /* Opcodes are gathered in groups of 16. */+    /* Please keep the spaces as they are.   */++    /*  SVTCA  y  */  Ins_SVTCA,+    /*  SVTCA  x  */  Ins_SVTCA,+    /*  SPvTCA y  */  Ins_SPVTCA,+    /*  SPvTCA x  */  Ins_SPVTCA,+    /*  SFvTCA y  */  Ins_SFVTCA,+    /*  SFvTCA x  */  Ins_SFVTCA,+    /*  SPvTL //  */  Ins_SPVTL,+    /*  SPvTL +   */  Ins_SPVTL,+    /*  SFvTL //  */  Ins_SFVTL,+    /*  SFvTL +   */  Ins_SFVTL,+    /*  SPvFS     */  Ins_SPVFS,+    /*  SFvFS     */  Ins_SFVFS,+    /*  GPV       */  Ins_GPV,+    /*  GFV       */  Ins_GFV,+    /*  SFvTPv    */  Ins_SFVTPV,+    /*  ISECT     */  Ins_ISECT,++    /*  SRP0      */  Ins_SRP0,+    /*  SRP1      */  Ins_SRP1,+    /*  SRP2      */  Ins_SRP2,+    /*  SZP0      */  Ins_SZP0,+    /*  SZP1      */  Ins_SZP1,+    /*  SZP2      */  Ins_SZP2,+    /*  SZPS      */  Ins_SZPS,+    /*  SLOOP     */  Ins_SLOOP,+    /*  RTG       */  Ins_RTG,+    /*  RTHG      */  Ins_RTHG,+    /*  SMD       */  Ins_SMD,+    /*  ELSE      */  Ins_ELSE,+    /*  JMPR      */  Ins_JMPR,+    /*  SCvTCi    */  Ins_SCVTCI,+    /*  SSwCi     */  Ins_SSWCI,+    /*  SSW       */  Ins_SSW,++    /*  DUP       */  Ins_DUP,+    /*  POP       */  Ins_POP,+    /*  CLEAR     */  Ins_CLEAR,+    /*  SWAP      */  Ins_SWAP,+    /*  DEPTH     */  Ins_DEPTH,+    /*  CINDEX    */  Ins_CINDEX,+    /*  MINDEX    */  Ins_MINDEX,+    /*  AlignPTS  */  Ins_ALIGNPTS,+    /*  INS_0x28  */  Ins_UNKNOWN,+    /*  UTP       */  Ins_UTP,+    /*  LOOPCALL  */  Ins_LOOPCALL,+    /*  CALL      */  Ins_CALL,+    /*  FDEF      */  Ins_FDEF,+    /*  ENDF      */  Ins_ENDF,+    /*  MDAP[0]   */  Ins_MDAP,+    /*  MDAP[1]   */  Ins_MDAP,++    /*  IUP[0]    */  Ins_IUP,+    /*  IUP[1]    */  Ins_IUP,+    /*  SHP[0]    */  Ins_SHP,+    /*  SHP[1]    */  Ins_SHP,+    /*  SHC[0]    */  Ins_SHC,+    /*  SHC[1]    */  Ins_SHC,+    /*  SHZ[0]    */  Ins_SHZ,+    /*  SHZ[1]    */  Ins_SHZ,+    /*  SHPIX     */  Ins_SHPIX,+    /*  IP        */  Ins_IP,+    /*  MSIRP[0]  */  Ins_MSIRP,+    /*  MSIRP[1]  */  Ins_MSIRP,+    /*  AlignRP   */  Ins_ALIGNRP,+    /*  RTDG      */  Ins_RTDG,+    /*  MIAP[0]   */  Ins_MIAP,+    /*  MIAP[1]   */  Ins_MIAP,++    /*  NPushB    */  Ins_NPUSHB,+    /*  NPushW    */  Ins_NPUSHW,+    /*  WS        */  Ins_WS,+    /*  RS        */  Ins_RS,+    /*  WCvtP     */  Ins_WCVTP,+    /*  RCvt      */  Ins_RCVT,+    /*  GC[0]     */  Ins_GC,+    /*  GC[1]     */  Ins_GC,+    /*  SCFS      */  Ins_SCFS,+    /*  MD[0]     */  Ins_MD,+    /*  MD[1]     */  Ins_MD,+    /*  MPPEM     */  Ins_MPPEM,+    /*  MPS       */  Ins_MPS,+    /*  FlipON    */  Ins_FLIPON,+    /*  FlipOFF   */  Ins_FLIPOFF,+    /*  DEBUG     */  Ins_DEBUG,++    /*  LT        */  Ins_LT,+    /*  LTEQ      */  Ins_LTEQ,+    /*  GT        */  Ins_GT,+    /*  GTEQ      */  Ins_GTEQ,+    /*  EQ        */  Ins_EQ,+    /*  NEQ       */  Ins_NEQ,+    /*  ODD       */  Ins_ODD,+    /*  EVEN      */  Ins_EVEN,+    /*  IF        */  Ins_IF,+    /*  EIF       */  Ins_EIF,+    /*  AND       */  Ins_AND,+    /*  OR        */  Ins_OR,+    /*  NOT       */  Ins_NOT,+    /*  DeltaP1   */  Ins_DELTAP,+    /*  SDB       */  Ins_SDB,+    /*  SDS       */  Ins_SDS,++    /*  ADD       */  Ins_ADD,+    /*  SUB       */  Ins_SUB,+    /*  DIV       */  Ins_DIV,+    /*  MUL       */  Ins_MUL,+    /*  ABS       */  Ins_ABS,+    /*  NEG       */  Ins_NEG,+    /*  FLOOR     */  Ins_FLOOR,+    /*  CEILING   */  Ins_CEILING,+    /*  ROUND[0]  */  Ins_ROUND,+    /*  ROUND[1]  */  Ins_ROUND,+    /*  ROUND[2]  */  Ins_ROUND,+    /*  ROUND[3]  */  Ins_ROUND,+    /*  NROUND[0] */  Ins_NROUND,+    /*  NROUND[1] */  Ins_NROUND,+    /*  NROUND[2] */  Ins_NROUND,+    /*  NROUND[3] */  Ins_NROUND,++    /*  WCvtF     */  Ins_WCVTF,+    /*  DeltaP2   */  Ins_DELTAP,+    /*  DeltaP3   */  Ins_DELTAP,+    /*  DeltaCn[0] */ Ins_DELTAC,+    /*  DeltaCn[1] */ Ins_DELTAC,+    /*  DeltaCn[2] */ Ins_DELTAC,+    /*  SROUND    */  Ins_SROUND,+    /*  S45Round  */  Ins_S45ROUND,+    /*  JROT      */  Ins_JROT,+    /*  JROF      */  Ins_JROF,+    /*  ROFF      */  Ins_ROFF,+    /*  INS_0x7B  */  Ins_UNKNOWN,+    /*  RUTG      */  Ins_RUTG,+    /*  RDTG      */  Ins_RDTG,+    /*  SANGW     */  Ins_SANGW,+    /*  AA        */  Ins_AA,++    /*  FlipPT    */  Ins_FLIPPT,+    /*  FlipRgON  */  Ins_FLIPRGON,+    /*  FlipRgOFF */  Ins_FLIPRGOFF,+    /*  INS_0x83  */  Ins_UNKNOWN,+    /*  INS_0x84  */  Ins_UNKNOWN,+    /*  ScanCTRL  */  Ins_SCANCTRL,+    /*  SDPVTL[0] */  Ins_SDPVTL,+    /*  SDPVTL[1] */  Ins_SDPVTL,+    /*  GetINFO   */  Ins_GETINFO,+    /*  IDEF      */  Ins_IDEF,+    /*  ROLL      */  Ins_ROLL,+    /*  MAX       */  Ins_MAX,+    /*  MIN       */  Ins_MIN,+    /*  ScanTYPE  */  Ins_SCANTYPE,+    /*  InstCTRL  */  Ins_INSTCTRL,+    /*  INS_0x8F  */  Ins_UNKNOWN,++    /*  INS_0x90  */   Ins_UNKNOWN,+    /*  INS_0x91  */   Ins_UNKNOWN,+    /*  INS_0x92  */   Ins_UNKNOWN,+    /*  INS_0x93  */   Ins_UNKNOWN,+    /*  INS_0x94  */   Ins_UNKNOWN,+    /*  INS_0x95  */   Ins_UNKNOWN,+    /*  INS_0x96  */   Ins_UNKNOWN,+    /*  INS_0x97  */   Ins_UNKNOWN,+    /*  INS_0x98  */   Ins_UNKNOWN,+    /*  INS_0x99  */   Ins_UNKNOWN,+    /*  INS_0x9A  */   Ins_UNKNOWN,+    /*  INS_0x9B  */   Ins_UNKNOWN,+    /*  INS_0x9C  */   Ins_UNKNOWN,+    /*  INS_0x9D  */   Ins_UNKNOWN,+    /*  INS_0x9E  */   Ins_UNKNOWN,+    /*  INS_0x9F  */   Ins_UNKNOWN,++    /*  INS_0xA0  */   Ins_UNKNOWN,+    /*  INS_0xA1  */   Ins_UNKNOWN,+    /*  INS_0xA2  */   Ins_UNKNOWN,+    /*  INS_0xA3  */   Ins_UNKNOWN,+    /*  INS_0xA4  */   Ins_UNKNOWN,+    /*  INS_0xA5  */   Ins_UNKNOWN,+    /*  INS_0xA6  */   Ins_UNKNOWN,+    /*  INS_0xA7  */   Ins_UNKNOWN,+    /*  INS_0xA8  */   Ins_UNKNOWN,+    /*  INS_0xA9  */   Ins_UNKNOWN,+    /*  INS_0xAA  */   Ins_UNKNOWN,+    /*  INS_0xAB  */   Ins_UNKNOWN,+    /*  INS_0xAC  */   Ins_UNKNOWN,+    /*  INS_0xAD  */   Ins_UNKNOWN,+    /*  INS_0xAE  */   Ins_UNKNOWN,+    /*  INS_0xAF  */   Ins_UNKNOWN,++    /*  PushB[0]  */  Ins_PUSHB,+    /*  PushB[1]  */  Ins_PUSHB,+    /*  PushB[2]  */  Ins_PUSHB,+    /*  PushB[3]  */  Ins_PUSHB,+    /*  PushB[4]  */  Ins_PUSHB,+    /*  PushB[5]  */  Ins_PUSHB,+    /*  PushB[6]  */  Ins_PUSHB,+    /*  PushB[7]  */  Ins_PUSHB,+    /*  PushW[0]  */  Ins_PUSHW,+    /*  PushW[1]  */  Ins_PUSHW,+    /*  PushW[2]  */  Ins_PUSHW,+    /*  PushW[3]  */  Ins_PUSHW,+    /*  PushW[4]  */  Ins_PUSHW,+    /*  PushW[5]  */  Ins_PUSHW,+    /*  PushW[6]  */  Ins_PUSHW,+    /*  PushW[7]  */  Ins_PUSHW,++    /*  MDRP[00]  */  Ins_MDRP,+    /*  MDRP[01]  */  Ins_MDRP,+    /*  MDRP[02]  */  Ins_MDRP,+    /*  MDRP[03]  */  Ins_MDRP,+    /*  MDRP[04]  */  Ins_MDRP,+    /*  MDRP[05]  */  Ins_MDRP,+    /*  MDRP[06]  */  Ins_MDRP,+    /*  MDRP[07]  */  Ins_MDRP,+    /*  MDRP[08]  */  Ins_MDRP,+    /*  MDRP[09]  */  Ins_MDRP,+    /*  MDRP[10]  */  Ins_MDRP,+    /*  MDRP[11]  */  Ins_MDRP,+    /*  MDRP[12]  */  Ins_MDRP,+    /*  MDRP[13]  */  Ins_MDRP,+    /*  MDRP[14]  */  Ins_MDRP,+    /*  MDRP[15]  */  Ins_MDRP,++    /*  MDRP[16]  */  Ins_MDRP,+    /*  MDRP[17]  */  Ins_MDRP,+    /*  MDRP[18]  */  Ins_MDRP,+    /*  MDRP[19]  */  Ins_MDRP,+    /*  MDRP[20]  */  Ins_MDRP,+    /*  MDRP[21]  */  Ins_MDRP,+    /*  MDRP[22]  */  Ins_MDRP,+    /*  MDRP[23]  */  Ins_MDRP,+    /*  MDRP[24]  */  Ins_MDRP,+    /*  MDRP[25]  */  Ins_MDRP,+    /*  MDRP[26]  */  Ins_MDRP,+    /*  MDRP[27]  */  Ins_MDRP,+    /*  MDRP[28]  */  Ins_MDRP,+    /*  MDRP[29]  */  Ins_MDRP,+    /*  MDRP[30]  */  Ins_MDRP,+    /*  MDRP[31]  */  Ins_MDRP,++    /*  MIRP[00]  */  Ins_MIRP,+    /*  MIRP[01]  */  Ins_MIRP,+    /*  MIRP[02]  */  Ins_MIRP,+    /*  MIRP[03]  */  Ins_MIRP,+    /*  MIRP[04]  */  Ins_MIRP,+    /*  MIRP[05]  */  Ins_MIRP,+    /*  MIRP[06]  */  Ins_MIRP,+    /*  MIRP[07]  */  Ins_MIRP,+    /*  MIRP[08]  */  Ins_MIRP,+    /*  MIRP[09]  */  Ins_MIRP,+    /*  MIRP[10]  */  Ins_MIRP,+    /*  MIRP[11]  */  Ins_MIRP,+    /*  MIRP[12]  */  Ins_MIRP,+    /*  MIRP[13]  */  Ins_MIRP,+    /*  MIRP[14]  */  Ins_MIRP,+    /*  MIRP[15]  */  Ins_MIRP,++    /*  MIRP[16]  */  Ins_MIRP,+    /*  MIRP[17]  */  Ins_MIRP,+    /*  MIRP[18]  */  Ins_MIRP,+    /*  MIRP[19]  */  Ins_MIRP,+    /*  MIRP[20]  */  Ins_MIRP,+    /*  MIRP[21]  */  Ins_MIRP,+    /*  MIRP[22]  */  Ins_MIRP,+    /*  MIRP[23]  */  Ins_MIRP,+    /*  MIRP[24]  */  Ins_MIRP,+    /*  MIRP[25]  */  Ins_MIRP,+    /*  MIRP[26]  */  Ins_MIRP,+    /*  MIRP[27]  */  Ins_MIRP,+    /*  MIRP[28]  */  Ins_MIRP,+    /*  MIRP[29]  */  Ins_MIRP,+    /*  MIRP[30]  */  Ins_MIRP,+    /*  MIRP[31]  */  Ins_MIRP+  };+++#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */+++  /*************************************************************************/+  /*                                                                       */+  /* RUN                                                                   */+  /*                                                                       */+  /*  This function executes a run of opcodes.  It will exit in the        */+  /*  following cases:                                                     */+  /*                                                                       */+  /*  - Errors (in which case it returns FALSE).                           */+  /*                                                                       */+  /*  - Reaching the end of the main code range (returns TRUE).            */+  /*    Reaching the end of a code range within a function call is an      */+  /*    error.                                                             */+  /*                                                                       */+  /*  - After executing one single opcode, if the flag `Instruction_Trap'  */+  /*    is set to TRUE (returns TRUE).                                     */+  /*                                                                       */+  /*  On exit with TRUE, test IP < CodeSize to know whether it comes from  */+  /*  an instruction trap or a normal termination.                         */+  /*                                                                       */+  /*                                                                       */+  /*  Note: The documented DEBUG opcode pops a value from the stack.  This */+  /*        behaviour is unsupported; here a DEBUG opcode is always an     */+  /*        error.                                                         */+  /*                                                                       */+  /*                                                                       */+  /* THIS IS THE INTERPRETER'S MAIN LOOP.                                  */+  /*                                                                       */+  /*  Instructions appear in the specification's order.                    */+  /*                                                                       */+  /*************************************************************************/+++  /* documentation is in ttinterp.h */++  FT_EXPORT_DEF( FT_Error )+  TT_RunIns( TT_ExecContext  exc )+  {+    FT_Long  ins_counter = 0;  /* executed instructions counter */+++#ifdef TT_CONFIG_OPTION_STATIC_RASTER+    cur = *exc;+#endif++    /* set CVT functions */+    CUR.tt_metrics.ratio = 0;+    if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )+    {+      /* non-square pixels, use the stretched routines */+      CUR.func_read_cvt  = Read_CVT_Stretched;+      CUR.func_write_cvt = Write_CVT_Stretched;+      CUR.func_move_cvt  = Move_CVT_Stretched;+    }+    else+    {+      /* square pixels, use normal routines */+      CUR.func_read_cvt  = Read_CVT;+      CUR.func_write_cvt = Write_CVT;+      CUR.func_move_cvt  = Move_CVT;+    }++    COMPUTE_Funcs();+    COMPUTE_Round( (FT_Byte)exc->GS.round_state );++    do+    {+      CUR.opcode = CUR.code[CUR.IP];++      FT_TRACE7(( "  " ));+      FT_TRACE7(( opcode_name[CUR.opcode] ));+      FT_TRACE7(( "\n" ));++      if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )+      {+        if ( CUR.IP + 1 > CUR.codeSize )+          goto LErrorCodeOverflow_;++        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];+      }++      if ( CUR.IP + CUR.length > CUR.codeSize )+        goto LErrorCodeOverflow_;++      /* First, let's check for empty stack and overflow */+      CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );++      /* `args' is the top of the stack once arguments have been popped. */+      /* One can also interpret it as the index of the last argument.    */+      if ( CUR.args < 0 )+      {+        CUR.error = TT_Err_Too_Few_Arguments;+        goto LErrorLabel_;+      }++      CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );++      /* `new_top' is the new top of the stack, after the instruction's */+      /* execution.  `top' will be set to `new_top' after the `switch'  */+      /* statement.                                                     */+      if ( CUR.new_top > CUR.stackSize )+      {+        CUR.error = TT_Err_Stack_Overflow;+        goto LErrorLabel_;+      }++      CUR.step_ins = TRUE;+      CUR.error    = TT_Err_Ok;++#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH++      {+        FT_Long*  args   = CUR.stack + CUR.args;+        FT_Byte   opcode = CUR.opcode;+++#undef  ARRAY_BOUND_ERROR+#define ARRAY_BOUND_ERROR  goto Set_Invalid_Ref+++        switch ( opcode )+        {+        case 0x00:  /* SVTCA y  */+        case 0x01:  /* SVTCA x  */+        case 0x02:  /* SPvTCA y */+        case 0x03:  /* SPvTCA x */+        case 0x04:  /* SFvTCA y */+        case 0x05:  /* SFvTCA x */+          {+            FT_Short AA, BB;+++            AA = (FT_Short)( ( opcode & 1 ) << 14 );+            BB = (FT_Short)( AA ^ 0x4000 );++            if ( opcode < 4 )+            {+              CUR.GS.projVector.x = AA;+              CUR.GS.projVector.y = BB;++              CUR.GS.dualVector.x = AA;+              CUR.GS.dualVector.y = BB;+            }+            else+            {+              GUESS_VECTOR( projVector );+            }++            if ( ( opcode & 2 ) == 0 )+            {+              CUR.GS.freeVector.x = AA;+              CUR.GS.freeVector.y = BB;+            }+            else+            {+              GUESS_VECTOR( freeVector );+            }++            COMPUTE_Funcs();+          }+          break;++        case 0x06:  /* SPvTL // */+        case 0x07:  /* SPvTL +  */+          DO_SPVTL+          break;++        case 0x08:  /* SFvTL // */+        case 0x09:  /* SFvTL +  */+          DO_SFVTL+          break;++        case 0x0A:  /* SPvFS */+          DO_SPVFS+          break;++        case 0x0B:  /* SFvFS */+          DO_SFVFS+          break;++        case 0x0C:  /* GPV */+          DO_GPV+          break;++        case 0x0D:  /* GFV */+          DO_GFV+          break;++        case 0x0E:  /* SFvTPv */+          DO_SFVTPV+          break;++        case 0x0F:  /* ISECT  */+          Ins_ISECT( EXEC_ARG_ args );+          break;++        case 0x10:  /* SRP0 */+          DO_SRP0+          break;++        case 0x11:  /* SRP1 */+          DO_SRP1+          break;++        case 0x12:  /* SRP2 */+          DO_SRP2+          break;++        case 0x13:  /* SZP0 */+          Ins_SZP0( EXEC_ARG_ args );+          break;++        case 0x14:  /* SZP1 */+          Ins_SZP1( EXEC_ARG_ args );+          break;++        case 0x15:  /* SZP2 */+          Ins_SZP2( EXEC_ARG_ args );+          break;++        case 0x16:  /* SZPS */+          Ins_SZPS( EXEC_ARG_ args );+          break;++        case 0x17:  /* SLOOP */+          DO_SLOOP+          break;++        case 0x18:  /* RTG */+          DO_RTG+          break;++        case 0x19:  /* RTHG */+          DO_RTHG+          break;++        case 0x1A:  /* SMD */+          DO_SMD+          break;++        case 0x1B:  /* ELSE */+          Ins_ELSE( EXEC_ARG_ args );+          break;++        case 0x1C:  /* JMPR */+          DO_JMPR+          break;++        case 0x1D:  /* SCVTCI */+          DO_SCVTCI+          break;++        case 0x1E:  /* SSWCI */+          DO_SSWCI+          break;++        case 0x1F:  /* SSW */+          DO_SSW+          break;++        case 0x20:  /* DUP */+          DO_DUP+          break;++        case 0x21:  /* POP */+          /* nothing :-) */+          break;++        case 0x22:  /* CLEAR */+          DO_CLEAR+          break;++        case 0x23:  /* SWAP */+          DO_SWAP+          break;++        case 0x24:  /* DEPTH */+          DO_DEPTH+          break;++        case 0x25:  /* CINDEX */+          DO_CINDEX+          break;++        case 0x26:  /* MINDEX */+          Ins_MINDEX( EXEC_ARG_ args );+          break;++        case 0x27:  /* ALIGNPTS */+          Ins_ALIGNPTS( EXEC_ARG_ args );+          break;++        case 0x28:  /* ???? */+          Ins_UNKNOWN( EXEC_ARG_ args );+          break;++        case 0x29:  /* UTP */+          Ins_UTP( EXEC_ARG_ args );+          break;++        case 0x2A:  /* LOOPCALL */+          Ins_LOOPCALL( EXEC_ARG_ args );+          break;++        case 0x2B:  /* CALL */+          Ins_CALL( EXEC_ARG_ args );+          break;++        case 0x2C:  /* FDEF */+          Ins_FDEF( EXEC_ARG_ args );+          break;++        case 0x2D:  /* ENDF */+          Ins_ENDF( EXEC_ARG_ args );+          break;++        case 0x2E:  /* MDAP */+        case 0x2F:  /* MDAP */+          Ins_MDAP( EXEC_ARG_ args );+          break;+++        case 0x30:  /* IUP */+        case 0x31:  /* IUP */+          Ins_IUP( EXEC_ARG_ args );+          break;++        case 0x32:  /* SHP */+        case 0x33:  /* SHP */+          Ins_SHP( EXEC_ARG_ args );+          break;++        case 0x34:  /* SHC */+        case 0x35:  /* SHC */+          Ins_SHC( EXEC_ARG_ args );+          break;++        case 0x36:  /* SHZ */+        case 0x37:  /* SHZ */+          Ins_SHZ( EXEC_ARG_ args );+          break;++        case 0x38:  /* SHPIX */+          Ins_SHPIX( EXEC_ARG_ args );+          break;++        case 0x39:  /* IP    */+          Ins_IP( EXEC_ARG_ args );+          break;++        case 0x3A:  /* MSIRP */+        case 0x3B:  /* MSIRP */+          Ins_MSIRP( EXEC_ARG_ args );+          break;++        case 0x3C:  /* AlignRP */+          Ins_ALIGNRP( EXEC_ARG_ args );+          break;++        case 0x3D:  /* RTDG */+          DO_RTDG+          break;++        case 0x3E:  /* MIAP */+        case 0x3F:  /* MIAP */+          Ins_MIAP( EXEC_ARG_ args );+          break;++        case 0x40:  /* NPUSHB */+          Ins_NPUSHB( EXEC_ARG_ args );+          break;++        case 0x41:  /* NPUSHW */+          Ins_NPUSHW( EXEC_ARG_ args );+          break;++        case 0x42:  /* WS */+          DO_WS+          break;++      Set_Invalid_Ref:+            CUR.error = TT_Err_Invalid_Reference;+          break;++        case 0x43:  /* RS */+          DO_RS+          break;++        case 0x44:  /* WCVTP */+          DO_WCVTP+          break;++        case 0x45:  /* RCVT */+          DO_RCVT+          break;++        case 0x46:  /* GC */+        case 0x47:  /* GC */+          Ins_GC( EXEC_ARG_ args );+          break;++        case 0x48:  /* SCFS */+          Ins_SCFS( EXEC_ARG_ args );+          break;++        case 0x49:  /* MD */+        case 0x4A:  /* MD */+          Ins_MD( EXEC_ARG_ args );+          break;++        case 0x4B:  /* MPPEM */+          DO_MPPEM+          break;++        case 0x4C:  /* MPS */+          DO_MPS+          break;++        case 0x4D:  /* FLIPON */+          DO_FLIPON+          break;++        case 0x4E:  /* FLIPOFF */+          DO_FLIPOFF+          break;++        case 0x4F:  /* DEBUG */+          DO_DEBUG+          break;++        case 0x50:  /* LT */+          DO_LT+          break;++        case 0x51:  /* LTEQ */+          DO_LTEQ+          break;++        case 0x52:  /* GT */+          DO_GT+          break;++        case 0x53:  /* GTEQ */+          DO_GTEQ+          break;++        case 0x54:  /* EQ */+          DO_EQ+          break;++        case 0x55:  /* NEQ */+          DO_NEQ+          break;++        case 0x56:  /* ODD */+          DO_ODD+          break;++        case 0x57:  /* EVEN */+          DO_EVEN+          break;++        case 0x58:  /* IF */+          Ins_IF( EXEC_ARG_ args );+          break;++        case 0x59:  /* EIF */+          /* do nothing */+          break;++        case 0x5A:  /* AND */+          DO_AND+          break;++        case 0x5B:  /* OR */+          DO_OR+          break;++        case 0x5C:  /* NOT */+          DO_NOT+          break;++        case 0x5D:  /* DELTAP1 */+          Ins_DELTAP( EXEC_ARG_ args );+          break;++        case 0x5E:  /* SDB */+          DO_SDB+          break;++        case 0x5F:  /* SDS */+          DO_SDS+          break;++        case 0x60:  /* ADD */+          DO_ADD+          break;++        case 0x61:  /* SUB */+          DO_SUB+          break;++        case 0x62:  /* DIV */+          DO_DIV+          break;++        case 0x63:  /* MUL */+          DO_MUL+          break;++        case 0x64:  /* ABS */+          DO_ABS+          break;++        case 0x65:  /* NEG */+          DO_NEG+          break;++        case 0x66:  /* FLOOR */+          DO_FLOOR+          break;++        case 0x67:  /* CEILING */+          DO_CEILING+          break;++        case 0x68:  /* ROUND */+        case 0x69:  /* ROUND */+        case 0x6A:  /* ROUND */+        case 0x6B:  /* ROUND */+          DO_ROUND+          break;++        case 0x6C:  /* NROUND */+        case 0x6D:  /* NROUND */+        case 0x6E:  /* NRRUND */+        case 0x6F:  /* NROUND */+          DO_NROUND+          break;++        case 0x70:  /* WCVTF */+          DO_WCVTF+          break;++        case 0x71:  /* DELTAP2 */+        case 0x72:  /* DELTAP3 */+          Ins_DELTAP( EXEC_ARG_ args );+          break;++        case 0x73:  /* DELTAC0 */+        case 0x74:  /* DELTAC1 */+        case 0x75:  /* DELTAC2 */+          Ins_DELTAC( EXEC_ARG_ args );+          break;++        case 0x76:  /* SROUND */+          DO_SROUND+          break;++        case 0x77:  /* S45Round */+          DO_S45ROUND+          break;++        case 0x78:  /* JROT */+          DO_JROT+          break;++        case 0x79:  /* JROF */+          DO_JROF+          break;++        case 0x7A:  /* ROFF */+          DO_ROFF+          break;++        case 0x7B:  /* ???? */+          Ins_UNKNOWN( EXEC_ARG_ args );+          break;++        case 0x7C:  /* RUTG */+          DO_RUTG+          break;++        case 0x7D:  /* RDTG */+          DO_RDTG+          break;++        case 0x7E:  /* SANGW */+        case 0x7F:  /* AA    */+          /* nothing - obsolete */+          break;++        case 0x80:  /* FLIPPT */+          Ins_FLIPPT( EXEC_ARG_ args );+          break;++        case 0x81:  /* FLIPRGON */+          Ins_FLIPRGON( EXEC_ARG_ args );+          break;++        case 0x82:  /* FLIPRGOFF */+          Ins_FLIPRGOFF( EXEC_ARG_ args );+          break;++        case 0x83:  /* UNKNOWN */+        case 0x84:  /* UNKNOWN */+          Ins_UNKNOWN( EXEC_ARG_ args );+          break;++        case 0x85:  /* SCANCTRL */+          Ins_SCANCTRL( EXEC_ARG_ args );+          break;++        case 0x86:  /* SDPVTL */+        case 0x87:  /* SDPVTL */+          Ins_SDPVTL( EXEC_ARG_ args );+          break;++        case 0x88:  /* GETINFO */+          Ins_GETINFO( EXEC_ARG_ args );+          break;++        case 0x89:  /* IDEF */+          Ins_IDEF( EXEC_ARG_ args );+          break;++        case 0x8A:  /* ROLL */+          Ins_ROLL( EXEC_ARG_ args );+          break;++        case 0x8B:  /* MAX */+          DO_MAX+          break;++        case 0x8C:  /* MIN */+          DO_MIN+          break;++        case 0x8D:  /* SCANTYPE */+          Ins_SCANTYPE( EXEC_ARG_ args );+          break;++        case 0x8E:  /* INSTCTRL */+          Ins_INSTCTRL( EXEC_ARG_ args );+          break;++        case 0x8F:+          Ins_UNKNOWN( EXEC_ARG_ args );+          break;++        default:+          if ( opcode >= 0xE0 )+            Ins_MIRP( EXEC_ARG_ args );+          else if ( opcode >= 0xC0 )+            Ins_MDRP( EXEC_ARG_ args );+          else if ( opcode >= 0xB8 )+            Ins_PUSHW( EXEC_ARG_ args );+          else if ( opcode >= 0xB0 )+            Ins_PUSHB( EXEC_ARG_ args );+          else+            Ins_UNKNOWN( EXEC_ARG_ args );+        }++      }++#else++      Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );++#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */++      if ( CUR.error != TT_Err_Ok )+      {+        switch ( CUR.error )+        {+        case TT_Err_Invalid_Opcode: /* looking for redefined instructions */+          {+            TT_DefRecord*  def   = CUR.IDefs;+            TT_DefRecord*  limit = def + CUR.numIDefs;+++            for ( ; def < limit; def++ )+            {+              if ( def->active && CUR.opcode == (FT_Byte)def->opc )+              {+                TT_CallRec*  callrec;+++                if ( CUR.callTop >= CUR.callSize )+                {+                  CUR.error = TT_Err_Invalid_Reference;+                  goto LErrorLabel_;+                }++                callrec = &CUR.callStack[CUR.callTop];++                callrec->Caller_Range = CUR.curRange;+                callrec->Caller_IP    = CUR.IP + 1;+                callrec->Cur_Count    = 1;+                callrec->Cur_Restart  = def->start;++                if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )+                  goto LErrorLabel_;++                goto LSuiteLabel_;+              }+            }+          }++          CUR.error = TT_Err_Invalid_Opcode;+          goto LErrorLabel_;++#if 0+          break;   /* Unreachable code warning suppression.             */+                   /* Leave to remind in case a later change the editor */+                   /* to consider break;                                */+#endif++        default:+          goto LErrorLabel_;++#if 0+        break;+#endif+        }+      }++      CUR.top = CUR.new_top;++      if ( CUR.step_ins )+        CUR.IP += CUR.length;++      /* increment instruction counter and check if we didn't */+      /* run this program for too long (e.g. infinite loops). */+      if ( ++ins_counter > MAX_RUNNABLE_OPCODES )+        return TT_Err_Execution_Too_Long;++    LSuiteLabel_:+      if ( CUR.IP >= CUR.codeSize )+      {+        if ( CUR.callTop > 0 )+        {+          CUR.error = TT_Err_Code_Overflow;+          goto LErrorLabel_;+        }+        else+          goto LNo_Error_;+      }+    } while ( !CUR.instruction_trap );++  LNo_Error_:++#ifdef TT_CONFIG_OPTION_STATIC_RASTER+    *exc = cur;+#endif++    return TT_Err_Ok;++  LErrorCodeOverflow_:+    CUR.error = TT_Err_Code_Overflow;++  LErrorLabel_:++#ifdef TT_CONFIG_OPTION_STATIC_RASTER+    *exc = cur;+#endif++    /* If any errors have occurred, function tables may be broken. */+    /* Force a re-execution of `prep' and `fpgm' tables if no      */+    /* bytecode debugger is run.                                   */+    if ( CUR.error && !CUR.instruction_trap )+    {+      FT_TRACE1(( "  The interpreter returned error 0x%x\n", CUR.error ));+      exc->size->cvt_ready      = FALSE;  +    }++    return CUR.error;+  }+++#endif /* TT_USE_BYTECODE_INTERPRETER */+++/* END */
+ src/truetype/ttinterp.h view
@@ -0,0 +1,319 @@+/***************************************************************************/+/*                                                                         */+/*  ttinterp.h                                                             */+/*                                                                         */+/*    TrueType bytecode interpreter (specification).                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010 by       */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTINTERP_H__+#define __TTINTERP_H__++#include <ft2build.h>+#include "ttobjs.h"+++FT_BEGIN_HEADER+++#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */++#define EXEC_OP_   TT_ExecContext  exc,+#define EXEC_OP    TT_ExecContext  exc+#define EXEC_ARG_  exc,+#define EXEC_ARG   exc++#else                                       /* static implementation */++#define EXEC_OP_   /* void */+#define EXEC_OP    /* void */+#define EXEC_ARG_  /* void */+#define EXEC_ARG   /* void */++#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */+++  /*************************************************************************/+  /*                                                                       */+  /* Rounding mode constants.                                              */+  /*                                                                       */+#define TT_Round_Off             5+#define TT_Round_To_Half_Grid    0+#define TT_Round_To_Grid         1+#define TT_Round_To_Double_Grid  2+#define TT_Round_Up_To_Grid      4+#define TT_Round_Down_To_Grid    3+#define TT_Round_Super           6+#define TT_Round_Super_45        7+++  /*************************************************************************/+  /*                                                                       */+  /* Function types used by the interpreter, depending on various modes    */+  /* (e.g. the rounding mode, whether to render a vertical or horizontal   */+  /* line etc).                                                            */+  /*                                                                       */+  /*************************************************************************/++  /* Rounding function */+  typedef FT_F26Dot6+  (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6  distance,+                             FT_F26Dot6  compensation );++  /* Point displacement along the freedom vector routine */+  typedef void+  (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone  zone,+                            FT_UShort     point,+                            FT_F26Dot6    distance );++  /* Distance projection along one of the projection vectors */+  typedef FT_F26Dot6+  (*TT_Project_Func)( EXEC_OP_ FT_Pos   dx,+                               FT_Pos   dy );++  /* reading a cvt value.  Take care of non-square pixels if necessary */+  typedef FT_F26Dot6+  (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong  idx );++  /* setting or moving a cvt value.  Take care of non-square pixels  */+  /* if necessary                                                    */+  typedef void+  (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong    idx,+                               FT_F26Dot6  value );+++  /*************************************************************************/+  /*                                                                       */+  /* This structure defines a call record, used to manage function calls.  */+  /*                                                                       */+  typedef struct  TT_CallRec_+  {+    FT_Int   Caller_Range;+    FT_Long  Caller_IP;+    FT_Long  Cur_Count;+    FT_Long  Cur_Restart;++  } TT_CallRec, *TT_CallStack;+++  /*************************************************************************/+  /*                                                                       */+  /* The main structure for the interpreter which collects all necessary   */+  /* variables and states.                                                 */+  /*                                                                       */+  typedef struct  TT_ExecContextRec_+  {+    TT_Face            face;+    TT_Size            size;+    FT_Memory          memory;++    /* instructions state */++    FT_Error           error;      /* last execution error */++    FT_Long            top;        /* top of exec. stack   */++    FT_UInt            stackSize;  /* size of exec. stack  */+    FT_Long*           stack;      /* current exec. stack  */++    FT_Long            args;+    FT_UInt            new_top;    /* new top after exec.  */++    TT_GlyphZoneRec    zp0,        /* zone records */+                       zp1,+                       zp2,+                       pts,+                       twilight;++    FT_Size_Metrics    metrics;+    TT_Size_Metrics    tt_metrics; /* size metrics */++    TT_GraphicsState   GS;         /* current graphics state */++    FT_Int             curRange;  /* current code range number   */+    FT_Byte*           code;      /* current code range          */+    FT_Long            IP;        /* current instruction pointer */+    FT_Long            codeSize;  /* size of current range       */++    FT_Byte            opcode;    /* current opcode              */+    FT_Int             length;    /* length of current opcode    */++    FT_Bool            step_ins;  /* true if the interpreter must */+                                  /* increment IP after ins. exec */+    FT_ULong           cvtSize;+    FT_Long*           cvt;++    FT_UInt            glyphSize; /* glyph instructions buffer size */+    FT_Byte*           glyphIns;  /* glyph instructions buffer */++    FT_UInt            numFDefs;  /* number of function defs         */+    FT_UInt            maxFDefs;  /* maximum number of function defs */+    TT_DefArray        FDefs;     /* table of FDefs entries          */++    FT_UInt            numIDefs;  /* number of instruction defs */+    FT_UInt            maxIDefs;  /* maximum number of ins defs */+    TT_DefArray        IDefs;     /* table of IDefs entries     */++    FT_UInt            maxFunc;   /* maximum function index     */+    FT_UInt            maxIns;    /* maximum instruction index  */++    FT_Int             callTop,    /* top of call stack during execution */+                       callSize;   /* size of call stack */+    TT_CallStack       callStack;  /* call stack */++    FT_UShort          maxPoints;    /* capacity of this context's `pts' */+    FT_Short           maxContours;  /* record, expressed in points and  */+                                     /* contours.                        */++    TT_CodeRangeTable  codeRangeTable;  /* table of valid code ranges */+                                        /* useful for the debugger   */++    FT_UShort          storeSize;  /* size of current storage */+    FT_Long*           storage;    /* storage area            */++    FT_F26Dot6         period;     /* values used for the */+    FT_F26Dot6         phase;      /* `SuperRounding'     */+    FT_F26Dot6         threshold;++#if 0+    /* this seems to be unused */+    FT_Int             cur_ppem;   /* ppem along the current proj vector */+#endif++    FT_Bool            instruction_trap; /* If `True', the interpreter will */+                                         /* exit after each instruction     */++    TT_GraphicsState   default_GS;       /* graphics state resulting from   */+                                         /* the prep program                */+    FT_Bool            is_composite;     /* true if the glyph is composite  */+    FT_Bool            pedantic_hinting; /* true if pedantic interpretation */++    /* latest interpreter additions */++    FT_Long            F_dot_P;    /* dot product of freedom and projection */+                                   /* vectors                               */+    TT_Round_Func      func_round; /* current rounding function             */++    TT_Project_Func    func_project,   /* current projection function */+                       func_dualproj,  /* current dual proj. function */+                       func_freeProj;  /* current freedom proj. func  */++    TT_Move_Func       func_move;      /* current point move function */+    TT_Move_Func       func_move_orig; /* move original position function */++    TT_Get_CVT_Func    func_read_cvt;  /* read a cvt entry              */+    TT_Set_CVT_Func    func_write_cvt; /* write a cvt entry (in pixels) */+    TT_Set_CVT_Func    func_move_cvt;  /* incr a cvt entry (in pixels)  */++    FT_Bool            grayscale;      /* are we hinting for grayscale? */++  } TT_ExecContextRec;+++  extern const TT_GraphicsState  tt_default_graphics_state;+++  FT_LOCAL( FT_Error )+  TT_Goto_CodeRange( TT_ExecContext  exec,+                     FT_Int          range,+                     FT_Long         IP );++  FT_LOCAL( FT_Error )+  TT_Set_CodeRange( TT_ExecContext  exec,+                    FT_Int          range,+                    void*           base,+                    FT_Long         length );++  FT_LOCAL( FT_Error )+  TT_Clear_CodeRange( TT_ExecContext  exec,+                      FT_Int          range );+++  FT_LOCAL( FT_Error )+  Update_Max( FT_Memory  memory,+              FT_ULong*  size,+              FT_Long    multiplier,+              void*      _pbuff,+              FT_ULong   new_max );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_New_Context                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Queries the face context for a given font.  Note that there is     */+  /*    now a _single_ execution context in the TrueType driver which is   */+  /*    shared among faces.                                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A handle to the source face object.                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    A handle to the execution context.  Initialized for `face'.        */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the glyph loader and debugger should call this function.      */+  /*                                                                       */+  FT_EXPORT( TT_ExecContext )+  TT_New_Context( TT_Driver  driver );++  FT_LOCAL( FT_Error )+  TT_Done_Context( TT_ExecContext  exec );++  FT_LOCAL( FT_Error )+  TT_Load_Context( TT_ExecContext  exec,+                   TT_Face         face,+                   TT_Size         size );++  FT_LOCAL( FT_Error )+  TT_Save_Context( TT_ExecContext  exec,+                   TT_Size         ins );++  FT_LOCAL( FT_Error )+  TT_Run_Context( TT_ExecContext  exec,+                  FT_Bool         debug );+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    TT_RunIns                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Executes one or more instruction in the execution context.  This   */+  /*    is the main function of the TrueType opcode interpreter.           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    exec :: A handle to the target execution context.                  */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only the object manager and debugger should call this function.    */+  /*                                                                       */+  /*    This function is publicly exported because it is directly          */+  /*    invoked by the TrueType debugger.                                  */+  /*                                                                       */+  FT_EXPORT( FT_Error )+  TT_RunIns( TT_ExecContext  exec );+++FT_END_HEADER++#endif /* __TTINTERP_H__ */+++/* END */
+ src/truetype/ttobjs.c view
@@ -0,0 +1,1135 @@+/***************************************************************************/+/*                                                                         */+/*  ttobjs.c                                                               */+/*                                                                         */+/*    Objects manager (body).                                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H+#include FT_INTERNAL_SFNT_H++#include "ttgload.h"+#include "ttpload.h"++#include "tterrors.h"++#ifdef TT_USE_BYTECODE_INTERPRETER+#include "ttinterp.h"+#endif++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+#include FT_TRUETYPE_UNPATENTED_H+#endif++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include "ttgxvar.h"+#endif++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttobjs+++#ifdef TT_USE_BYTECODE_INTERPRETER++  /*************************************************************************/+  /*                                                                       */+  /*                       GLYPH ZONE FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_glyphzone_done                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Deallocate a glyph zone.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    zone :: A pointer to the target glyph zone.                        */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_glyphzone_done( TT_GlyphZone  zone )+  {+    FT_Memory  memory = zone->memory;+++    if ( memory )+    {+      FT_FREE( zone->contours );+      FT_FREE( zone->tags );+      FT_FREE( zone->cur );+      FT_FREE( zone->org );+      FT_FREE( zone->orus );++      zone->max_points   = zone->n_points   = 0;+      zone->max_contours = zone->n_contours = 0;+      zone->memory       = NULL;+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_glyphzone_new                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Allocate a new glyph zone.                                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    memory      :: A handle to the current memory object.              */+  /*                                                                       */+  /*    maxPoints   :: The capacity of glyph zone in points.               */+  /*                                                                       */+  /*    maxContours :: The capacity of glyph zone in contours.             */+  /*                                                                       */+  /* <Output>                                                              */+  /*    zone        :: A pointer to the target glyph zone record.          */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_glyphzone_new( FT_Memory     memory,+                    FT_UShort     maxPoints,+                    FT_Short      maxContours,+                    TT_GlyphZone  zone )+  {+    FT_Error  error;+++    FT_MEM_ZERO( zone, sizeof ( *zone ) );+    zone->memory = memory;++    if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||+         FT_NEW_ARRAY( zone->cur,      maxPoints   ) ||+         FT_NEW_ARRAY( zone->orus,     maxPoints   ) ||+         FT_NEW_ARRAY( zone->tags,     maxPoints   ) ||+         FT_NEW_ARRAY( zone->contours, maxContours ) )+    {+      tt_glyphzone_done( zone );+    }+    else+    {+      zone->max_points   = maxPoints;+      zone->max_contours = maxContours;+    }++    return error;+  }+#endif /* TT_USE_BYTECODE_INTERPRETER */+++  /* Compare the face with a list of well-known `tricky' fonts. */+  /* This list shall be expanded as we find more of them.       */++  static FT_Bool+  tt_check_trickyness_family( FT_String*  name )+  {++#define TRICK_NAMES_MAX_CHARACTERS  16+#define TRICK_NAMES_COUNT            8++    static const char trick_names[TRICK_NAMES_COUNT]+                                 [TRICK_NAMES_MAX_CHARACTERS + 1] =+    {+      "DFKaiSho-SB",     /* dfkaisb.ttf */+      "DFKaiShu",+      "DFKai-SB",        /* kaiu.ttf */+      "HuaTianKaiTi?",   /* htkt2.ttf */+      "HuaTianSongTi?",  /* htst3.ttf */+      "MingLiU",         /* mingliu.ttf & mingliu.ttc */+      "PMingLiU",        /* mingliu.ttc */+      "MingLi43",        /* mingli.ttf */+    };++    int  nn;+++    for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )+      if ( ft_strstr( name, trick_names[nn] ) )+        return TRUE;++    return FALSE;+  }+++  /* XXX: This function should be in the `sfnt' module. */++  /* Some PDF generators clear the checksums in the TrueType header table. */+  /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF     */+  /* Printer clears the entries for subsetted subtables.  We thus have to  */+  /* recalculate the checksums  where necessary.                           */++  static FT_UInt32+  tt_synth_sfnt_checksum( FT_Stream  stream,+                          FT_ULong   length )+  {+    FT_Error   error;+    FT_UInt32  checksum = 0;+    int        i;+++    if ( FT_FRAME_ENTER( length ) )+      return 0;++    for ( ; length > 3; length -= 4 )+      checksum += (FT_UInt32)FT_GET_ULONG();++    for ( i = 3; length > 0; length --, i-- )+      checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) );++    FT_FRAME_EXIT();++    return checksum;+  }+++  /* XXX: This function should be in the `sfnt' module. */++  static FT_ULong+  tt_get_sfnt_checksum( TT_Face    face,+                        FT_UShort  i )+  {+    if ( face->dir_tables[i].CheckSum )+      return face->dir_tables[i].CheckSum;++    else if ( !face->goto_table )+      return 0;++    else if ( !face->goto_table( face,+                                 face->dir_tables[i].Tag,+                                 face->root.stream,+                                 NULL ) )+      return 0;++    return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,+                                             face->dir_tables[i].Length );+  }+++  typedef struct tt_sfnt_id_rec_+  {+    FT_ULong  CheckSum;+    FT_ULong  Length;++  } tt_sfnt_id_rec;+++  static FT_Bool+  tt_check_trickyness_sfnt_ids( TT_Face  face )+  {+#define TRICK_SFNT_IDS_PER_FACE   3+#define TRICK_SFNT_IDS_NUM_FACES  5++    static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]+                                       [TRICK_SFNT_IDS_PER_FACE] = {++#define TRICK_SFNT_ID_cvt   0+#define TRICK_SFNT_ID_fpgm  1+#define TRICK_SFNT_ID_prep  2++      { /* MingLiU 1995 */+        { 0x05bcf058, 0x000002e4 }, /* cvt  */+        { 0x28233bf1, 0x000087c4 }, /* fpgm */+        { 0xa344a1ea, 0x000001e1 }  /* prep */+      },+      { /* MingLiU 1996- */+        { 0x05bcf058, 0x000002e4 }, /* cvt  */+        { 0x28233bf1, 0x000087c4 }, /* fpgm */+        { 0xa344a1eb, 0x000001e1 }  /* prep */+      },+      { /* DFKaiShu */+        { 0x11e5ead4, 0x00000350 }, /* cvt  */+        { 0x5a30ca3b, 0x00009063 }, /* fpgm */+        { 0x13a42602, 0x0000007e }  /* prep */+      },+      { /* HuaTianKaiTi */+        { 0xfffbfffc, 0x00000008 }, /* cvt  */+        { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */+        { 0x70020112, 0x00000008 }  /* prep */+      },+      { /* HuaTianSongTi */+        { 0xfffbfffc, 0x00000008 }, /* cvt  */+        { 0x0a5a0483, 0x00017c39 }, /* fpgm */+        { 0x70020112, 0x00000008 }  /* prep */+      }+    };++    FT_ULong  checksum;+    int       num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];+    int       i, j, k;+++    FT_MEM_SET( num_matched_ids, 0,+                sizeof( int ) * TRICK_SFNT_IDS_NUM_FACES );++    for ( i = 0; i < face->num_tables; i++ )+    {+      checksum = 0;++      switch( face->dir_tables[i].Tag )+      {+      case TTAG_cvt:+        k = TRICK_SFNT_ID_cvt;+        break;++      case TTAG_fpgm:+        k = TRICK_SFNT_ID_fpgm;+        break;++      case TTAG_prep:+        k = TRICK_SFNT_ID_prep;+        break;++      default:+        continue;+      }++      for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )+        if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )+        {+          if ( !checksum )+            checksum = tt_get_sfnt_checksum( face, i );++          if ( sfnt_id[j][k].CheckSum == checksum )+            num_matched_ids[j]++;++          if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )+            return TRUE;+        }+    }++    return FALSE;+  }+++  static FT_Bool+  tt_check_trickyness( FT_Face  face )+  {+    if ( !face )+      return FALSE;++    /* First, check the face name. */+    if ( face->family_name )+    {+      if ( tt_check_trickyness_family( face->family_name ) )+        return TRUE;+      else+        return FALSE;+    }++    /* Type42 fonts may lack `name' tables, we thus try to identify */+    /* tricky fonts by checking the checksums of Type42-persistent  */+    /* sfnt tables (`cvt', `fpgm', and `prep').                     */+    if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )+      return TRUE;++    return FALSE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_init                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a given TrueType face object.                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream     :: The source font stream.                              */+  /*                                                                       */+  /*    face_index :: The index of the font face in the resource.          */+  /*                                                                       */+  /*    num_params :: Number of additional generic parameters.  Ignored.   */+  /*                                                                       */+  /*    params     :: Additional generic parameters.  Ignored.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The newly built face object.                         */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_init( FT_Stream      stream,+                FT_Face        ttface,      /* TT_Face */+                FT_Int         face_index,+                FT_Int         num_params,+                FT_Parameter*  params )+  {+    FT_Error      error;+    FT_Library    library;+    SFNT_Service  sfnt;+    TT_Face       face = (TT_Face)ttface;+++    library = ttface->driver->root.library;+    sfnt    = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );+    if ( !sfnt )+      goto Bad_Format;++    /* create input stream from resource */+    if ( FT_STREAM_SEEK( 0 ) )+      goto Exit;++    /* check that we have a valid TrueType file */+    error = sfnt->init_face( stream, face, face_index, num_params, params );+    if ( error )+      goto Exit;++    /* We must also be able to accept Mac/GX fonts, as well as OT ones. */+    /* The 0x00020000 tag is completely undocumented; some fonts from   */+    /* Arphic made for Chinese Windows 3.1 have this.                   */+    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */+         face->format_tag != 0x00020000L &&    /* CJK fonts for Win 3.1 */+         face->format_tag != TTAG_true   )     /* Mac fonts */+    {+      FT_TRACE2(( "[not a valid TTF font]\n" ));+      goto Bad_Format;+    }++#ifdef TT_USE_BYTECODE_INTERPRETER+    ttface->face_flags |= FT_FACE_FLAG_HINTER;+#endif++    /* If we are performing a simple font format check, exit immediately. */+    if ( face_index < 0 )+      return TT_Err_Ok;++    /* Load font directory */+    error = sfnt->load_face( stream, face, face_index, num_params, params );+    if ( error )+      goto Exit;++    if ( tt_check_trickyness( ttface ) )+      ttface->face_flags |= FT_FACE_FLAG_TRICKY;++    error = tt_face_load_hdmx( face, stream );+    if ( error )+      goto Exit;++    if ( FT_IS_SCALABLE( ttface ) )+    {++#ifdef FT_CONFIG_OPTION_INCREMENTAL++      if ( !ttface->internal->incremental_interface )+        error = tt_face_load_loca( face, stream );+      if ( !error )+        error = tt_face_load_cvt( face, stream );+      if ( !error )+        error = tt_face_load_fpgm( face, stream );+      if ( !error )+        error = tt_face_load_prep( face, stream );++#else++      if ( !error )+        error = tt_face_load_loca( face, stream );+      if ( !error )+        error = tt_face_load_cvt( face, stream );+      if ( !error )+        error = tt_face_load_fpgm( face, stream );+      if ( !error )+        error = tt_face_load_prep( face, stream );++#endif++    }++#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING    ) && \+    !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )++    {+      FT_Bool  unpatented_hinting;+      int      i;+++      /* Determine whether unpatented hinting is to be used for this face. */+      unpatented_hinting = FT_BOOL+        ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );++      for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )+        if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )+          unpatented_hinting = TRUE;++      if ( !unpatented_hinting )+        ttface->internal->ignore_unpatented_hinter = TRUE;+    }++#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&+          !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */++    /* initialize standard glyph loading routines */+    TT_Init_Glyph_Loading( face );++  Exit:+    return error;++  Bad_Format:+    error = TT_Err_Unknown_File_Format;+    goto Exit;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_done                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalize a given face object.                                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A pointer to the face object to destroy.                   */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_face_done( FT_Face  ttface )           /* TT_Face */+  {+    TT_Face       face = (TT_Face)ttface;+    FT_Memory     memory;+    FT_Stream     stream;+    SFNT_Service  sfnt;+++    if ( !face )+      return;++    memory = ttface->memory;+    stream = ttface->stream;+    sfnt   = (SFNT_Service)face->sfnt;++    /* for `extended TrueType formats' (i.e. compressed versions) */+    if ( face->extra.finalizer )+      face->extra.finalizer( face->extra.data );++    if ( sfnt )+      sfnt->done_face( face );++    /* freeing the locations table */+    tt_face_done_loca( face );++    tt_face_free_hdmx( face );++    /* freeing the CVT */+    FT_FREE( face->cvt );+    face->cvt_size = 0;++    /* freeing the programs */+    FT_FRAME_RELEASE( face->font_program );+    FT_FRAME_RELEASE( face->cvt_program );+    face->font_program_size = 0;+    face->cvt_program_size  = 0;++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    tt_done_blend( memory, face->blend );+    face->blend = NULL;+#endif+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                           SIZE  FUNCTIONS                             */+  /*                                                                       */+  /*************************************************************************/++#ifdef TT_USE_BYTECODE_INTERPRETER++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_size_run_fpgm                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Run the font program.                                              */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to the size object.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_size_run_fpgm( TT_Size  size )+  {+    TT_Face         face = (TT_Face)size->root.face;+    TT_ExecContext  exec;+    FT_Error        error;+++    /* debugging instances have their own context */+    if ( size->debug )+      exec = size->context;+    else+      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;++    if ( !exec )+      return TT_Err_Could_Not_Find_Context;++    TT_Load_Context( exec, face, size );++    exec->callTop   = 0;+    exec->top       = 0;++    exec->period    = 64;+    exec->phase     = 0;+    exec->threshold = 0;++    exec->instruction_trap = FALSE;+    exec->F_dot_P = 0x10000L;++    {+      FT_Size_Metrics*  metrics    = &exec->metrics;+      TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;+++      metrics->x_ppem   = 0;+      metrics->y_ppem   = 0;+      metrics->x_scale  = 0;+      metrics->y_scale  = 0;++      tt_metrics->ppem  = 0;+      tt_metrics->scale = 0;+      tt_metrics->ratio = 0x10000L;+    }++    /* allow font program execution */+    TT_Set_CodeRange( exec,+                      tt_coderange_font,+                      face->font_program,+                      face->font_program_size );++    /* disable CVT and glyph programs coderange */+    TT_Clear_CodeRange( exec, tt_coderange_cvt );+    TT_Clear_CodeRange( exec, tt_coderange_glyph );++    if ( face->font_program_size > 0 )+    {+      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );++      if ( !error )+      {+        FT_TRACE4(( "Executing `fpgm' table.\n" ));++        error = face->interpreter( exec );+      }+    }+    else+      error = TT_Err_Ok;++    if ( !error )+      TT_Save_Context( exec, size );++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_size_run_prep                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Run the control value program.                                     */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to the size object.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_size_run_prep( TT_Size  size )+  {+    TT_Face         face = (TT_Face)size->root.face;+    TT_ExecContext  exec;+    FT_Error        error;+++    /* debugging instances have their own context */+    if ( size->debug )+      exec = size->context;+    else+      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;++    if ( !exec )+      return TT_Err_Could_Not_Find_Context;++    TT_Load_Context( exec, face, size );++    exec->callTop = 0;+    exec->top     = 0;++    exec->instruction_trap = FALSE;++    TT_Set_CodeRange( exec,+                      tt_coderange_cvt,+                      face->cvt_program,+                      face->cvt_program_size );++    TT_Clear_CodeRange( exec, tt_coderange_glyph );++    if ( face->cvt_program_size > 0 )+    {+      error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );++      if ( !error && !size->debug )+      {+        FT_TRACE4(( "Executing `prep' table.\n" ));++        error = face->interpreter( exec );+      }+    }+    else+      error = TT_Err_Ok;++    /* save as default graphics state */+    size->GS = exec->GS;++    TT_Save_Context( exec, size );++    return error;+  }++#endif /* TT_USE_BYTECODE_INTERPRETER */+++#ifdef TT_USE_BYTECODE_INTERPRETER++  static void+  tt_size_done_bytecode( FT_Size  ftsize )+  {+    TT_Size    size   = (TT_Size)ftsize;+    TT_Face    face   = (TT_Face)ftsize->face;+    FT_Memory  memory = face->root.memory;+++    if ( size->debug )+    {+      /* the debug context must be deleted by the debugger itself */+      size->context = NULL;+      size->debug   = FALSE;+    }++    FT_FREE( size->cvt );+    size->cvt_size = 0;++    /* free storage area */+    FT_FREE( size->storage );+    size->storage_size = 0;++    /* twilight zone */+    tt_glyphzone_done( &size->twilight );++    FT_FREE( size->function_defs );+    FT_FREE( size->instruction_defs );++    size->num_function_defs    = 0;+    size->max_function_defs    = 0;+    size->num_instruction_defs = 0;+    size->max_instruction_defs = 0;++    size->max_func = 0;+    size->max_ins  = 0;++    size->bytecode_ready = 0;+    size->cvt_ready      = 0;+  }+++  /* Initialize bytecode-related fields in the size object.       */+  /* We do this only if bytecode interpretation is really needed. */+  static FT_Error+  tt_size_init_bytecode( FT_Size  ftsize )+  {+    FT_Error   error;+    TT_Size    size = (TT_Size)ftsize;+    TT_Face    face = (TT_Face)ftsize->face;+    FT_Memory  memory = face->root.memory;+    FT_Int     i;++    FT_UShort       n_twilight;+    TT_MaxProfile*  maxp = &face->max_profile;+++    size->bytecode_ready = 1;+    size->cvt_ready      = 0;++    size->max_function_defs    = maxp->maxFunctionDefs;+    size->max_instruction_defs = maxp->maxInstructionDefs;++    size->num_function_defs    = 0;+    size->num_instruction_defs = 0;++    size->max_func = 0;+    size->max_ins  = 0;++    size->cvt_size     = face->cvt_size;+    size->storage_size = maxp->maxStorage;++    /* Set default metrics */+    {+      TT_Size_Metrics*  metrics = &size->ttmetrics;+++      metrics->rotated   = FALSE;+      metrics->stretched = FALSE;++      /* set default compensation (all 0) */+      for ( i = 0; i < 4; i++ )+        metrics->compensations[i] = 0;+    }++    /* allocate function defs, instruction defs, cvt, and storage area */+    if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||+         FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||+         FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||+         FT_NEW_ARRAY( size->storage,          size->storage_size         ) )+      goto Exit;++    /* reserve twilight zone */+    n_twilight = maxp->maxTwilightPoints;++    /* there are 4 phantom points (do we need this?) */+    n_twilight += 4;++    error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );+    if ( error )+      goto Exit;++    size->twilight.n_points = n_twilight;++    size->GS = tt_default_graphics_state;++    /* set `face->interpreter' according to the debug hook present */+    {+      FT_Library  library = face->root.driver->root.library;+++      face->interpreter = (TT_Interpreter)+                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];+      if ( !face->interpreter )+        face->interpreter = (TT_Interpreter)TT_RunIns;+    }++    /* Fine, now run the font program! */+    error = tt_size_run_fpgm( size );++  Exit:+    if ( error )+      tt_size_done_bytecode( ftsize );++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  tt_size_ready_bytecode( TT_Size  size )+  {+    FT_Error  error = TT_Err_Ok;+++    if ( !size->bytecode_ready )+    {+      error = tt_size_init_bytecode( (FT_Size)size );+      if ( error )+        goto Exit;+    }++    /* rescale CVT when needed */+    if ( !size->cvt_ready )+    {+      FT_UInt  i;+      TT_Face  face = (TT_Face)size->root.face;+++      /* Scale the cvt values to the new ppem.          */+      /* We use by default the y ppem to scale the CVT. */+      for ( i = 0; i < size->cvt_size; i++ )+        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );++      /* all twilight points are originally zero */+      for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )+      {+        size->twilight.org[i].x = 0;+        size->twilight.org[i].y = 0;+        size->twilight.cur[i].x = 0;+        size->twilight.cur[i].y = 0;+      }++      /* clear storage area */+      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )+        size->storage[i] = 0;++      size->GS = tt_default_graphics_state;++      error = tt_size_run_prep( size );+      if ( !error )+        size->cvt_ready = 1;+    }++  Exit:+    return error;+  }++#endif /* TT_USE_BYTECODE_INTERPRETER */+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_size_init                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a new TrueType size object.                             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    size :: A handle to the size object.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_size_init( FT_Size  ttsize )           /* TT_Size */+  {+    TT_Size   size  = (TT_Size)ttsize;+    FT_Error  error = TT_Err_Ok;++#ifdef TT_USE_BYTECODE_INTERPRETER+    size->bytecode_ready = 0;+    size->cvt_ready      = 0;+#endif++    size->ttmetrics.valid = FALSE;+    size->strike_index    = 0xFFFFFFFFUL;++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_size_done                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The TrueType size object finalizer.                                */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to the target size object.                        */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_size_done( FT_Size  ttsize )           /* TT_Size */+  {+    TT_Size  size = (TT_Size)ttsize;+++#ifdef TT_USE_BYTECODE_INTERPRETER+    if ( size->bytecode_ready )+      tt_size_done_bytecode( ttsize );+#endif++    size->ttmetrics.valid = FALSE;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_size_reset                                                      */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Reset a TrueType size when resolutions and character dimensions    */+  /*    have been changed.                                                 */+  /*                                                                       */+  /* <Input>                                                               */+  /*    size :: A handle to the target size object.                        */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_size_reset( TT_Size  size )+  {+    TT_Face           face;+    FT_Error          error = TT_Err_Ok;+    FT_Size_Metrics*  metrics;+++    size->ttmetrics.valid = FALSE;++    face = (TT_Face)size->root.face;++    metrics = &size->metrics;++    /* copy the result from base layer */+    *metrics = size->root.metrics;++    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )+      return TT_Err_Invalid_PPem;++    /* This bit flag, if set, indicates that the ppems must be       */+    /* rounded to integers.  Nearly all TrueType fonts have this bit */+    /* set, as hinting won't work really well otherwise.             */+    /*                                                               */+    if ( face->header.Flags & 8 )+    {+      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,+                                    face->root.units_per_EM );+      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,+                                    face->root.units_per_EM );++      metrics->ascender =+        FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );+      metrics->descender =+        FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );+      metrics->height =+        FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );+      metrics->max_advance =+        FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,+                                 metrics->x_scale ) );+    }++    /* compute new transformation */+    if ( metrics->x_ppem >= metrics->y_ppem )+    {+      size->ttmetrics.scale   = metrics->x_scale;+      size->ttmetrics.ppem    = metrics->x_ppem;+      size->ttmetrics.x_ratio = 0x10000L;+      size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,+                                           0x10000L,+                                           metrics->x_ppem );+    }+    else+    {+      size->ttmetrics.scale   = metrics->y_scale;+      size->ttmetrics.ppem    = metrics->y_ppem;+      size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,+                                           0x10000L,+                                           metrics->y_ppem );+      size->ttmetrics.y_ratio = 0x10000L;+    }++#ifdef TT_USE_BYTECODE_INTERPRETER+    size->cvt_ready = 0;+#endif /* TT_USE_BYTECODE_INTERPRETER */++    if ( !error )+      size->ttmetrics.valid = TRUE;++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_driver_init                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a given TrueType driver object.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target driver object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_driver_init( FT_Module  ttdriver )     /* TT_Driver */+  {++#ifdef TT_USE_BYTECODE_INTERPRETER++    TT_Driver  driver = (TT_Driver)ttdriver;+++    if ( !TT_New_Context( driver ) )+      return TT_Err_Could_Not_Find_Context;++#else++    FT_UNUSED( ttdriver );++#endif++    return TT_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_driver_done                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalize a given TrueType driver.                                  */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target TrueType driver.                  */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  tt_driver_done( FT_Module  ttdriver )     /* TT_Driver */+  {+#ifdef TT_USE_BYTECODE_INTERPRETER+    TT_Driver  driver = (TT_Driver)ttdriver;+++    /* destroy the execution context */+    if ( driver->context )+    {+      TT_Done_Context( driver->context );+      driver->context = NULL;+    }+#else+    FT_UNUSED( ttdriver );+#endif++  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_slot_init                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initialize a new slot object.                                      */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    slot :: A handle to the slot object.                               */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_slot_init( FT_GlyphSlot  slot )+  {+    return FT_GlyphLoader_CreateExtra( slot->internal->loader );+  }+++/* END */
+ src/truetype/ttobjs.h view
@@ -0,0 +1,431 @@+/***************************************************************************/+/*                                                                         */+/*  ttobjs.h                                                               */+/*                                                                         */+/*    Objects manager (specification).                                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTOBJS_H__+#define __TTOBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    TT_Driver                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a TrueType driver object.                              */+  /*                                                                       */+  typedef struct TT_DriverRec_*  TT_Driver;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    TT_Instance                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a TrueType size object.                                */+  /*                                                                       */+  typedef struct TT_SizeRec_*  TT_Size;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    TT_GlyphSlot                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a TrueType glyph slot object.                          */+  /*                                                                       */+  /* <Note>                                                                */+  /*    This is a direct typedef of FT_GlyphSlot, as there is nothing      */+  /*    specific about the TrueType glyph slot.                            */+  /*                                                                       */+  typedef FT_GlyphSlot  TT_GlyphSlot;+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    TT_GraphicsState                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The TrueType graphics state used during bytecode interpretation.   */+  /*                                                                       */+  typedef struct  TT_GraphicsState_+  {+    FT_UShort      rp0;+    FT_UShort      rp1;+    FT_UShort      rp2;++    FT_UnitVector  dualVector;+    FT_UnitVector  projVector;+    FT_UnitVector  freeVector;++#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING+    FT_Bool        both_x_axis;+#endif++    FT_Long        loop;+    FT_F26Dot6     minimum_distance;+    FT_Int         round_state;++    FT_Bool        auto_flip;+    FT_F26Dot6     control_value_cutin;+    FT_F26Dot6     single_width_cutin;+    FT_F26Dot6     single_width_value;+    FT_Short       delta_base;+    FT_Short       delta_shift;++    FT_Byte        instruct_control;+    /* According to Greg Hitchcock from Microsoft, the `scan_control'     */+    /* variable as documented in the TrueType specification is a 32-bit   */+    /* integer; the high-word part holds the SCANTYPE value, the low-word */+    /* part the SCANCTRL value.  We separate it into two fields.          */+    FT_Bool        scan_control;+    FT_Int         scan_type;++    FT_UShort      gep0;+    FT_UShort      gep1;+    FT_UShort      gep2;++  } TT_GraphicsState;+++#ifdef TT_USE_BYTECODE_INTERPRETER++  FT_LOCAL( void )+  tt_glyphzone_done( TT_GlyphZone  zone );++  FT_LOCAL( FT_Error )+  tt_glyphzone_new( FT_Memory     memory,+                    FT_UShort     maxPoints,+                    FT_Short      maxContours,+                    TT_GlyphZone  zone );++#endif /* TT_USE_BYTECODE_INTERPRETER */++++  /*************************************************************************/+  /*                                                                       */+  /*  EXECUTION SUBTABLES                                                  */+  /*                                                                       */+  /*  These sub-tables relate to instruction execution.                    */+  /*                                                                       */+  /*************************************************************************/+++#define TT_MAX_CODE_RANGES  3+++  /*************************************************************************/+  /*                                                                       */+  /* There can only be 3 active code ranges at once:                       */+  /*   - the Font Program                                                  */+  /*   - the CVT Program                                                   */+  /*   - a glyph's instructions set                                        */+  /*                                                                       */+  typedef enum  TT_CodeRange_Tag_+  {+    tt_coderange_none = 0,+    tt_coderange_font,+    tt_coderange_cvt,+    tt_coderange_glyph++  } TT_CodeRange_Tag;+++  typedef struct  TT_CodeRange_+  {+    FT_Byte*  base;+    FT_ULong  size;++  } TT_CodeRange;++  typedef TT_CodeRange  TT_CodeRangeTable[TT_MAX_CODE_RANGES];+++  /*************************************************************************/+  /*                                                                       */+  /* Defines a function/instruction definition record.                     */+  /*                                                                       */+  typedef struct  TT_DefRecord_+  {+    FT_Int   range;      /* in which code range is it located? */+    FT_Long  start;      /* where does it start?               */+    FT_UInt  opc;        /* function #, or instruction code    */+    FT_Bool  active;     /* is it active?                      */++  } TT_DefRecord, *TT_DefArray;+++  /*************************************************************************/+  /*                                                                       */+  /* Subglyph transformation record.                                       */+  /*                                                                       */+  typedef struct  TT_Transform_+  {+    FT_Fixed    xx, xy;     /* transformation matrix coefficients */+    FT_Fixed    yx, yy;+    FT_F26Dot6  ox, oy;     /* offsets        */++  } TT_Transform;+++  /*************************************************************************/+  /*                                                                       */+  /* A note regarding non-squared pixels:                                  */+  /*                                                                       */+  /* (This text will probably go into some docs at some time; for now, it  */+  /* is kept here to explain some definitions in the TT_Size_Metrics       */+  /* record).                                                              */+  /*                                                                       */+  /* The CVT is a one-dimensional array containing values that control     */+  /* certain important characteristics in a font, like the height of all   */+  /* capitals, all lowercase letter, default spacing or stem width/height. */+  /*                                                                       */+  /* These values are found in FUnits in the font file, and must be scaled */+  /* to pixel coordinates before being used by the CVT and glyph programs. */+  /* Unfortunately, when using distinct x and y resolutions (or distinct x */+  /* and y pointsizes), there are two possible scalings.                   */+  /*                                                                       */+  /* A first try was to implement a `lazy' scheme where all values were    */+  /* scaled when first used.  However, while some values are always used   */+  /* in the same direction, some others are used under many different      */+  /* circumstances and orientations.                                       */+  /*                                                                       */+  /* I have found a simpler way to do the same, and it even seems to work  */+  /* in most of the cases:                                                 */+  /*                                                                       */+  /* - All CVT values are scaled to the maximum ppem size.                 */+  /*                                                                       */+  /* - When performing a read or write in the CVT, a ratio factor is used  */+  /*   to perform adequate scaling.  Example:                              */+  /*                                                                       */+  /*     x_ppem = 14                                                       */+  /*     y_ppem = 10                                                       */+  /*                                                                       */+  /*   We choose ppem = x_ppem = 14 as the CVT scaling size.  All cvt      */+  /*   entries are scaled to it.                                           */+  /*                                                                       */+  /*     x_ratio = 1.0                                                     */+  /*     y_ratio = y_ppem/ppem (< 1.0)                                     */+  /*                                                                       */+  /*   We compute the current ratio like:                                  */+  /*                                                                       */+  /*   - If projVector is horizontal,                                      */+  /*       ratio = x_ratio = 1.0                                           */+  /*                                                                       */+  /*   - if projVector is vertical,                                        */+  /*       ratio = y_ratio                                                 */+  /*                                                                       */+  /*   - else,                                                             */+  /*       ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */+  /*                                                                       */+  /*   Reading a cvt value returns                                         */+  /*     ratio * cvt[index]                                                */+  /*                                                                       */+  /*   Writing a cvt value in pixels:                                      */+  /*     cvt[index] / ratio                                                */+  /*                                                                       */+  /*   The current ppem is simply                                          */+  /*     ratio * ppem                                                      */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* Metrics used by the TrueType size and context objects.                */+  /*                                                                       */+  typedef struct  TT_Size_Metrics_+  {+    /* for non-square pixels */+    FT_Long     x_ratio;+    FT_Long     y_ratio;++    FT_UShort   ppem;               /* maximum ppem size              */+    FT_Long     ratio;              /* current ratio                  */+    FT_Fixed    scale;++    FT_F26Dot6  compensations[4];   /* device-specific compensations  */++    FT_Bool     valid;++    FT_Bool     rotated;            /* `is the glyph rotated?'-flag   */+    FT_Bool     stretched;          /* `is the glyph stretched?'-flag */++  } TT_Size_Metrics;+++  /*************************************************************************/+  /*                                                                       */+  /* TrueType size class.                                                  */+  /*                                                                       */+  typedef struct  TT_SizeRec_+  {+    FT_SizeRec         root;++    /* we have our own copy of metrics so that we can modify */+    /* it without affecting auto-hinting (when used)         */+    FT_Size_Metrics    metrics;++    TT_Size_Metrics    ttmetrics;++    FT_ULong           strike_index;      /* 0xFFFFFFFF to indicate invalid */++#ifdef TT_USE_BYTECODE_INTERPRETER++    FT_UInt            num_function_defs; /* number of function definitions */+    FT_UInt            max_function_defs;+    TT_DefArray        function_defs;     /* table of function definitions  */++    FT_UInt            num_instruction_defs;  /* number of ins. definitions */+    FT_UInt            max_instruction_defs;+    TT_DefArray        instruction_defs;      /* table of ins. definitions  */++    FT_UInt            max_func;+    FT_UInt            max_ins;++    TT_CodeRangeTable  codeRangeTable;++    TT_GraphicsState   GS;++    FT_ULong           cvt_size;      /* the scaled control value table */+    FT_Long*           cvt;++    FT_UShort          storage_size; /* The storage area is now part of */+    FT_Long*           storage;      /* the instance                    */++    TT_GlyphZoneRec    twilight;     /* The instance's twilight zone    */++    /* debugging variables */++    /* When using the debugger, we must keep the */+    /* execution context tied to the instance    */+    /* object rather than asking it on demand.   */++    FT_Bool            debug;+    TT_ExecContext     context;++    FT_Bool            bytecode_ready;+    FT_Bool            cvt_ready;++#endif /* TT_USE_BYTECODE_INTERPRETER */++  } TT_SizeRec;+++  /*************************************************************************/+  /*                                                                       */+  /* TrueType driver class.                                                */+  /*                                                                       */+  typedef struct  TT_DriverRec_+  {+    FT_DriverRec     root;+    TT_ExecContext   context;  /* execution context        */+    TT_GlyphZoneRec  zone;     /* glyph loader points zone */++    void*            extension_component;++  } TT_DriverRec;+++  /* Note: All of the functions below (except tt_size_reset()) are used    */+  /* as function pointers in a FT_Driver_ClassRec.  Therefore their        */+  /* parameters are of types FT_Face, FT_Size, etc., rather than TT_Face,  */+  /* TT_Size, etc., so that the compiler can confirm that the types and    */+  /* number of parameters are correct.  In all cases the FT_xxx types are  */+  /* cast to their TT_xxx counterparts inside the functions since FreeType */+  /* will always use the TT driver to create them.                         */+++  /*************************************************************************/+  /*                                                                       */+  /* Face functions                                                        */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_face_init( FT_Stream      stream,+                FT_Face        ttface,      /* TT_Face */+                FT_Int         face_index,+                FT_Int         num_params,+                FT_Parameter*  params );++  FT_LOCAL( void )+  tt_face_done( FT_Face  ttface );          /* TT_Face */+++  /*************************************************************************/+  /*                                                                       */+  /* Size functions                                                        */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_size_init( FT_Size  ttsize );          /* TT_Size */++  FT_LOCAL( void )+  tt_size_done( FT_Size  ttsize );          /* TT_Size */++#ifdef TT_USE_BYTECODE_INTERPRETER++  FT_LOCAL( FT_Error )+  tt_size_run_fpgm( TT_Size  size );++  FT_LOCAL( FT_Error )+  tt_size_run_prep( TT_Size  size );++  FT_LOCAL( FT_Error )+  tt_size_ready_bytecode( TT_Size  size );++#endif /* TT_USE_BYTECODE_INTERPRETER */++  FT_LOCAL( FT_Error )+  tt_size_reset( TT_Size  size );+++  /*************************************************************************/+  /*                                                                       */+  /* Driver functions                                                      */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_driver_init( FT_Module  ttdriver );    /* TT_Driver */++  FT_LOCAL( void )+  tt_driver_done( FT_Module  ttdriver );    /* TT_Driver */+++  /*************************************************************************/+  /*                                                                       */+  /* Slot functions                                                        */+  /*                                                                       */+  FT_LOCAL( FT_Error )+  tt_slot_init( FT_GlyphSlot  slot );+++FT_END_HEADER++#endif /* __TTOBJS_H__ */+++/* END */
+ src/truetype/ttpic.c view
@@ -0,0 +1,81 @@+/***************************************************************************/+/*                                                                         */+/*  ttpic.c                                                                */+/*                                                                         */+/*    The FreeType position independent code services for truetype module. */+/*                                                                         */+/*  Copyright 2009, 2010 by                                                */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_INTERNAL_OBJECTS_H+#include "ttpic.h"++#ifdef FT_CONFIG_OPTION_PIC++  /* forward declaration of PIC init functions from ttdriver.c */+  FT_Error FT_Create_Class_tt_services( FT_Library, FT_ServiceDescRec**);+  void FT_Destroy_Class_tt_services( FT_Library, FT_ServiceDescRec*);+  void FT_Init_Class_tt_service_gx_multi_masters(FT_Service_MultiMastersRec*);+  void FT_Init_Class_tt_service_truetype_glyf(FT_Service_TTGlyfRec*);++  void+  tt_driver_class_pic_free(  FT_Library library )+  {+    FT_PIC_Container* pic_container = &library->pic_container;+    FT_Memory memory = library->memory;+    if ( pic_container->truetype )+    {+      TTModulePIC* container = (TTModulePIC*)pic_container->truetype;+      if(container->tt_services)+        FT_Destroy_Class_tt_services(library, container->tt_services);+      container->tt_services = NULL;+      FT_FREE( container );+      pic_container->truetype = NULL;+    }+  }+++  FT_Error+  tt_driver_class_pic_init( FT_Library  library )+  {+    FT_PIC_Container*  pic_container = &library->pic_container;+    FT_Error           error         = TT_Err_Ok;+    TTModulePIC*       container;+    FT_Memory          memory        = library->memory;+++    /* allocate pointer, clear and set global container pointer */+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )+      return error;+    FT_MEM_SET( container, 0, sizeof(*container) );+    pic_container->truetype = container;++    /* initialize pointer table - this is how the module usually expects this data */+    error = FT_Create_Class_tt_services(library, &container->tt_services);+    if(error) +      goto Exit;+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    FT_Init_Class_tt_service_gx_multi_masters(&container->tt_service_gx_multi_masters);+#endif+    FT_Init_Class_tt_service_truetype_glyf(&container->tt_service_truetype_glyf);+Exit:+    if(error)+      tt_driver_class_pic_free(library);+    return error;+  }++#endif /* FT_CONFIG_OPTION_PIC */+++/* END */
+ src/truetype/ttpic.h view
@@ -0,0 +1,59 @@+/***************************************************************************/+/*                                                                         */+/*  ttpic.h                                                                */+/*                                                                         */+/*    The FreeType position independent code services for truetype module. */+/*                                                                         */+/*  Copyright 2009 by                                                      */+/*  Oran Agra and Mickey Gabel.                                            */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTPIC_H__+#define __TTPIC_H__++  +FT_BEGIN_HEADER++#ifndef FT_CONFIG_OPTION_PIC+#define FT_TT_SERVICES_GET                   tt_services+#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET   tt_service_gx_multi_masters+#define FT_TT_SERVICE_TRUETYPE_GLYF_GET      tt_service_truetype_glyf++#else /* FT_CONFIG_OPTION_PIC */++#include FT_MULTIPLE_MASTERS_H+#include FT_SERVICE_MULTIPLE_MASTERS_H+#include FT_SERVICE_TRUETYPE_GLYF_H++  typedef struct TTModulePIC_+  {+    FT_ServiceDescRec* tt_services;+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    FT_Service_MultiMastersRec tt_service_gx_multi_masters;+#endif+    FT_Service_TTGlyfRec tt_service_truetype_glyf;+  } TTModulePIC;++#define GET_PIC(lib)                         ((TTModulePIC*)((lib)->pic_container.truetype))+#define FT_TT_SERVICES_GET                   (GET_PIC(library)->tt_services)+#define FT_TT_SERVICE_GX_MULTI_MASTERS_GET   (GET_PIC(library)->tt_service_gx_multi_masters)+#define FT_TT_SERVICE_TRUETYPE_GLYF_GET      (GET_PIC(library)->tt_service_truetype_glyf)++#endif /* FT_CONFIG_OPTION_PIC */++ /* */++FT_END_HEADER++#endif /* __TTPIC_H__ */+++/* END */
+ src/truetype/ttpload.c view
@@ -0,0 +1,598 @@+/***************************************************************************/+/*                                                                         */+/*  ttpload.c                                                              */+/*                                                                         */+/*    TrueType-specific tables loader (body).                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_TAGS_H++#include "ttpload.h"++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+#include "ttgxvar.h"+#endif++#include "tterrors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_ttpload+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_loca                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the locations table.                                          */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: The input stream.                                        */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_loca( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error  error;+    FT_ULong  table_len;+    FT_Int    shift;+++    /* we need the size of the `glyf' table for malformed `loca' tables */+    error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );++    /* it is possible that a font doesn't have a glyf table at all */+    /* or its size is zero                                         */+    if ( error == TT_Err_Table_Missing )+      face->glyf_len = 0;+    else if ( error )+      goto Exit;++    FT_TRACE2(( "Locations " ));+    error = face->goto_table( face, TTAG_loca, stream, &table_len );+    if ( error )+    {+      error = TT_Err_Locations_Missing;+      goto Exit;+    }++    if ( face->header.Index_To_Loc_Format != 0 )+    {+      shift = 2;++      if ( table_len >= 0x40000L )+      {+        FT_TRACE2(( "table too large\n" ));+        error = TT_Err_Invalid_Table;+        goto Exit;+      }+      face->num_locations = table_len >> shift;+    }+    else+    {+      shift = 1;++      if ( table_len >= 0x20000L )+      {+        FT_TRACE2(( "table too large\n" ));+        error = TT_Err_Invalid_Table;+        goto Exit;+      }+      face->num_locations = table_len >> shift;+    }++    if ( face->num_locations != (FT_ULong)face->root.num_glyphs )+    {+      FT_TRACE2(( "glyph count mismatch!  loca: %d, maxp: %d\n",+                  face->num_locations, face->root.num_glyphs ));++      /* we only handle the case where `maxp' gives a larger value */+      if ( face->num_locations < (FT_ULong)face->root.num_glyphs )+      {+        FT_Long   new_loca_len = (FT_Long)face->root.num_glyphs << shift;++        TT_Table  entry = face->dir_tables;+        TT_Table  limit = entry + face->num_tables;++        FT_Long   pos  = FT_Stream_Pos( stream );+        FT_Long   dist = 0x7FFFFFFFL;+++        /* compute the distance to next table in font file */+        for ( ; entry < limit; entry++ )+        {+          FT_Long  diff = entry->Offset - pos;+++          if ( diff > 0 && diff < dist )+            dist = diff;+        }++        if ( entry == limit )+        {+          /* `loca' is the last table */+          dist = stream->size - pos;+        }++        if ( new_loca_len <= dist )+        {+          face->num_locations = face->root.num_glyphs;+          table_len           = new_loca_len;++          FT_TRACE2(( "adjusting num_locations to %d\n",+                      face->num_locations ));+        }+      }+    }++    /*+     * Extract the frame.  We don't need to decompress it since+     * we are able to parse it directly.+     */+    if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )+      goto Exit;++    FT_TRACE2(( "loaded\n" ));++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_ULong )+  tt_face_get_location( TT_Face   face,+                        FT_UInt   gindex,+                        FT_UInt  *asize )+  {+    FT_ULong  pos1, pos2;+    FT_Byte*  p;+    FT_Byte*  p_limit;+++    pos1 = pos2 = 0;++    if ( gindex < face->num_locations )+    {+      if ( face->header.Index_To_Loc_Format != 0 )+      {+        p       = face->glyph_locations + gindex * 4;+        p_limit = face->glyph_locations + face->num_locations * 4;++        pos1 = FT_NEXT_ULONG( p );+        pos2 = pos1;++        if ( p + 4 <= p_limit )+          pos2 = FT_NEXT_ULONG( p );+      }+      else+      {+        p       = face->glyph_locations + gindex * 2;+        p_limit = face->glyph_locations + face->num_locations * 2;++        pos1 = FT_NEXT_USHORT( p );+        pos2 = pos1;++        if ( p + 2 <= p_limit )+          pos2 = FT_NEXT_USHORT( p );++        pos1 <<= 1;+        pos2 <<= 1;+      }+    }++    /* Check broken location data */+    if ( pos1 >= face->glyf_len )+    {+      FT_TRACE1(( "tt_face_get_location:"+                 " too large offset=0x%08lx found for gid=0x%04lx,"+                 " exceeding the end of glyf table (0x%08lx)\n",+                 pos1, gindex, face->glyf_len ));+      *asize = 0;+      return 0;+    }++    if ( pos2 >= face->glyf_len )+    {+      FT_TRACE1(( "tt_face_get_location:"+                 " too large offset=0x%08lx found for gid=0x%04lx,"+                 " truncate at the end of glyf table (0x%08lx)\n",+                 pos2, gindex + 1, face->glyf_len ));+      pos2 = face->glyf_len;+    }++    /* The `loca' table must be ordered; it refers to the length of */+    /* an entry as the difference between the current and the next  */+    /* position.  However, there do exist (malformed) fonts which   */+    /* don't obey this rule, so we are only able to provide an      */+    /* upper bound for the size.                                    */+    /*                                                              */+    /* We get (intentionally) a wrong, non-zero result in case the  */+    /* `glyf' table is missing.                                     */+    if ( pos2 >= pos1 )+      *asize = (FT_UInt)( pos2 - pos1 );+    else+      *asize = (FT_UInt)( face->glyf_len - pos1 );++    return pos1;+  }+++  FT_LOCAL_DEF( void )+  tt_face_done_loca( TT_Face  face )+  {+    FT_Stream  stream = face->root.stream;+++    FT_FRAME_RELEASE( face->glyph_locations );+    face->num_locations = 0;+  }++++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_cvt                                                   */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the control value table into a face object.                   */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_cvt( TT_Face    face,+                    FT_Stream  stream )+  {+#ifdef TT_USE_BYTECODE_INTERPRETER++    FT_Error   error;+    FT_Memory  memory = stream->memory;+    FT_ULong   table_len;+++    FT_TRACE2(( "CVT " ));++    error = face->goto_table( face, TTAG_cvt, stream, &table_len );+    if ( error )+    {+      FT_TRACE2(( "is missing\n" ));++      face->cvt_size = 0;+      face->cvt      = NULL;+      error          = TT_Err_Ok;++      goto Exit;+    }++    face->cvt_size = table_len / 2;++    if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )+      goto Exit;++    if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )+      goto Exit;++    {+      FT_Short*  cur   = face->cvt;+      FT_Short*  limit = cur + face->cvt_size;+++      for ( ; cur < limit; cur++ )+        *cur = FT_GET_SHORT();+    }++    FT_FRAME_EXIT();+    FT_TRACE2(( "loaded\n" ));++#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT+    if ( face->doblend )+      error = tt_face_vary_cvt( face, stream );+#endif++  Exit:+    return error;++#else /* !TT_USE_BYTECODE_INTERPRETER */++    FT_UNUSED( face   );+    FT_UNUSED( stream );++    return TT_Err_Ok;++#endif+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_fpgm                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the font program.                                             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_fpgm( TT_Face    face,+                     FT_Stream  stream )+  {+#ifdef TT_USE_BYTECODE_INTERPRETER++    FT_Error  error;+    FT_ULong  table_len;+++    FT_TRACE2(( "Font program " ));++    /* The font program is optional */+    error = face->goto_table( face, TTAG_fpgm, stream, &table_len );+    if ( error )+    {+      face->font_program      = NULL;+      face->font_program_size = 0;+      error                   = TT_Err_Ok;++      FT_TRACE2(( "is missing\n" ));+    }+    else+    {+      face->font_program_size = table_len;+      if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )+        goto Exit;++      FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));+    }++  Exit:+    return error;++#else /* !TT_USE_BYTECODE_INTERPRETER */++    FT_UNUSED( face   );+    FT_UNUSED( stream );++    return TT_Err_Ok;++#endif+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_prep                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the cvt program.                                              */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  tt_face_load_prep( TT_Face    face,+                     FT_Stream  stream )+  {+#ifdef TT_USE_BYTECODE_INTERPRETER++    FT_Error  error;+    FT_ULong  table_len;+++    FT_TRACE2(( "Prep program " ));++    error = face->goto_table( face, TTAG_prep, stream, &table_len );+    if ( error )+    {+      face->cvt_program      = NULL;+      face->cvt_program_size = 0;+      error                  = TT_Err_Ok;++      FT_TRACE2(( "is missing\n" ));+    }+    else+    {+      face->cvt_program_size = table_len;+      if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )+        goto Exit;++      FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));+    }++  Exit:+    return error;++#else /* !TT_USE_BYTECODE_INTERPRETER */++    FT_UNUSED( face   );+    FT_UNUSED( stream );++    return TT_Err_Ok;++#endif+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    tt_face_load_hdmx                                                  */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Load the `hdmx' table into the face object.                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face   :: A handle to the target face object.                      */+  /*                                                                       */+  /*    stream :: A handle to the input stream.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */++  FT_LOCAL_DEF( FT_Error )+  tt_face_load_hdmx( TT_Face    face,+                     FT_Stream  stream )+  {+    FT_Error   error;+    FT_Memory  memory = stream->memory;+    FT_UInt    version, nn, num_records;+    FT_ULong   table_size, record_size;+    FT_Byte*   p;+    FT_Byte*   limit;+++    /* this table is optional */+    error = face->goto_table( face, TTAG_hdmx, stream, &table_size );+    if ( error || table_size < 8 )+      return TT_Err_Ok;++    if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )+      goto Exit;++    p     = face->hdmx_table;+    limit = p + table_size;++    version     = FT_NEXT_USHORT( p );+    num_records = FT_NEXT_USHORT( p );+    record_size = FT_NEXT_ULONG( p );++    /* The maximum number of bytes in an hdmx device record is the */+    /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */+    /* the reason why `record_size' is a long (which we read as    */+    /* unsigned long for convenience).  In practice, two bytes     */+    /* sufficient to hold the size value.                          */+    /*                                                             */+    /* There are at least two fonts, HANNOM-A and HANNOM-B version */+    /* 2.0 (2005), which get this wrong: The upper two bytes of    */+    /* the size value are set to 0xFF instead of 0x00.  We catch   */+    /* and fix this.                                               */++    if ( record_size >= 0xFFFF0000UL )+      record_size &= 0xFFFFU;++    /* The limit for `num_records' is a heuristic value. */++    if ( version != 0 || num_records > 255 || record_size > 0x10001L )+    {+      error = TT_Err_Invalid_File_Format;+      goto Fail;+    }++    if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )+      goto Fail;++    for ( nn = 0; nn < num_records; nn++ )+    {+      if ( p + record_size > limit )+        break;++      face->hdmx_record_sizes[nn] = p[0];+      p                          += record_size;+    }++    face->hdmx_record_count = nn;+    face->hdmx_table_size   = table_size;+    face->hdmx_record_size  = record_size;++  Exit:+    return error;++  Fail:+    FT_FRAME_RELEASE( face->hdmx_table );+    face->hdmx_table_size = 0;+    goto Exit;+  }+++  FT_LOCAL_DEF( void )+  tt_face_free_hdmx( TT_Face  face )+  {+    FT_Stream  stream = face->root.stream;+    FT_Memory  memory = stream->memory;+++    FT_FREE( face->hdmx_record_sizes );+    FT_FRAME_RELEASE( face->hdmx_table );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Return the advance width table for a given pixel size if it is found  */+  /* in the font's `hdmx' table (if any).                                  */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Byte* )+  tt_face_get_device_metrics( TT_Face  face,+                              FT_UInt  ppem,+                              FT_UInt  gindex )+  {+    FT_UInt   nn;+    FT_Byte*  result      = NULL;+    FT_ULong  record_size = face->hdmx_record_size;+    FT_Byte*  record      = face->hdmx_table + 8;+++    for ( nn = 0; nn < face->hdmx_record_count; nn++ )+      if ( face->hdmx_record_sizes[nn] == ppem )+      {+        gindex += 2;+        if ( gindex < record_size )+          result = record + nn * record_size + gindex;+        break;+      }++    return result;+  }+++/* END */
+ src/truetype/ttpload.h view
@@ -0,0 +1,75 @@+/***************************************************************************/+/*                                                                         */+/*  ttpload.h                                                              */+/*                                                                         */+/*    TrueType-specific tables loader (specification).                     */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2005, 2006 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __TTPLOAD_H__+#define __TTPLOAD_H__+++#include <ft2build.h>+#include FT_INTERNAL_TRUETYPE_TYPES_H+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  tt_face_load_loca( TT_Face    face,+                     FT_Stream  stream );++  FT_LOCAL( FT_ULong )+  tt_face_get_location( TT_Face   face,+                        FT_UInt   gindex,+                        FT_UInt  *asize );++  FT_LOCAL( void )+  tt_face_done_loca( TT_Face  face );++  FT_LOCAL( FT_Error )+  tt_face_load_cvt( TT_Face    face,+                    FT_Stream  stream );++  FT_LOCAL( FT_Error )+  tt_face_load_fpgm( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_prep( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( FT_Error )+  tt_face_load_hdmx( TT_Face    face,+                     FT_Stream  stream );+++  FT_LOCAL( void )+  tt_face_free_hdmx( TT_Face  face );+++  FT_LOCAL( FT_Byte* )+  tt_face_get_device_metrics( TT_Face    face,+                              FT_UInt    ppem,+                              FT_UInt    gindex );++FT_END_HEADER++#endif /* __TTPLOAD_H__ */+++/* END */
+ src/type1/t1afm.c view
@@ -0,0 +1,397 @@+/***************************************************************************/+/*                                                                         */+/*  t1afm.c                                                                */+/*                                                                         */+/*    AFM support for Type 1 fonts (body).                                 */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "t1afm.h"+#include "t1errors.h"+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1afm+++  FT_LOCAL_DEF( void )+  T1_Done_Metrics( FT_Memory     memory,+                   AFM_FontInfo  fi )+  {+    FT_FREE( fi->KernPairs );+    fi->NumKernPair = 0;++    FT_FREE( fi->TrackKerns );+    fi->NumTrackKern = 0;++    FT_FREE( fi );+  }+++  /* read a glyph name and return the equivalent glyph index */+  static FT_Int+  t1_get_index( const char*  name,+                FT_Offset    len,+                void*        user_data )+  {+    T1_Font  type1 = (T1_Font)user_data;+    FT_Int   n;+++    /* PS string/name length must be < 16-bit */+    if ( len > 0xFFFFU )+      return 0;++    for ( n = 0; n < type1->num_glyphs; n++ )+    {+      char*  gname = (char*)type1->glyph_names[n];+++      if ( gname && gname[0] == name[0]        &&+           ft_strlen( gname ) == len           &&+           ft_strncmp( gname, name, len ) == 0 )+        return n;+    }++    return 0;+  }+++#undef  KERN_INDEX+#define KERN_INDEX( g1, g2 )  ( ( (FT_ULong)(g1) << 16 ) | (g2) )+++  /* compare two kerning pairs */+  FT_CALLBACK_DEF( int )+  compare_kern_pairs( const void*  a,+                      const void*  b )+  {+    AFM_KernPair  pair1 = (AFM_KernPair)a;+    AFM_KernPair  pair2 = (AFM_KernPair)b;++    FT_ULong  index1 = KERN_INDEX( pair1->index1, pair1->index2 );+    FT_ULong  index2 = KERN_INDEX( pair2->index1, pair2->index2 );+++    if ( index1 > index2 )+      return 1;+    else if ( index1 < index2 )+      return -1;+    else+      return 0;+  }+++  /* parse a PFM file -- for now, only read the kerning pairs */+  static FT_Error+  T1_Read_PFM( FT_Face       t1_face,+               FT_Stream     stream,+               AFM_FontInfo  fi )+  {+    FT_Error      error = T1_Err_Ok;+    FT_Memory     memory = stream->memory;+    FT_Byte*      start;+    FT_Byte*      limit;+    FT_Byte*      p;+    AFM_KernPair  kp;+    FT_Int        width_table_length;+    FT_CharMap    oldcharmap;+    FT_CharMap    charmap;+    FT_Int        n;+++    start = (FT_Byte*)stream->cursor;+    limit = (FT_Byte*)stream->limit;+    p     = start;++    /* Figure out how long the width table is.          */+    /* This info is a little-endian short at offset 99. */+    p = start + 99;+    if ( p + 2 > limit )+    {+      error = T1_Err_Unknown_File_Format;+      goto Exit;+    }+    width_table_length = FT_PEEK_USHORT_LE( p );++    p += 18 + width_table_length;+    if ( p + 0x12 > limit || FT_PEEK_USHORT_LE( p ) < 0x12 )+      /* extension table is probably optional */+      goto Exit;++    /* Kerning offset is 14 bytes from start of extensions table. */+    p += 14;+    p = start + FT_PEEK_ULONG_LE( p );++    if ( p == start )+      /* zero offset means no table */+      goto Exit;++    if ( p + 2 > limit )+    {+      error = T1_Err_Unknown_File_Format;+      goto Exit;+    }++    fi->NumKernPair = FT_PEEK_USHORT_LE( p );+    p += 2;+    if ( p + 4 * fi->NumKernPair > limit )+    {+      error = T1_Err_Unknown_File_Format;+      goto Exit;+    }++    /* Actually, kerning pairs are simply optional! */+    if ( fi->NumKernPair == 0 )+      goto Exit;++    /* allocate the pairs */+    if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )+      goto Exit;++    /* now, read each kern pair */+    kp             = fi->KernPairs;+    limit          = p + 4 * fi->NumKernPair;++    /* PFM kerning data are stored by encoding rather than glyph index, */+    /* so find the PostScript charmap of this font and install it       */+    /* temporarily.  If we find no PostScript charmap, then just use    */+    /* the default and hope it is the right one.                        */+    oldcharmap = t1_face->charmap;+    charmap    = NULL;++    for ( n = 0; n < t1_face->num_charmaps; n++ )+    {+      charmap = t1_face->charmaps[n];+      /* check against PostScript pseudo platform */+      if ( charmap->platform_id == 7 )+      {+        error = FT_Set_Charmap( t1_face, charmap );+        if ( error )+          goto Exit;+        break;+      }+    }++    /* Kerning info is stored as:             */+    /*                                        */+    /*   encoding of first glyph (1 byte)     */+    /*   encoding of second glyph (1 byte)    */+    /*   offset (little-endian short)         */+    for ( ; p < limit ; p += 4 )+    {+      kp->index1 = FT_Get_Char_Index( t1_face, p[0] );+      kp->index2 = FT_Get_Char_Index( t1_face, p[1] );++      kp->x = (FT_Int)FT_PEEK_SHORT_LE(p + 2);+      kp->y = 0;++      kp++;+    }++    if ( oldcharmap != NULL )+      error = FT_Set_Charmap( t1_face, oldcharmap );+    if ( error )+      goto Exit;++    /* now, sort the kern pairs according to their glyph indices */+    ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ),+              compare_kern_pairs );++  Exit:+    if ( error )+    {+      FT_FREE( fi->KernPairs );+      fi->NumKernPair = 0;+    }++    return error;+  }+++  /* parse a metrics file -- either AFM or PFM depending on what */+  /* it turns out to be                                          */+  FT_LOCAL_DEF( FT_Error )+  T1_Read_Metrics( FT_Face    t1_face,+                   FT_Stream  stream )+  {+    PSAux_Service  psaux;+    FT_Memory      memory  = stream->memory;+    AFM_ParserRec  parser;+    AFM_FontInfo   fi      = NULL;+    FT_Error       error   = T1_Err_Unknown_File_Format;+    T1_Font        t1_font = &( (T1_Face)t1_face )->type1;+++    if ( FT_NEW( fi )                   ||+         FT_FRAME_ENTER( stream->size ) )+      goto Exit;++    fi->FontBBox  = t1_font->font_bbox;+    fi->Ascender  = t1_font->font_bbox.yMax;+    fi->Descender = t1_font->font_bbox.yMin;++    psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux;+    if ( psaux && psaux->afm_parser_funcs )+    {+      error = psaux->afm_parser_funcs->init( &parser,+                                             stream->memory,+                                             stream->cursor,+                                             stream->limit );++      if ( !error )+      {+        parser.FontInfo  = fi;+        parser.get_index = t1_get_index;+        parser.user_data = t1_font;++        error = psaux->afm_parser_funcs->parse( &parser );+        psaux->afm_parser_funcs->done( &parser );+      }+    }++    if ( error == T1_Err_Unknown_File_Format )+    {+      FT_Byte*  start = stream->cursor;+++      /* MS Windows allows versions up to 0x3FF without complaining */+      if ( stream->size > 6                              &&+           start[1] < 4                                  &&+           FT_PEEK_ULONG_LE( start + 2 ) == stream->size )+        error = T1_Read_PFM( t1_face, stream, fi );+    }++    if ( !error )+    {+      t1_font->font_bbox = fi->FontBBox;++      t1_face->bbox.xMin =   fi->FontBBox.xMin            >> 16;+      t1_face->bbox.yMin =   fi->FontBBox.yMin            >> 16;+      /* no `U' suffix here to 0xFFFF! */+      t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16;+      t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16;++      /* no `U' suffix here to 0x8000! */+      t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );+      t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );++      if ( fi->NumKernPair )+      {+        t1_face->face_flags |= FT_FACE_FLAG_KERNING;+        ( (T1_Face)t1_face )->afm_data = fi;+        fi = NULL;+      }+    }++    FT_FRAME_EXIT();++  Exit:+    if ( fi != NULL )+      T1_Done_Metrics( memory, fi );++    return error;+  }+++  /* find the kerning for a given glyph pair */+  FT_LOCAL_DEF( void )+  T1_Get_Kerning( AFM_FontInfo  fi,+                  FT_UInt       glyph1,+                  FT_UInt       glyph2,+                  FT_Vector*    kerning )+  {+    AFM_KernPair  min, mid, max;+    FT_ULong      idx = KERN_INDEX( glyph1, glyph2 );+++    /* simple binary search */+    min = fi->KernPairs;+    max = min + fi->NumKernPair - 1;++    while ( min <= max )+    {+      FT_ULong  midi;+++      mid  = min + ( max - min ) / 2;+      midi = KERN_INDEX( mid->index1, mid->index2 );++      if ( midi == idx )+      {+        kerning->x = mid->x;+        kerning->y = mid->y;++        return;+      }++      if ( midi < idx )+        min = mid + 1;+      else+        max = mid - 1;+    }++    kerning->x = 0;+    kerning->y = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Get_Track_Kerning( FT_Face    face,+                        FT_Fixed   ptsize,+                        FT_Int     degree,+                        FT_Fixed*  kerning )+  {+    AFM_FontInfo  fi = (AFM_FontInfo)( (T1_Face)face )->afm_data;+    FT_Int        i;+++    if ( !fi )+      return T1_Err_Invalid_Argument;++    for ( i = 0; i < fi->NumTrackKern; i++ )+    {+      AFM_TrackKern  tk = fi->TrackKerns + i;+++      if ( tk->degree != degree )+        continue;++      if ( ptsize < tk->min_ptsize )+        *kerning = tk->min_kern;+      else if ( ptsize > tk->max_ptsize )+        *kerning = tk->max_kern;+      else+      {+        *kerning = FT_MulDiv( ptsize - tk->min_ptsize,+                              tk->max_kern - tk->min_kern,+                              tk->max_ptsize - tk->min_ptsize ) ++                   tk->min_kern;+      }+    }++    return T1_Err_Ok;+  }+++/* END */
+ src/type1/t1afm.h view
@@ -0,0 +1,54 @@+/***************************************************************************/+/*                                                                         */+/*  t1afm.h                                                                */+/*                                                                         */+/*    AFM support for Type 1 fonts (specification).                        */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2006 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1AFM_H__+#define __T1AFM_H__++#include <ft2build.h>+#include "t1objs.h"+#include FT_INTERNAL_TYPE1_TYPES_H++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  T1_Read_Metrics( FT_Face    face,+                   FT_Stream  stream );++  FT_LOCAL( void )+  T1_Done_Metrics( FT_Memory     memory,+                   AFM_FontInfo  fi );++  FT_LOCAL( void )+  T1_Get_Kerning( AFM_FontInfo  fi,+                  FT_UInt       glyph1,+                  FT_UInt       glyph2,+                  FT_Vector*    kerning );++  FT_LOCAL( FT_Error )+  T1_Get_Track_Kerning( FT_Face    face,+                        FT_Fixed   ptsize,+                        FT_Int     degree,+                        FT_Fixed*  kerning );++FT_END_HEADER++#endif /* __T1AFM_H__ */+++/* END */
+ src/type1/t1driver.c view
@@ -0,0 +1,331 @@+/***************************************************************************/+/*                                                                         */+/*  t1driver.c                                                             */+/*                                                                         */+/*    Type 1 driver interface (body).                                      */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "t1driver.h"+#include "t1gload.h"+#include "t1load.h"++#include "t1errors.h"++#ifndef T1_CONFIG_OPTION_NO_AFM+#include "t1afm.h"+#endif++#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H++#include FT_SERVICE_MULTIPLE_MASTERS_H+#include FT_SERVICE_GLYPH_DICT_H+#include FT_SERVICE_XFREE86_NAME_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_SERVICE_POSTSCRIPT_INFO_H+#include FT_SERVICE_KERNING_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1driver++ /*+  *  GLYPH DICT SERVICE+  *+  */++  static FT_Error+  t1_get_glyph_name( T1_Face     face,+                     FT_UInt     glyph_index,+                     FT_Pointer  buffer,+                     FT_UInt     buffer_max )+  {+    FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max );++    return T1_Err_Ok;+  }+++  static FT_UInt+  t1_get_name_index( T1_Face     face,+                     FT_String*  glyph_name )+  {+    FT_Int      i;+    FT_String*  gname;+++    for ( i = 0; i < face->type1.num_glyphs; i++ )+    {+      gname = face->type1.glyph_names[i];++      if ( !ft_strcmp( glyph_name, gname ) )+        return (FT_UInt)i;+    }++    return 0;+  }+++  static const FT_Service_GlyphDictRec  t1_service_glyph_dict =+  {+    (FT_GlyphDict_GetNameFunc)  t1_get_glyph_name,+    (FT_GlyphDict_NameIndexFunc)t1_get_name_index+  };+++  /*+   *  POSTSCRIPT NAME SERVICE+   *+   */++  static const char*+  t1_get_ps_name( T1_Face  face )+  {+    return (const char*) face->type1.font_name;+  }+++  static const FT_Service_PsFontNameRec  t1_service_ps_name =+  {+    (FT_PsName_GetFunc)t1_get_ps_name+  };+++  /*+   *  MULTIPLE MASTERS SERVICE+   *+   */++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+  static const FT_Service_MultiMastersRec  t1_service_multi_masters =+  {+    (FT_Get_MM_Func)        T1_Get_Multi_Master,+    (FT_Set_MM_Design_Func) T1_Set_MM_Design,+    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,+    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,+    (FT_Set_Var_Design_Func)T1_Set_Var_Design+  };+#endif+++  /*+   *  POSTSCRIPT INFO SERVICE+   *+   */++  static FT_Error+  t1_ps_get_font_info( FT_Face          face,+                       PS_FontInfoRec*  afont_info )+  {+    *afont_info = ((T1_Face)face)->type1.font_info;++    return T1_Err_Ok;+  }+++  static FT_Error+  t1_ps_get_font_extra( FT_Face           face,+                        PS_FontExtraRec*  afont_extra )+  {+    *afont_extra = ((T1_Face)face)->type1.font_extra;++    return T1_Err_Ok;+  }+++  static FT_Int+  t1_ps_has_glyph_names( FT_Face  face )+  {+    FT_UNUSED( face );++    return 1;+  }+++  static FT_Error+  t1_ps_get_font_private( FT_Face         face,+                          PS_PrivateRec*  afont_private )+  {+    *afont_private = ((T1_Face)face)->type1.private_dict;++    return T1_Err_Ok;+  }+++  static const FT_Service_PsInfoRec  t1_service_ps_info =+  {+    (PS_GetFontInfoFunc)   t1_ps_get_font_info,+    (PS_GetFontExtraFunc)  t1_ps_get_font_extra,+    (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,+    (PS_GetFontPrivateFunc)t1_ps_get_font_private,+  };+++#ifndef T1_CONFIG_OPTION_NO_AFM+  static const FT_Service_KerningRec  t1_service_kerning =+  {+    T1_Get_Track_Kerning,+  };+#endif+++  /*+   *  SERVICE LIST+   *+   */++  static const FT_ServiceDescRec  t1_services[] =+  {+    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name },+    { FT_SERVICE_ID_GLYPH_DICT,           &t1_service_glyph_dict },+    { FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_TYPE_1 },+    { FT_SERVICE_ID_POSTSCRIPT_INFO,      &t1_service_ps_info },++#ifndef T1_CONFIG_OPTION_NO_AFM+    { FT_SERVICE_ID_KERNING,              &t1_service_kerning },+#endif++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+    { FT_SERVICE_ID_MULTI_MASTERS,        &t1_service_multi_masters },+#endif+    { NULL, NULL }+  };+++  static FT_Module_Interface+  Get_Interface( FT_Driver         driver,+                 const FT_String*  t1_interface )+  {+    FT_UNUSED( driver );++    return ft_service_list_lookup( t1_services, t1_interface );+  }+++#ifndef T1_CONFIG_OPTION_NO_AFM++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    Get_Kerning                                                        */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A driver method used to return the kerning vector between two      */+  /*    glyphs of the same face.                                           */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face        :: A handle to the source face object.                 */+  /*                                                                       */+  /*    left_glyph  :: The index of the left glyph in the kern pair.       */+  /*                                                                       */+  /*    right_glyph :: The index of the right glyph in the kern pair.      */+  /*                                                                       */+  /* <Output>                                                              */+  /*    kerning     :: The kerning vector.  This is in font units for      */+  /*                   scalable formats, and in pixels for fixed-sizes     */+  /*                   formats.                                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  /* <Note>                                                                */+  /*    Only horizontal layouts (left-to-right & right-to-left) are        */+  /*    supported by this function.  Other layouts, or more sophisticated  */+  /*    kernings are out of scope of this method (the basic driver         */+  /*    interface is meant to be simple).                                  */+  /*                                                                       */+  /*    They can be implemented by format-specific interfaces.             */+  /*                                                                       */+  static FT_Error+  Get_Kerning( T1_Face     face,+               FT_UInt     left_glyph,+               FT_UInt     right_glyph,+               FT_Vector*  kerning )+  {+    kerning->x = 0;+    kerning->y = 0;++    if ( face->afm_data )+      T1_Get_Kerning( (AFM_FontInfo)face->afm_data,+                      left_glyph,+                      right_glyph,+                      kerning );++    return T1_Err_Ok;+  }+++#endif /* T1_CONFIG_OPTION_NO_AFM */+++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  t1_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER       |+      FT_MODULE_DRIVER_SCALABLE   |+      FT_MODULE_DRIVER_HAS_HINTER,++      sizeof( FT_DriverRec ),++      "type1",+      0x10000L,+      0x20000L,++      0,   /* format interface */++      (FT_Module_Constructor)T1_Driver_Init,+      (FT_Module_Destructor) T1_Driver_Done,+      (FT_Module_Requester)  Get_Interface,+    },++    sizeof( T1_FaceRec ),+    sizeof( T1_SizeRec ),+    sizeof( T1_GlyphSlotRec ),++    (FT_Face_InitFunc)        T1_Face_Init,+    (FT_Face_DoneFunc)        T1_Face_Done,+    (FT_Size_InitFunc)        T1_Size_Init,+    (FT_Size_DoneFunc)        T1_Size_Done,+    (FT_Slot_InitFunc)        T1_GlyphSlot_Init,+    (FT_Slot_DoneFunc)        T1_GlyphSlot_Done,++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    (FT_Slot_LoadFunc)        T1_Load_Glyph,++#ifdef T1_CONFIG_OPTION_NO_AFM+    (FT_Face_GetKerningFunc)  0,+    (FT_Face_AttachFunc)      0,+#else+    (FT_Face_GetKerningFunc)  Get_Kerning,+    (FT_Face_AttachFunc)      T1_Read_Metrics,+#endif+    (FT_Face_GetAdvancesFunc) T1_Get_Advances,+    (FT_Size_RequestFunc)     T1_Size_Request,+    (FT_Size_SelectFunc)      0+  };+++/* END */
+ src/type1/t1driver.h view
@@ -0,0 +1,42 @@+/***************************************************************************/+/*                                                                         */+/*  t1driver.h                                                             */+/*                                                                         */+/*    High-level Type 1 driver interface (specification).                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002 by                                           */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1DRIVER_H__+#define __T1DRIVER_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  t1_driver_class;+++FT_END_HEADER++#endif /* __T1DRIVER_H__ */+++/* END */
+ src/type1/t1errors.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  t1errors.h                                                             */+/*                                                                         */+/*    Type 1 error codes (specification only).                             */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the Type 1 error enumeration constants.   */+  /*                                                                       */+  /*************************************************************************/++#ifndef __T1ERRORS_H__+#define __T1ERRORS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  T1_Err_+#define FT_ERR_BASE    FT_Mod_Err_Type1++#include FT_ERRORS_H++#endif /* __T1ERRORS_H__ */+++/* END */
+ src/type1/t1gload.c view
@@ -0,0 +1,515 @@+/***************************************************************************/+/*                                                                         */+/*  t1gload.c                                                              */+/*                                                                         */+/*    Type 1 Glyph Loader (body).                                          */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include "t1gload.h"+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_OUTLINE_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H++#include "t1errors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1gload+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /**********                                                      *********/+  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/+  /**********                                                      *********/+  /**********    The following code is in charge of computing      *********/+  /**********    the maximum advance width of the font.  It        *********/+  /**********    quickly processes each glyph charstring to        *********/+  /**********    extract the value from either a `sbw' or `seac'   *********/+  /**********    operator.                                         *********/+  /**********                                                      *********/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  FT_LOCAL_DEF( FT_Error )+  T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,+                                      FT_UInt     glyph_index,+                                      FT_Data*    char_string )+  {+    T1_Face   face  = (T1_Face)decoder->builder.face;+    T1_Font   type1 = &face->type1;+    FT_Error  error = T1_Err_Ok;++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    FT_Incremental_InterfaceRec *inc =+                      face->root.internal->incremental_interface;+#endif+++    decoder->font_matrix = type1->font_matrix;+    decoder->font_offset = type1->font_offset;++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* For incremental fonts get the character data using the */+    /* callback function.                                     */+    if ( inc )+      error = inc->funcs->get_glyph_data( inc->object,+                                          glyph_index, char_string );+    else++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    /* For ordinary fonts get the character data stored in the face record. */+    {+      char_string->pointer = type1->charstrings[glyph_index];+      char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];+    }++    if ( !error )+      error = decoder->funcs.parse_charstrings(+                decoder, (FT_Byte*)char_string->pointer,+                char_string->length );++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    /* Incremental fonts can optionally override the metrics. */+    if ( !error && inc && inc->funcs->get_glyph_metrics )+    {+      FT_Incremental_MetricsRec  metrics;+++      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );+      metrics.bearing_y = 0;+      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );+      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );++      error = inc->funcs->get_glyph_metrics( inc->object,+                                             glyph_index, FALSE, &metrics );++      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );+      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );+      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );+    }++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    return error;+  }+++  FT_CALLBACK_DEF( FT_Error )+  T1_Parse_Glyph( T1_Decoder  decoder,+                  FT_UInt     glyph_index )+  {+    FT_Data   glyph_data;+    FT_Error  error = T1_Parse_Glyph_And_Get_Char_String(+                        decoder, glyph_index, &glyph_data );+++#ifdef FT_CONFIG_OPTION_INCREMENTAL++    if ( !error )+    {+      T1_Face  face = (T1_Face)decoder->builder.face;+++      if ( face->root.internal->incremental_interface )+        face->root.internal->incremental_interface->funcs->free_glyph_data(+          face->root.internal->incremental_interface->object,+          &glyph_data );+    }++#endif /* FT_CONFIG_OPTION_INCREMENTAL */++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Compute_Max_Advance( T1_Face  face,+                          FT_Pos*  max_advance )+  {+    FT_Error       error;+    T1_DecoderRec  decoder;+    FT_Int         glyph_index;+    T1_Font        type1 = &face->type1;+    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );++    *max_advance = 0;++    /* initialize load decoder */+    error = psaux->t1_decoder_funcs->init( &decoder,+                                           (FT_Face)face,+                                           0, /* size       */+                                           0, /* glyph slot */+                                           (FT_Byte**)type1->glyph_names,+                                           face->blend,+                                           0,+                                           FT_RENDER_MODE_NORMAL,+                                           T1_Parse_Glyph );+    if ( error )+      return error;++    decoder.builder.metrics_only = 1;+    decoder.builder.load_points  = 0;++    decoder.num_subrs     = type1->num_subrs;+    decoder.subrs         = type1->subrs;+    decoder.subrs_len     = type1->subrs_len;++    decoder.buildchar     = face->buildchar;+    decoder.len_buildchar = face->len_buildchar;++    *max_advance = 0;++    /* for each glyph, parse the glyph charstring and extract */+    /* the advance width                                      */+    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )+    {+      /* now get load the unscaled outline */+      error = T1_Parse_Glyph( &decoder, glyph_index );+      if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )+        *max_advance = decoder.builder.advance.x;++      /* ignore the error if one occurred - skip to next glyph */+    }++    psaux->t1_decoder_funcs->done( &decoder );++    return T1_Err_Ok;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Get_Advances( T1_Face    face,+                   FT_UInt    first,+                   FT_UInt    count,+                   FT_ULong   load_flags,+                   FT_Fixed*  advances )+  {+    T1_DecoderRec  decoder;+    T1_Font        type1 = &face->type1;+    PSAux_Service  psaux = (PSAux_Service)face->psaux;+    FT_UInt        nn;+    FT_Error       error;+++    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )+    {+      for ( nn = 0; nn < count; nn++ )+        advances[nn] = 0;++      return T1_Err_Ok;+    }++    error = psaux->t1_decoder_funcs->init( &decoder,+                                           (FT_Face)face,+                                           0, /* size       */+                                           0, /* glyph slot */+                                           (FT_Byte**)type1->glyph_names,+                                           face->blend,+                                           0,+                                           FT_RENDER_MODE_NORMAL,+                                           T1_Parse_Glyph );+    if ( error )+      return error;++    decoder.builder.metrics_only = 1;+    decoder.builder.load_points  = 0;++    decoder.num_subrs = type1->num_subrs;+    decoder.subrs     = type1->subrs;+    decoder.subrs_len = type1->subrs_len;++    decoder.buildchar     = face->buildchar;+    decoder.len_buildchar = face->len_buildchar;++    for ( nn = 0; nn < count; nn++ )+    {+      error = T1_Parse_Glyph( &decoder, first + nn );+      if ( !error )+        advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );+      else+        advances[nn] = 0;+    }++    return T1_Err_Ok;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Load_Glyph( T1_GlyphSlot  glyph,+                 T1_Size       size,+                 FT_UInt       glyph_index,+                 FT_Int32      load_flags )+  {+    FT_Error                error;+    T1_DecoderRec           decoder;+    T1_Face                 face = (T1_Face)glyph->root.face;+    FT_Bool                 hinting;+    T1_Font                 type1         = &face->type1;+    PSAux_Service           psaux         = (PSAux_Service)face->psaux;+    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;++    FT_Matrix               font_matrix;+    FT_Vector               font_offset;+    FT_Data                 glyph_data;+    FT_Bool                 must_finish_decoder = FALSE;+#ifdef FT_CONFIG_OPTION_INCREMENTAL+    FT_Bool                 glyph_data_loaded = 0;+#endif+++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&+         !face->root.internal->incremental_interface   )+#else+    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )+#endif /* FT_CONFIG_OPTION_INCREMENTAL */+    {+      error = T1_Err_Invalid_Argument;+      goto Exit;+    }++    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );++    if ( load_flags & FT_LOAD_NO_RECURSE )+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;++    if ( size )+    {+      glyph->x_scale = size->root.metrics.x_scale;+      glyph->y_scale = size->root.metrics.y_scale;+    }+    else+    {+      glyph->x_scale = 0x10000L;+      glyph->y_scale = 0x10000L;+    }++    glyph->root.outline.n_points   = 0;+    glyph->root.outline.n_contours = 0;++    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&+                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );++    glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;++    error = decoder_funcs->init( &decoder,+                                 (FT_Face)face,+                                 (FT_Size)size,+                                 (FT_GlyphSlot)glyph,+                                 (FT_Byte**)type1->glyph_names,+                                 face->blend,+                                 FT_BOOL( hinting ),+                                 FT_LOAD_TARGET_MODE( load_flags ),+                                 T1_Parse_Glyph );+    if ( error )+      goto Exit;++    must_finish_decoder = TRUE;++    decoder.builder.no_recurse = FT_BOOL(+                                   ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );++    decoder.num_subrs     = type1->num_subrs;+    decoder.subrs         = type1->subrs;+    decoder.subrs_len     = type1->subrs_len;++    decoder.buildchar     = face->buildchar;+    decoder.len_buildchar = face->len_buildchar;++    /* now load the unscaled outline */+    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,+                                                &glyph_data );+    if ( error )+      goto Exit;+#ifdef FT_CONFIG_OPTION_INCREMENTAL+    glyph_data_loaded = 1;+#endif++    font_matrix = decoder.font_matrix;+    font_offset = decoder.font_offset;++    /* save new glyph tables */+    decoder_funcs->done( &decoder );++    must_finish_decoder = FALSE;++    /* now, set the metrics -- this is rather simple, as   */+    /* the left side bearing is the xMin, and the top side */+    /* bearing the yMax                                    */+    if ( !error )+    {+      glyph->root.outline.flags &= FT_OUTLINE_OWNER;+      glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;++      /* for composite glyphs, return only left side bearing and */+      /* advance width                                           */+      if ( load_flags & FT_LOAD_NO_RECURSE )+      {+        FT_Slot_Internal  internal = glyph->root.internal;+++        glyph->root.metrics.horiBearingX =+          FIXED_TO_INT( decoder.builder.left_bearing.x );+        glyph->root.metrics.horiAdvance  =+          FIXED_TO_INT( decoder.builder.advance.x );++        internal->glyph_matrix      = font_matrix;+        internal->glyph_delta       = font_offset;+        internal->glyph_transformed = 1;+      }+      else+      {+        FT_BBox            cbox;+        FT_Glyph_Metrics*  metrics = &glyph->root.metrics;+        FT_Vector          advance;+++        /* copy the _unscaled_ advance width */+        metrics->horiAdvance =+          FIXED_TO_INT( decoder.builder.advance.x );+        glyph->root.linearHoriAdvance =+          FIXED_TO_INT( decoder.builder.advance.x );+        glyph->root.internal->glyph_transformed = 0;++        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) +        {+          /* make up vertical ones */+          metrics->vertAdvance = ( face->type1.font_bbox.yMax -+                                   face->type1.font_bbox.yMin ) >> 16;+          glyph->root.linearVertAdvance = metrics->vertAdvance;+        }+        else+        {+          metrics->vertAdvance =+            FIXED_TO_INT( decoder.builder.advance.y );+          glyph->root.linearVertAdvance =+            FIXED_TO_INT( decoder.builder.advance.y );+        }++        glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;++        if ( size && size->root.metrics.y_ppem < 24 )+          glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;++#if 1+        /* apply the font matrix, if any */+        if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx ||+             font_matrix.xy != 0        || font_matrix.yx != 0              )+          FT_Outline_Transform( &glyph->root.outline, &font_matrix );++        if ( font_offset.x || font_offset.y )+          FT_Outline_Translate( &glyph->root.outline,+                                font_offset.x,+                                font_offset.y );++        advance.x = metrics->horiAdvance;+        advance.y = 0;+        FT_Vector_Transform( &advance, &font_matrix );+        metrics->horiAdvance = advance.x + font_offset.x;+        advance.x = 0;+        advance.y = metrics->vertAdvance;+        FT_Vector_Transform( &advance, &font_matrix );+        metrics->vertAdvance = advance.y + font_offset.y;+#endif++        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )+        {+          /* scale the outline and the metrics */+          FT_Int       n;+          FT_Outline*  cur = decoder.builder.base;+          FT_Vector*   vec = cur->points;+          FT_Fixed     x_scale = glyph->x_scale;+          FT_Fixed     y_scale = glyph->y_scale;+++          /* First of all, scale the points, if we are not hinting */+          if ( !hinting || ! decoder.builder.hints_funcs )+            for ( n = cur->n_points; n > 0; n--, vec++ )+            {+              vec->x = FT_MulFix( vec->x, x_scale );+              vec->y = FT_MulFix( vec->y, y_scale );+            }++          /* Then scale the metrics */+          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );+          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );+        }++        /* compute the other metrics */+        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );++        metrics->width  = cbox.xMax - cbox.xMin;+        metrics->height = cbox.yMax - cbox.yMin;++        metrics->horiBearingX = cbox.xMin;+        metrics->horiBearingY = cbox.yMax;++        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) +        {+          /* make up vertical ones */+          ft_synthesize_vertical_metrics( metrics,+                                          metrics->vertAdvance );+        }+      }++      /* Set control data to the glyph charstrings.  Note that this is */+      /* _not_ zero-terminated.                                        */+      glyph->root.control_data = (FT_Byte*)glyph_data.pointer;+      glyph->root.control_len  = glyph_data.length;+    }+++  Exit:++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( glyph_data_loaded && face->root.internal->incremental_interface )+    {+      face->root.internal->incremental_interface->funcs->free_glyph_data(+        face->root.internal->incremental_interface->object,+        &glyph_data );++      /* Set the control data to null - it is no longer available if   */+      /* loaded incrementally.                                         */+      glyph->root.control_data = 0;+      glyph->root.control_len  = 0;+    }+#endif++    if ( must_finish_decoder )+      decoder_funcs->done( &decoder );++    return error;+  }+++/* END */
+ src/type1/t1gload.h view
@@ -0,0 +1,53 @@+/***************************************************************************/+/*                                                                         */+/*  t1gload.h                                                              */+/*                                                                         */+/*    Type 1 Glyph Loader (specification).                                 */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2008 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1GLOAD_H__+#define __T1GLOAD_H__+++#include <ft2build.h>+#include "t1objs.h"+++FT_BEGIN_HEADER+++  FT_LOCAL( FT_Error )+  T1_Compute_Max_Advance( T1_Face  face,+                          FT_Pos*  max_advance );++  FT_LOCAL( FT_Error )+  T1_Get_Advances( T1_Face    face,+                   FT_UInt    first,+                   FT_UInt    count,+                   FT_ULong   load_flags,+                   FT_Fixed*  advances );++  FT_LOCAL( FT_Error )+  T1_Load_Glyph( T1_GlyphSlot  glyph,+                 T1_Size       size,+                 FT_UInt       glyph_index,+                 FT_Int32      load_flags );+++FT_END_HEADER++#endif /* __T1GLOAD_H__ */+++/* END */
+ src/type1/t1load.c view
@@ -0,0 +1,2237 @@+/***************************************************************************/+/*                                                                         */+/*  t1load.c                                                               */+/*                                                                         */+/*    Type 1 font loader (body).                                           */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */+/*            2010 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This is the new and improved Type 1 data loader for FreeType 2.  The  */+  /* old loader has several problems: it is slow, complex, difficult to    */+  /* maintain, and contains incredible hacks to make it accept some        */+  /* ill-formed Type 1 fonts without hiccup-ing.  Moreover, about 5% of    */+  /* the Type 1 fonts on my machine still aren't loaded correctly by it.   */+  /*                                                                       */+  /* This version is much simpler, much faster and also easier to read and */+  /* maintain by a great order of magnitude.  The idea behind it is to     */+  /* _not_ try to read the Type 1 token stream with a state machine (i.e.  */+  /* a Postscript-like interpreter) but rather to perform simple pattern   */+  /* matching.                                                             */+  /*                                                                       */+  /* Indeed, nearly all data definitions follow a simple pattern like      */+  /*                                                                       */+  /*  ... /Field <data> ...                                                */+  /*                                                                       */+  /* where <data> can be a number, a boolean, a string, or an array of     */+  /* numbers.  There are a few exceptions, namely the encoding, font name, */+  /* charstrings, and subrs; they are handled with a special pattern       */+  /* matching routine.                                                     */+  /*                                                                       */+  /* All other common cases are handled very simply.  The matching rules   */+  /* are defined in the file `t1tokens.h' through the use of several       */+  /* macros calls PARSE_XXX.  This file is included twice here; the first  */+  /* time to generate parsing callback functions, the second time to       */+  /* generate a table of keywords (with pointers to the associated         */+  /* callback functions).                                                  */+  /*                                                                       */+  /* The function `parse_dict' simply scans *linearly* a given dictionary  */+  /* (either the top-level or private one) and calls the appropriate       */+  /* callback when it encounters an immediate keyword.                     */+  /*                                                                       */+  /* This is by far the fastest way one can find to parse and read all     */+  /* data.                                                                 */+  /*                                                                       */+  /* This led to tremendous code size reduction.  Note that later, the     */+  /* glyph loader will also be _greatly_ simplified, and the automatic     */+  /* hinter will replace the clumsy `t1hinter'.                            */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_CONFIG_CONFIG_H+#include FT_MULTIPLE_MASTERS_H+#include FT_INTERNAL_TYPE1_TYPES_H+#include FT_INTERNAL_CALC_H++#include "t1load.h"+#include "t1errors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1load+++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                    MULTIPLE MASTERS SUPPORT                   *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static FT_Error+  t1_allocate_blend( T1_Face  face,+                     FT_UInt  num_designs,+                     FT_UInt  num_axis )+  {+    PS_Blend   blend;+    FT_Memory  memory = face->root.memory;+    FT_Error   error  = T1_Err_Ok;+++    blend = face->blend;+    if ( !blend )+    {+      if ( FT_NEW( blend ) )+        goto Exit;++      blend->num_default_design_vector = 0;++      face->blend = blend;+    }++    /* allocate design data if needed */+    if ( num_designs > 0 )+    {+      if ( blend->num_designs == 0 )+      {+        FT_UInt  nn;+++        /* allocate the blend `private' and `font_info' dictionaries */+        if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs     ) ||+             FT_NEW_ARRAY( blend->privates[1], num_designs       ) ||+             FT_NEW_ARRAY( blend->bboxes[1], num_designs         ) ||+             FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )+          goto Exit;++        blend->default_weight_vector = blend->weight_vector + num_designs;++        blend->font_infos[0] = &face->type1.font_info;+        blend->privates  [0] = &face->type1.private_dict;+        blend->bboxes    [0] = &face->type1.font_bbox;++        for ( nn = 2; nn <= num_designs; nn++ )+        {+          blend->privates[nn]   = blend->privates  [nn - 1] + 1;+          blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;+          blend->bboxes[nn]     = blend->bboxes    [nn - 1] + 1;+        }++        blend->num_designs   = num_designs;+      }+      else if ( blend->num_designs != num_designs )+        goto Fail;+    }++    /* allocate axis data if needed */+    if ( num_axis > 0 )+    {+      if ( blend->num_axis != 0 && blend->num_axis != num_axis )+        goto Fail;++      blend->num_axis = num_axis;+    }++    /* allocate the blend design pos table if needed */+    num_designs = blend->num_designs;+    num_axis    = blend->num_axis;+    if ( num_designs && num_axis && blend->design_pos[0] == 0 )+    {+      FT_UInt  n;+++      if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )+        goto Exit;++      for ( n = 1; n < num_designs; n++ )+        blend->design_pos[n] = blend->design_pos[0] + num_axis * n;+    }++  Exit:+    return error;++  Fail:+    error = T1_Err_Invalid_File_Format;+    goto Exit;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Get_Multi_Master( T1_Face           face,+                       FT_Multi_Master*  master )+  {+    PS_Blend  blend = face->blend;+    FT_UInt   n;+    FT_Error  error;+++    error = T1_Err_Invalid_Argument;++    if ( blend )+    {+      master->num_axis    = blend->num_axis;+      master->num_designs = blend->num_designs;++      for ( n = 0; n < blend->num_axis; n++ )+      {+        FT_MM_Axis*   axis = master->axis + n;+        PS_DesignMap  map = blend->design_map + n;+++        axis->name    = blend->axis_names[n];+        axis->minimum = map->design_points[0];+        axis->maximum = map->design_points[map->num_points - 1];+      }++      error = T1_Err_Ok;+    }++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Given a normalized (blend) coordinate, figure out the design          */+  /* coordinate appropriate for that value.                                */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Fixed )+  mm_axis_unmap( PS_DesignMap  axismap,+                 FT_Fixed      ncv )+  {+    int  j;+++    if ( ncv <= axismap->blend_points[0] )+      return INT_TO_FIXED( axismap->design_points[0] );++    for ( j = 1; j < axismap->num_points; ++j )+    {+      if ( ncv <= axismap->blend_points[j] )+      {+        FT_Fixed  t = FT_MulDiv( ncv - axismap->blend_points[j - 1],+                                 0x10000L,+                                 axismap->blend_points[j] -+                                   axismap->blend_points[j - 1] );++        return INT_TO_FIXED( axismap->design_points[j - 1] ) ++                 FT_MulDiv( t,+                            axismap->design_points[j] -+                              axismap->design_points[j - 1],+                            1L );+      }+    }++    return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Given a vector of weights, one for each design, figure out the        */+  /* normalized axis coordinates which gave rise to those weights.         */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  mm_weights_unmap( FT_Fixed*  weights,+                    FT_Fixed*  axiscoords,+                    FT_UInt    axis_count )+  {+    FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );++    if ( axis_count == 1 )+      axiscoords[0] = weights[1];++    else if ( axis_count == 2 )+    {+      axiscoords[0] = weights[3] + weights[1];+      axiscoords[1] = weights[3] + weights[2];+    }++    else if ( axis_count == 3 )+    {+      axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];+      axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];+      axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];+    }++    else+    {+      axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] ++                        weights[7] + weights[5] + weights[3] + weights[1];+      axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] ++                        weights[7] + weights[6] + weights[3] + weights[2];+      axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] ++                        weights[7] + weights[6] + weights[5] + weights[4];+      axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] ++                        weights[11] + weights[10] + weights[9] + weights[8];+    }+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Just a wrapper around T1_Get_Multi_Master to support the different    */+  /*  arguments needed by the GX var distortable fonts.                    */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  T1_Get_MM_Var( T1_Face      face,+                 FT_MM_Var*  *master )+  {+    FT_Memory        memory = face->root.memory;+    FT_MM_Var       *mmvar;+    FT_Multi_Master  mmaster;+    FT_Error         error;+    FT_UInt          i;+    FT_Fixed         axiscoords[T1_MAX_MM_AXIS];+    PS_Blend         blend = face->blend;+++    error = T1_Get_Multi_Master( face, &mmaster );+    if ( error )+      goto Exit;+    if ( FT_ALLOC( mmvar,+                   sizeof ( FT_MM_Var ) ++                     mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )+      goto Exit;++    mmvar->num_axis        = mmaster.num_axis;+    mmvar->num_designs     = mmaster.num_designs;+    mmvar->num_namedstyles = (FT_UInt)-1;                /* Does not apply */+    mmvar->axis            = (FT_Var_Axis*)&mmvar[1];+                                      /* Point to axes after MM_Var struct */+    mmvar->namedstyle      = NULL;++    for ( i = 0 ; i < mmaster.num_axis; ++i )+    {+      mmvar->axis[i].name    = mmaster.axis[i].name;+      mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum);+      mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum);+      mmvar->axis[i].def     = ( mmvar->axis[i].minimum ++                                   mmvar->axis[i].maximum ) / 2;+                            /* Does not apply.  But this value is in range */+      mmvar->axis[i].strid   = (FT_UInt)-1;    /* Does not apply */+      mmvar->axis[i].tag     = (FT_ULong)-1;   /* Does not apply */++      if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )+        mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );+      else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )+        mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );+      else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )+        mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );+    }++    if ( blend->num_designs == ( 1U << blend->num_axis ) )+    {+      mm_weights_unmap( blend->default_weight_vector,+                        axiscoords,+                        blend->num_axis );++      for ( i = 0; i < mmaster.num_axis; ++i )+        mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],+                                            axiscoords[i] );+    }++    *master = mmvar;++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Set_MM_Blend( T1_Face    face,+                   FT_UInt    num_coords,+                   FT_Fixed*  coords )+  {+    PS_Blend  blend = face->blend;+    FT_Error  error;+    FT_UInt   n, m;+++    error = T1_Err_Invalid_Argument;++    if ( blend && blend->num_axis == num_coords )+    {+      /* recompute the weight vector from the blend coordinates */+      error = T1_Err_Ok;++      for ( n = 0; n < blend->num_designs; n++ )+      {+        FT_Fixed  result = 0x10000L;  /* 1.0 fixed */+++        for ( m = 0; m < blend->num_axis; m++ )+        {+          FT_Fixed  factor;+++          /* get current blend axis position */+          factor = coords[m];+          if ( factor < 0 )        factor = 0;+          if ( factor > 0x10000L ) factor = 0x10000L;++          if ( ( n & ( 1 << m ) ) == 0 )+            factor = 0x10000L - factor;++          result = FT_MulFix( result, factor );+        }+        blend->weight_vector[n] = result;+      }++      error = T1_Err_Ok;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Set_MM_Design( T1_Face   face,+                    FT_UInt   num_coords,+                    FT_Long*  coords )+  {+    PS_Blend  blend = face->blend;+    FT_Error  error;+    FT_UInt   n, p;+++    error = T1_Err_Invalid_Argument;+    if ( blend && blend->num_axis == num_coords )+    {+      /* compute the blend coordinates through the blend design map */+      FT_Fixed  final_blends[T1_MAX_MM_DESIGNS];+++      for ( n = 0; n < blend->num_axis; n++ )+      {+        FT_Long       design  = coords[n];+        FT_Fixed      the_blend;+        PS_DesignMap  map     = blend->design_map + n;+        FT_Long*      designs = map->design_points;+        FT_Fixed*     blends  = map->blend_points;+        FT_Int        before  = -1, after = -1;+++        for ( p = 0; p < (FT_UInt)map->num_points; p++ )+        {+          FT_Long  p_design = designs[p];+++          /* exact match? */+          if ( design == p_design )+          {+            the_blend = blends[p];+            goto Found;+          }++          if ( design < p_design )+          {+            after = p;+            break;+          }++          before = p;+        }++        /* now interpolate if necessary */+        if ( before < 0 )+          the_blend = blends[0];++        else if ( after < 0 )+          the_blend = blends[map->num_points - 1];++        else+          the_blend = FT_MulDiv( design         - designs[before],+                                 blends [after] - blends [before],+                                 designs[after] - designs[before] );++      Found:+        final_blends[n] = the_blend;+      }++      error = T1_Set_MM_Blend( face, num_coords, final_blends );+    }++    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Just a wrapper around T1_Set_MM_Design to support the different       */+  /* arguments needed by the GX var distortable fonts.                     */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  T1_Set_Var_Design( T1_Face    face,+                     FT_UInt    num_coords,+                     FT_Fixed*  coords )+  {+     FT_Long   lcoords[4];          /* maximum axis count is 4 */+     FT_UInt   i;+     FT_Error  error;+++     error = T1_Err_Invalid_Argument;+     if ( num_coords <= 4 && num_coords > 0 )+     {+       for ( i = 0; i < num_coords; ++i )+         lcoords[i] = FIXED_TO_INT( coords[i] );+       error = T1_Set_MM_Design( face, num_coords, lcoords );+     }++     return error;+  }+++  FT_LOCAL_DEF( void )+  T1_Done_Blend( T1_Face  face )+  {+    FT_Memory  memory = face->root.memory;+    PS_Blend   blend  = face->blend;+++    if ( blend )+    {+      FT_UInt  num_designs = blend->num_designs;+      FT_UInt  num_axis    = blend->num_axis;+      FT_UInt  n;+++      /* release design pos table */+      FT_FREE( blend->design_pos[0] );+      for ( n = 1; n < num_designs; n++ )+        blend->design_pos[n] = 0;++      /* release blend `private' and `font info' dictionaries */+      FT_FREE( blend->privates[1] );+      FT_FREE( blend->font_infos[1] );+      FT_FREE( blend->bboxes[1] );++      for ( n = 0; n < num_designs; n++ )+      {+        blend->privates  [n] = 0;+        blend->font_infos[n] = 0;+        blend->bboxes    [n] = 0;+      }++      /* release weight vectors */+      FT_FREE( blend->weight_vector );+      blend->default_weight_vector = 0;++      /* release axis names */+      for ( n = 0; n < num_axis; n++ )+        FT_FREE( blend->axis_names[n] );++      /* release design map */+      for ( n = 0; n < num_axis; n++ )+      {+        PS_DesignMap  dmap = blend->design_map + n;+++        FT_FREE( dmap->design_points );+        dmap->num_points = 0;+      }++      FT_FREE( face->blend );+    }+  }+++  static void+  parse_blend_axis_types( T1_Face    face,+                          T1_Loader  loader )+  {+    T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];+    FT_Int       n, num_axis;+    FT_Error     error = T1_Err_Ok;+    PS_Blend     blend;+    FT_Memory    memory;+++    /* take an array of objects */+    T1_ToTokenArray( &loader->parser, axis_tokens,+                     T1_MAX_MM_AXIS, &num_axis );+    if ( num_axis < 0 )+    {+      error = T1_Err_Ignore;+      goto Exit;+    }+    if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )+    {+      FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",+                 num_axis ));+      error = T1_Err_Invalid_File_Format;+      goto Exit;+    }++    /* allocate blend if necessary */+    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );+    if ( error )+      goto Exit;++    blend  = face->blend;+    memory = face->root.memory;++    /* each token is an immediate containing the name of the axis */+    for ( n = 0; n < num_axis; n++ )+    {+      T1_Token    token = axis_tokens + n;+      FT_Byte*    name;+      FT_PtrDist  len;+++      /* skip first slash, if any */+      if ( token->start[0] == '/' )+        token->start++;++      len = token->limit - token->start;+      if ( len == 0 )+      {+        error = T1_Err_Invalid_File_Format;+        goto Exit;+      }++      if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )+        goto Exit;++      name = (FT_Byte*)blend->axis_names[n];+      FT_MEM_COPY( name, token->start, len );+      name[len] = 0;+    }++  Exit:+    loader->parser.root.error = error;+  }+++  static void+  parse_blend_design_positions( T1_Face    face,+                                T1_Loader  loader )+  {+    T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];+    FT_Int       num_designs;+    FT_Int       num_axis;+    T1_Parser    parser = &loader->parser;++    FT_Error     error = T1_Err_Ok;+    PS_Blend     blend;+++    /* get the array of design tokens -- compute number of designs */+    T1_ToTokenArray( parser, design_tokens,+                     T1_MAX_MM_DESIGNS, &num_designs );+    if ( num_designs < 0 )+    {+      error = T1_Err_Ignore;+      goto Exit;+    }+    if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )+    {+      FT_ERROR(( "parse_blend_design_positions:"+                 " incorrect number of designs: %d\n",+                 num_designs ));+      error = T1_Err_Invalid_File_Format;+      goto Exit;+    }++    {+      FT_Byte*  old_cursor = parser->root.cursor;+      FT_Byte*  old_limit  = parser->root.limit;+      FT_Int    n;+++      blend    = face->blend;+      num_axis = 0;  /* make compiler happy */++      for ( n = 0; n < num_designs; n++ )+      {+        T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];+        T1_Token     token;+        FT_Int       axis, n_axis;+++        /* read axis/coordinates tokens */+        token = design_tokens + n;+        parser->root.cursor = token->start;+        parser->root.limit  = token->limit;+        T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );++        if ( n == 0 )+        {+          if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )+          {+            FT_ERROR(( "parse_blend_design_positions:"+                       " invalid number of axes: %d\n",+                       n_axis ));+            error = T1_Err_Invalid_File_Format;+            goto Exit;+          }++          num_axis = n_axis;+          error = t1_allocate_blend( face, num_designs, num_axis );+          if ( error )+            goto Exit;+          blend = face->blend;+        }+        else if ( n_axis != num_axis )+        {+          FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));+          error = T1_Err_Invalid_File_Format;+          goto Exit;+        }++        /* now read each axis token into the design position */+        for ( axis = 0; axis < n_axis; axis++ )+        {+          T1_Token  token2 = axis_tokens + axis;+++          parser->root.cursor = token2->start;+          parser->root.limit  = token2->limit;+          blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );+        }+      }++      loader->parser.root.cursor = old_cursor;+      loader->parser.root.limit  = old_limit;+    }++  Exit:+    loader->parser.root.error = error;+  }+++  static void+  parse_blend_design_map( T1_Face    face,+                          T1_Loader  loader )+  {+    FT_Error     error  = T1_Err_Ok;+    T1_Parser    parser = &loader->parser;+    PS_Blend     blend;+    T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];+    FT_Int       n, num_axis;+    FT_Byte*     old_cursor;+    FT_Byte*     old_limit;+    FT_Memory    memory = face->root.memory;+++    T1_ToTokenArray( parser, axis_tokens,+                     T1_MAX_MM_AXIS, &num_axis );+    if ( num_axis < 0 )+    {+      error = T1_Err_Ignore;+      goto Exit;+    }+    if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )+    {+      FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",+                 num_axis ));+      error = T1_Err_Invalid_File_Format;+      goto Exit;+    }++    old_cursor = parser->root.cursor;+    old_limit  = parser->root.limit;++    error = t1_allocate_blend( face, 0, num_axis );+    if ( error )+      goto Exit;+    blend = face->blend;++    /* now read each axis design map */+    for ( n = 0; n < num_axis; n++ )+    {+      PS_DesignMap  map = blend->design_map + n;+      T1_Token      axis_token;+      T1_TokenRec   point_tokens[T1_MAX_MM_MAP_POINTS];+      FT_Int        p, num_points;+++      axis_token = axis_tokens + n;++      parser->root.cursor = axis_token->start;+      parser->root.limit  = axis_token->limit;+      T1_ToTokenArray( parser, point_tokens,+                       T1_MAX_MM_MAP_POINTS, &num_points );++      if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )+      {+        FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));+        error = T1_Err_Invalid_File_Format;+        goto Exit;+      }++      /* allocate design map data */+      if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )+        goto Exit;+      map->blend_points = map->design_points + num_points;+      map->num_points   = (FT_Byte)num_points;++      for ( p = 0; p < num_points; p++ )+      {+        T1_Token  point_token;+++        point_token = point_tokens + p;++        /* don't include delimiting brackets */+        parser->root.cursor = point_token->start + 1;+        parser->root.limit  = point_token->limit - 1;++        map->design_points[p] = T1_ToInt( parser );+        map->blend_points [p] = T1_ToFixed( parser, 0 );+      }+    }++    parser->root.cursor = old_cursor;+    parser->root.limit  = old_limit;++  Exit:+    parser->root.error = error;+  }+++  static void+  parse_weight_vector( T1_Face    face,+                       T1_Loader  loader )+  {+    T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];+    FT_Int       num_designs;+    FT_Error     error  = T1_Err_Ok;+    T1_Parser    parser = &loader->parser;+    PS_Blend     blend  = face->blend;+    T1_Token     token;+    FT_Int       n;+    FT_Byte*     old_cursor;+    FT_Byte*     old_limit;+++    T1_ToTokenArray( parser, design_tokens,+                     T1_MAX_MM_DESIGNS, &num_designs );+    if ( num_designs < 0 )+    {+      error = T1_Err_Ignore;+      goto Exit;+    }+    if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )+    {+      FT_ERROR(( "parse_weight_vector:"+                 " incorrect number of designs: %d\n",+                 num_designs ));+      error = T1_Err_Invalid_File_Format;+      goto Exit;+    }++    if ( !blend || !blend->num_designs )+    {+      error = t1_allocate_blend( face, num_designs, 0 );+      if ( error )+        goto Exit;+      blend = face->blend;+    }+    else if ( blend->num_designs != (FT_UInt)num_designs )+    {+      FT_ERROR(( "parse_weight_vector:"+                 " /BlendDesignPosition and /WeightVector have\n"+                 "                    "+                 " different number of elements\n" ));+      error = T1_Err_Invalid_File_Format;+      goto Exit;+    }++    old_cursor = parser->root.cursor;+    old_limit  = parser->root.limit;++    for ( n = 0; n < num_designs; n++ )+    {+      token = design_tokens + n;+      parser->root.cursor = token->start;+      parser->root.limit  = token->limit;++      blend->default_weight_vector[n] =+      blend->weight_vector[n]         = T1_ToFixed( parser, 0 );+    }++    parser->root.cursor = old_cursor;+    parser->root.limit  = old_limit;++  Exit:+    parser->root.error = error;+  }+++  /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def           */+  /* we're only interested in the number of array elements */+  static void+  parse_buildchar( T1_Face    face,+                   T1_Loader  loader )+  {+    face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 );++    return;+  }+++#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */+++++  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                      TYPE 1 SYMBOL PARSING                    *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/++  static FT_Error+  t1_load_keyword( T1_Face         face,+                   T1_Loader       loader,+                   const T1_Field  field )+  {+    FT_Error  error;+    void*     dummy_object;+    void**    objects;+    FT_UInt   max_objects;+    PS_Blend  blend = face->blend;+++    /* if the keyword has a dedicated callback, call it */+    if ( field->type == T1_FIELD_TYPE_CALLBACK )+    {+      field->reader( (FT_Face)face, loader );+      error = loader->parser.root.error;+      goto Exit;+    }++    /* now, the keyword is either a simple field, or a table of fields; */+    /* we are now going to take care of it                              */+    switch ( field->location )+    {+    case T1_FIELD_LOCATION_FONT_INFO:+      dummy_object = &face->type1.font_info;+      objects      = &dummy_object;+      max_objects  = 0;++      if ( blend )+      {+        objects     = (void**)blend->font_infos;+        max_objects = blend->num_designs;+      }+      break;++    case T1_FIELD_LOCATION_FONT_EXTRA:+      dummy_object = &face->type1.font_extra;+      objects      = &dummy_object;+      max_objects  = 0;+      break;++    case T1_FIELD_LOCATION_PRIVATE:+      dummy_object = &face->type1.private_dict;+      objects      = &dummy_object;+      max_objects  = 0;++      if ( blend )+      {+        objects     = (void**)blend->privates;+        max_objects = blend->num_designs;+      }+      break;++    case T1_FIELD_LOCATION_BBOX:+      dummy_object = &face->type1.font_bbox;+      objects      = &dummy_object;+      max_objects  = 0;++      if ( blend )+      {+        objects     = (void**)blend->bboxes;+        max_objects = blend->num_designs;+      }+      break;++    case T1_FIELD_LOCATION_LOADER:+      dummy_object = loader;+      objects      = &dummy_object;+      max_objects  = 0;+      break;++    case T1_FIELD_LOCATION_FACE:+      dummy_object = face;+      objects      = &dummy_object;+      max_objects  = 0;+      break;++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+    case T1_FIELD_LOCATION_BLEND:+      dummy_object = face->blend;+      objects      = &dummy_object;+      max_objects  = 0;+      break;+#endif++    default:+      dummy_object = &face->type1;+      objects      = &dummy_object;+      max_objects  = 0;+    }++    if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||+         field->type == T1_FIELD_TYPE_FIXED_ARRAY   )+      error = T1_Load_Field_Table( &loader->parser, field,+                                   objects, max_objects, 0 );+    else+      error = T1_Load_Field( &loader->parser, field,+                             objects, max_objects, 0 );++  Exit:+    return error;+  }+++  static void+  parse_private( T1_Face    face,+                 T1_Loader  loader )+  {+    FT_UNUSED( face );++    loader->keywords_encountered |= T1_PRIVATE;+  }+++  static int+  read_binary_data( T1_Parser  parser,+                    FT_Long*   size,+                    FT_Byte**  base )+  {+    FT_Byte*  cur;+    FT_Byte*  limit = parser->root.limit;+++    /* the binary data has one of the following formats */+    /*                                                  */+    /*   `size' [white*] RD white ....... ND            */+    /*   `size' [white*] -| white ....... |-            */+    /*                                                  */++    T1_Skip_Spaces( parser );++    cur = parser->root.cursor;++    if ( cur < limit && ft_isdigit( *cur ) )+    {+      FT_Long  s = T1_ToInt( parser );+++      T1_Skip_PS_Token( parser );   /* `RD' or `-|' or something else */++      /* there is only one whitespace char after the */+      /* `RD' or `-|' token                          */+      *base = parser->root.cursor + 1;++      if ( s >= 0 && s < limit - *base )+      {+        parser->root.cursor += s + 1;+        *size = s;+        return !parser->root.error;+      }+    }++    FT_ERROR(( "read_binary_data: invalid size field\n" ));+    parser->root.error = T1_Err_Invalid_File_Format;+    return 0;+  }+++  /* We now define the routines to handle the `/Encoding', `/Subrs', */+  /* and `/CharStrings' dictionaries.                                */++  static void+  parse_font_matrix( T1_Face    face,+                     T1_Loader  loader )+  {+    T1_Parser   parser = &loader->parser;+    FT_Matrix*  matrix = &face->type1.font_matrix;+    FT_Vector*  offset = &face->type1.font_offset;+    FT_Face     root   = (FT_Face)&face->root;+    FT_Fixed    temp[6];+    FT_Fixed    temp_scale;+    FT_Int      result;+++    result = T1_ToFixedArray( parser, 6, temp, 3 );++    if ( result < 0 )+    {+      parser->root.error = T1_Err_Invalid_File_Format;+      return;+    }++    temp_scale = FT_ABS( temp[3] );++    if ( temp_scale == 0 )+    {+      FT_ERROR(( "parse_font_matrix: invalid font matrix\n" ));+      parser->root.error = T1_Err_Invalid_File_Format;+      return;+    }++    /* Set Units per EM based on FontMatrix values.  We set the value to */+    /* 1000 / temp_scale, because temp_scale was already multiplied by   */+    /* 1000 (in t1_tofixed, from psobjs.c).                              */++    root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,+                                                 temp_scale ) >> 16 );++    /* we need to scale the values by 1.0/temp_scale */+    if ( temp_scale != 0x10000L )+    {+      temp[0] = FT_DivFix( temp[0], temp_scale );+      temp[1] = FT_DivFix( temp[1], temp_scale );+      temp[2] = FT_DivFix( temp[2], temp_scale );+      temp[4] = FT_DivFix( temp[4], temp_scale );+      temp[5] = FT_DivFix( temp[5], temp_scale );+      temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;+    }++    matrix->xx = temp[0];+    matrix->yx = temp[1];+    matrix->xy = temp[2];+    matrix->yy = temp[3];++    /* note that the offsets must be expressed in integer font units */+    offset->x = temp[4] >> 16;+    offset->y = temp[5] >> 16;+  }+++  static void+  parse_encoding( T1_Face    face,+                  T1_Loader  loader )+  {+    T1_Parser  parser = &loader->parser;+    FT_Byte*   cur;+    FT_Byte*   limit  = parser->root.limit;++    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    T1_Skip_Spaces( parser );+    cur = parser->root.cursor;+    if ( cur >= limit )+    {+      FT_ERROR(( "parse_encoding: out of bounds\n" ));+      parser->root.error = T1_Err_Invalid_File_Format;+      return;+    }++    /* if we have a number or `[', the encoding is an array, */+    /* and we must load it now                               */+    if ( ft_isdigit( *cur ) || *cur == '[' )+    {+      T1_Encoding  encode          = &face->type1.encoding;+      FT_Int       count, n;+      PS_Table     char_table      = &loader->encoding_table;+      FT_Memory    memory          = parser->root.memory;+      FT_Error     error;+      FT_Bool      only_immediates = 0;+++      /* read the number of entries in the encoding; should be 256 */+      if ( *cur == '[' )+      {+        count           = 256;+        only_immediates = 1;+        parser->root.cursor++;+      }+      else+        count = (FT_Int)T1_ToInt( parser );++      T1_Skip_Spaces( parser );+      if ( parser->root.cursor >= limit )+        return;++      /* we use a T1_Table to store our charnames */+      loader->num_chars = encode->num_chars = count;+      if ( FT_NEW_ARRAY( encode->char_index, count )     ||+           FT_NEW_ARRAY( encode->char_name,  count )     ||+           FT_SET_ERROR( psaux->ps_table_funcs->init(+                           char_table, count, memory ) ) )+      {+        parser->root.error = error;+        return;+      }++      /* We need to `zero' out encoding_table.elements */+      for ( n = 0; n < count; n++ )+      {+        char*  notdef = (char *)".notdef";+++        T1_Add_Table( char_table, n, notdef, 8 );+      }++      /* Now we need to read records of the form                */+      /*                                                        */+      /*   ... charcode /charname ...                           */+      /*                                                        */+      /* for each entry in our table.                           */+      /*                                                        */+      /* We simply look for a number followed by an immediate   */+      /* name.  Note that this ignores correctly the sequence   */+      /* that is often seen in type1 fonts:                     */+      /*                                                        */+      /*   0 1 255 { 1 index exch /.notdef put } for dup        */+      /*                                                        */+      /* used to clean the encoding array before anything else. */+      /*                                                        */+      /* Alternatively, if the array is directly given as       */+      /*                                                        */+      /*   /Encoding [ ... ]                                    */+      /*                                                        */+      /* we only read immediates.                               */++      n = 0;+      T1_Skip_Spaces( parser );++      while ( parser->root.cursor < limit )+      {+        cur = parser->root.cursor;++        /* we stop when we encounter a `def' or `]' */+        if ( *cur == 'd' && cur + 3 < limit )+        {+          if ( cur[1] == 'e'         &&+               cur[2] == 'f'         &&+               IS_PS_DELIM( cur[3] ) )+          {+            FT_TRACE6(( "encoding end\n" ));+            cur += 3;+            break;+          }+        }+        if ( *cur == ']' )+        {+          FT_TRACE6(( "encoding end\n" ));+          cur++;+          break;+        }++        /* check whether we've found an entry */+        if ( ft_isdigit( *cur ) || only_immediates )+        {+          FT_Int  charcode;+++          if ( only_immediates )+            charcode = n;+          else+          {+            charcode = (FT_Int)T1_ToInt( parser );+            T1_Skip_Spaces( parser );+          }++          cur = parser->root.cursor;++          if ( *cur == '/' && cur + 2 < limit && n < count )+          {+            FT_PtrDist  len;+++            cur++;++            parser->root.cursor = cur;+            T1_Skip_PS_Token( parser );+            if ( parser->root.error )+              return;++            len = parser->root.cursor - cur;++            parser->root.error = T1_Add_Table( char_table, charcode,+                                               cur, len + 1 );+            if ( parser->root.error )+              return;+            char_table->elements[charcode][len] = '\0';++            n++;+          }+          else if ( only_immediates )+          {+            /* Since the current position is not updated for           */+            /* immediates-only mode we would get an infinite loop if   */+            /* we don't do anything here.                              */+            /*                                                         */+            /* This encoding array is not valid according to the type1 */+            /* specification (it might be an encoding for a CID type1  */+            /* font, however), so we conclude that this font is NOT a  */+            /* type1 font.                                             */+            parser->root.error = FT_Err_Unknown_File_Format;+            return;+          }+        }+        else+        {+          T1_Skip_PS_Token( parser );+          if ( parser->root.error )+            return;+        }++        T1_Skip_Spaces( parser );+      }++      face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;+      parser->root.cursor       = cur;+    }++    /* Otherwise, we should have either `StandardEncoding', */+    /* `ExpertEncoding', or `ISOLatin1Encoding'             */+    else+    {+      if ( cur + 17 < limit                                            &&+           ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;++      else if ( cur + 15 < limit                                          &&+                ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;++      else if ( cur + 18 < limit                                             &&+                ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;++      else+        parser->root.error = T1_Err_Ignore;+    }+  }+++  static void+  parse_subrs( T1_Face    face,+               T1_Loader  loader )+  {+    T1_Parser  parser = &loader->parser;+    PS_Table   table  = &loader->subrs;+    FT_Memory  memory = parser->root.memory;+    FT_Error   error;+    FT_Int     num_subrs;++    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    T1_Skip_Spaces( parser );++    /* test for empty array */+    if ( parser->root.cursor < parser->root.limit &&+         *parser->root.cursor == '['              )+    {+      T1_Skip_PS_Token( parser );+      T1_Skip_Spaces  ( parser );+      if ( parser->root.cursor >= parser->root.limit ||+           *parser->root.cursor != ']'               )+        parser->root.error = T1_Err_Invalid_File_Format;+      return;+    }++    num_subrs = (FT_Int)T1_ToInt( parser );++    /* position the parser right before the `dup' of the first subr */+    T1_Skip_PS_Token( parser );         /* `array' */+    if ( parser->root.error )+      return;+    T1_Skip_Spaces( parser );++    /* initialize subrs array -- with synthetic fonts it is possible */+    /* we get here twice                                             */+    if ( !loader->num_subrs )+    {+      error = psaux->ps_table_funcs->init( table, num_subrs, memory );+      if ( error )+        goto Fail;+    }++    /* the format is simple:   */+    /*                         */+    /*   `index' + binary data */+    /*                         */+    for (;;)+    {+      FT_Long   idx, size;+      FT_Byte*  base;+++      /* If the next token isn't `dup' we are done. */+      if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )+        break;++      T1_Skip_PS_Token( parser );       /* `dup' */++      idx = T1_ToInt( parser );++      if ( !read_binary_data( parser, &size, &base ) )+        return;++      /* The binary string is followed by one token, e.g. `NP' */+      /* (bound to `noaccess put') or by two separate tokens:  */+      /* `noaccess' & `put'.  We position the parser right     */+      /* before the next `dup', if any.                        */+      T1_Skip_PS_Token( parser );   /* `NP' or `|' or `noaccess' */+      if ( parser->root.error )+        return;+      T1_Skip_Spaces  ( parser );++      if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )+      {+        T1_Skip_PS_Token( parser ); /* skip `put' */+        T1_Skip_Spaces  ( parser );+      }++      /* with synthetic fonts it is possible we get here twice */+      if ( loader->num_subrs )+        continue;++      /* some fonts use a value of -1 for lenIV to indicate that */+      /* the charstrings are unencoded                           */+      /*                                                         */+      /* thanks to Tom Kacvinsky for pointing this out           */+      /*                                                         */+      if ( face->type1.private_dict.lenIV >= 0 )+      {+        FT_Byte*  temp;+++        /* some fonts define empty subr records -- this is not totally */+        /* compliant to the specification (which says they should at   */+        /* least contain a `return'), but we support them anyway       */+        if ( size < face->type1.private_dict.lenIV )+        {+          error = T1_Err_Invalid_File_Format;+          goto Fail;+        }++        /* t1_decrypt() shouldn't write to base -- make temporary copy */+        if ( FT_ALLOC( temp, size ) )+          goto Fail;+        FT_MEM_COPY( temp, base, size );+        psaux->t1_decrypt( temp, size, 4330 );+        size -= face->type1.private_dict.lenIV;+        error = T1_Add_Table( table, (FT_Int)idx,+                              temp + face->type1.private_dict.lenIV, size );+        FT_FREE( temp );+      }+      else+        error = T1_Add_Table( table, (FT_Int)idx, base, size );+      if ( error )+        goto Fail;+    }++    if ( !loader->num_subrs )+      loader->num_subrs = num_subrs;++    return;++  Fail:+    parser->root.error = error;+  }+++#define TABLE_EXTEND  5+++  static void+  parse_charstrings( T1_Face    face,+                     T1_Loader  loader )+  {+    T1_Parser      parser       = &loader->parser;+    PS_Table       code_table   = &loader->charstrings;+    PS_Table       name_table   = &loader->glyph_names;+    PS_Table       swap_table   = &loader->swap_table;+    FT_Memory      memory       = parser->root.memory;+    FT_Error       error;++    PSAux_Service  psaux        = (PSAux_Service)face->psaux;++    FT_Byte*       cur;+    FT_Byte*       limit        = parser->root.limit;+    FT_Int         n, num_glyphs;+    FT_UInt        notdef_index = 0;+    FT_Byte        notdef_found = 0;+++    num_glyphs = (FT_Int)T1_ToInt( parser );+    /* some fonts like Optima-Oblique not only define the /CharStrings */+    /* array but access it also                                        */+    if ( num_glyphs == 0 || parser->root.error )+      return;++    /* initialize tables, leaving space for addition of .notdef, */+    /* if necessary, and a few other glyphs to handle buggy      */+    /* fonts which have more glyphs than specified.              */++    /* for some non-standard fonts like `Optima' which provides  */+    /* different outlines depending on the resolution it is      */+    /* possible to get here twice                                */+    if ( !loader->num_glyphs )+    {+      error = psaux->ps_table_funcs->init(+                code_table, num_glyphs + 1 + TABLE_EXTEND, memory );+      if ( error )+        goto Fail;++      error = psaux->ps_table_funcs->init(+                name_table, num_glyphs + 1 + TABLE_EXTEND, memory );+      if ( error )+        goto Fail;++      /* Initialize table for swapping index notdef_index and */+      /* index 0 names and codes (if necessary).              */++      error = psaux->ps_table_funcs->init( swap_table, 4, memory );+      if ( error )+        goto Fail;+    }++    n = 0;++    for (;;)+    {+      FT_Long   size;+      FT_Byte*  base;+++      /* the format is simple:        */+      /*   `/glyphname' + binary data */++      T1_Skip_Spaces( parser );++      cur = parser->root.cursor;+      if ( cur >= limit )+        break;++      /* we stop when we find a `def' or `end' keyword */+      if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )+      {+        if ( cur[0] == 'd' &&+             cur[1] == 'e' &&+             cur[2] == 'f' )+        {+          /* There are fonts which have this: */+          /*                                  */+          /*   /CharStrings 118 dict def      */+          /*   Private begin                  */+          /*   CharStrings begin              */+          /*   ...                            */+          /*                                  */+          /* To catch this we ignore `def' if */+          /* no charstring has actually been  */+          /* seen.                            */+          if ( n )+            break;+        }++        if ( cur[0] == 'e' &&+             cur[1] == 'n' &&+             cur[2] == 'd' )+          break;+      }++      T1_Skip_PS_Token( parser );+      if ( parser->root.error )+        return;++      if ( *cur == '/' )+      {+        FT_PtrDist  len;+++        if ( cur + 1 >= limit )+        {+          error = T1_Err_Invalid_File_Format;+          goto Fail;+        }++        cur++;                              /* skip `/' */+        len = parser->root.cursor - cur;++        if ( !read_binary_data( parser, &size, &base ) )+          return;++        /* for some non-standard fonts like `Optima' which provides */+        /* different outlines depending on the resolution it is     */+        /* possible to get here twice                               */+        if ( loader->num_glyphs )+          continue;++        error = T1_Add_Table( name_table, n, cur, len + 1 );+        if ( error )+          goto Fail;++        /* add a trailing zero to the name table */+        name_table->elements[n][len] = '\0';++        /* record index of /.notdef */+        if ( *cur == '.'                                              &&+             ft_strcmp( ".notdef",+                        (const char*)(name_table->elements[n]) ) == 0 )+        {+          notdef_index = n;+          notdef_found = 1;+        }++        if ( face->type1.private_dict.lenIV >= 0 &&+             n < num_glyphs + TABLE_EXTEND       )+        {+          FT_Byte*  temp;+++          if ( size <= face->type1.private_dict.lenIV )+          {+            error = T1_Err_Invalid_File_Format;+            goto Fail;+          }++          /* t1_decrypt() shouldn't write to base -- make temporary copy */+          if ( FT_ALLOC( temp, size ) )+            goto Fail;+          FT_MEM_COPY( temp, base, size );+          psaux->t1_decrypt( temp, size, 4330 );+          size -= face->type1.private_dict.lenIV;+          error = T1_Add_Table( code_table, n,+                                temp + face->type1.private_dict.lenIV, size );+          FT_FREE( temp );+        }+        else+          error = T1_Add_Table( code_table, n, base, size );+        if ( error )+          goto Fail;++        n++;+      }+    }++    loader->num_glyphs = n;++    /* if /.notdef is found but does not occupy index 0, do our magic. */+    if ( notdef_found                                                 &&+         ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )+    {+      /* Swap glyph in index 0 with /.notdef glyph.  First, add index 0  */+      /* name and code entries to swap_table.  Then place notdef_index   */+      /* name and code entries into swap_table.  Then swap name and code */+      /* entries at indices notdef_index and 0 using values stored in    */+      /* swap_table.                                                     */++      /* Index 0 name */+      error = T1_Add_Table( swap_table, 0,+                            name_table->elements[0],+                            name_table->lengths [0] );+      if ( error )+        goto Fail;++      /* Index 0 code */+      error = T1_Add_Table( swap_table, 1,+                            code_table->elements[0],+                            code_table->lengths [0] );+      if ( error )+        goto Fail;++      /* Index notdef_index name */+      error = T1_Add_Table( swap_table, 2,+                            name_table->elements[notdef_index],+                            name_table->lengths [notdef_index] );+      if ( error )+        goto Fail;++      /* Index notdef_index code */+      error = T1_Add_Table( swap_table, 3,+                            code_table->elements[notdef_index],+                            code_table->lengths [notdef_index] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, notdef_index,+                            swap_table->elements[0],+                            swap_table->lengths [0] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, notdef_index,+                            swap_table->elements[1],+                            swap_table->lengths [1] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, 0,+                            swap_table->elements[2],+                            swap_table->lengths [2] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, 0,+                            swap_table->elements[3],+                            swap_table->lengths [3] );+      if ( error )+        goto Fail;++    }+    else if ( !notdef_found )+    {+      /* notdef_index is already 0, or /.notdef is undefined in   */+      /* charstrings dictionary.  Worry about /.notdef undefined. */+      /* We take index 0 and add it to the end of the table(s)    */+      /* and add our own /.notdef glyph to index 0.               */++      /* 0 333 hsbw endchar */+      FT_Byte  notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };+      char*    notdef_name    = (char *)".notdef";+++      error = T1_Add_Table( swap_table, 0,+                            name_table->elements[0],+                            name_table->lengths [0] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( swap_table, 1,+                            code_table->elements[0],+                            code_table->lengths [0] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, 0, notdef_name, 8 );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, 0, notdef_glyph, 5 );++      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, n,+                            swap_table->elements[0],+                            swap_table->lengths [0] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, n,+                            swap_table->elements[1],+                            swap_table->lengths [1] );+      if ( error )+        goto Fail;++      /* we added a glyph. */+      loader->num_glyphs += 1;+    }++    return;++  Fail:+    parser->root.error = error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* Define the token field static variables.  This is a set of            */+  /* T1_FieldRec variables.                                                */+  /*                                                                       */+  /*************************************************************************/+++  static+  const T1_FieldRec  t1_keywords[] =+  {++#include "t1tokens.h"++    /* now add the special functions... */+    T1_FIELD_CALLBACK( "FontMatrix",           parse_font_matrix,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "Encoding",             parse_encoding,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "Subrs",                parse_subrs,+                       T1_FIELD_DICT_PRIVATE )+    T1_FIELD_CALLBACK( "CharStrings",          parse_charstrings,+                       T1_FIELD_DICT_PRIVATE )+    T1_FIELD_CALLBACK( "Private",              parse_private,+                       T1_FIELD_DICT_FONTDICT )++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+    T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "BlendDesignMap",       parse_blend_design_map,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "BlendAxisTypes",       parse_blend_axis_types,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "WeightVector",         parse_weight_vector,+                       T1_FIELD_DICT_FONTDICT )+    T1_FIELD_CALLBACK( "BuildCharArray",       parse_buildchar,+                       T1_FIELD_DICT_PRIVATE )+#endif++    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }+  };+++#define T1_FIELD_COUNT                                           \+          ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) )+++  static FT_Error+  parse_dict( T1_Face    face,+              T1_Loader  loader,+              FT_Byte*   base,+              FT_Long    size )+  {+    T1_Parser  parser = &loader->parser;+    FT_Byte   *limit, *start_binary = NULL;+    FT_Bool    have_integer = 0;+++    parser->root.cursor = base;+    parser->root.limit  = base + size;+    parser->root.error  = T1_Err_Ok;++    limit = parser->root.limit;++    T1_Skip_Spaces( parser );++    while ( parser->root.cursor < limit )+    {+      FT_Byte*  cur;+++      cur = parser->root.cursor;++      /* look for `eexec' */+      if ( IS_PS_TOKEN( cur, limit, "eexec" ) )+        break;++      /* look for `closefile' which ends the eexec section */+      else if ( IS_PS_TOKEN( cur, limit, "closefile" ) )+        break;++      /* in a synthetic font the base font starts after a           */+      /* `FontDictionary' token that is placed after a Private dict */+      else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) )+      {+        if ( loader->keywords_encountered & T1_PRIVATE )+          loader->keywords_encountered |=+            T1_FONTDIR_AFTER_PRIVATE;+        parser->root.cursor += 13;+      }++      /* check whether we have an integer */+      else if ( ft_isdigit( *cur ) )+      {+        start_binary = cur;+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;+        have_integer = 1;+      }++      /* in valid Type 1 fonts we don't see `RD' or `-|' directly */+      /* since those tokens are handled by parse_subrs and        */+      /* parse_charstrings                                        */+      else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&+                have_integer )+      {+        FT_Long   s;+        FT_Byte*  b;+++        parser->root.cursor = start_binary;+        if ( !read_binary_data( parser, &s, &b ) )+          return T1_Err_Invalid_File_Format;+        have_integer = 0;+      }++      else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&+                have_integer )+      {+        FT_Long   s;+        FT_Byte*  b;+++        parser->root.cursor = start_binary;+        if ( !read_binary_data( parser, &s, &b ) )+          return T1_Err_Invalid_File_Format;+        have_integer = 0;+      }++      /* look for immediates */+      else if ( *cur == '/' && cur + 2 < limit )+      {+        FT_PtrDist  len;+++        cur++;++        parser->root.cursor = cur;+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;++        len = parser->root.cursor - cur;++        if ( len > 0 && len < 22 && parser->root.cursor < limit )+        {+          /* now compare the immediate name to the keyword table */+          T1_Field  keyword = (T1_Field)t1_keywords;+++          for (;;)+          {+            FT_Byte*  name;+++            name = (FT_Byte*)keyword->ident;+            if ( !name )+              break;++            if ( cur[0] == name[0]                                  &&+                 len == (FT_PtrDist)ft_strlen( (const char *)name ) &&+                 ft_memcmp( cur, name, len ) == 0                   )+            {+              /* We found it -- run the parsing callback!     */+              /* We record every instance of every field      */+              /* (until we reach the base font of a           */+              /* synthetic font) to deal adequately with      */+              /* multiple master fonts; this is also          */+              /* necessary because later PostScript           */+              /* definitions override earlier ones.           */++              /* Once we encounter `FontDirectory' after      */+              /* `/Private', we know that this is a synthetic */+              /* font; except for `/CharStrings' we are not   */+              /* interested in anything that follows this     */+              /* `FontDirectory'.                             */++              /* MM fonts have more than one /Private token at */+              /* the top level; let's hope that all the junk   */+              /* that follows the first /Private token is not  */+              /* interesting to us.                            */++              /* According to Adobe Tech Note #5175 (CID-Keyed */+              /* Font Installation for ATM Software) a `begin' */+              /* must be followed by exactly one `end', and    */+              /* `begin' -- `end' pairs must be accurately     */+              /* paired.  We could use this to distinguish     */+              /* between the global Private and the Private    */+              /* dict that is a member of the Blend dict.      */++              const FT_UInt dict =+                ( loader->keywords_encountered & T1_PRIVATE )+                    ? T1_FIELD_DICT_PRIVATE+                    : T1_FIELD_DICT_FONTDICT;++              if ( !( dict & keyword->dict ) )+              {+                FT_TRACE1(( "parse_dict: found %s but ignoring it "+                            "since it is in the wrong dictionary\n",+                            keyword->ident ));+                break;+              }++              if ( !( loader->keywords_encountered &+                      T1_FONTDIR_AFTER_PRIVATE     )                  ||+                   ft_strcmp( (const char*)name, "CharStrings" ) == 0 )+              {+                parser->root.error = t1_load_keyword( face,+                                                      loader,+                                                      keyword );+                if ( parser->root.error != T1_Err_Ok )+                {+                  if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore )+                    parser->root.error = T1_Err_Ok;+                  else+                    return parser->root.error;+                }+              }+              break;+            }++            keyword++;+          }+        }++        have_integer = 0;+      }+      else+      {+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;+        have_integer = 0;+      }++      T1_Skip_Spaces( parser );+    }++  Exit:+    return parser->root.error;+  }+++  static void+  t1_init_loader( T1_Loader  loader,+                  T1_Face    face )+  {+    FT_UNUSED( face );++    FT_MEM_ZERO( loader, sizeof ( *loader ) );+    loader->num_glyphs = 0;+    loader->num_chars  = 0;++    /* initialize the tables -- simply set their `init' field to 0 */+    loader->encoding_table.init  = 0;+    loader->charstrings.init     = 0;+    loader->glyph_names.init     = 0;+    loader->subrs.init           = 0;+    loader->swap_table.init      = 0;+    loader->fontdata             = 0;+    loader->keywords_encountered = 0;+  }+++  static void+  t1_done_loader( T1_Loader  loader )+  {+    T1_Parser  parser = &loader->parser;+++    /* finalize tables */+    T1_Release_Table( &loader->encoding_table );+    T1_Release_Table( &loader->charstrings );+    T1_Release_Table( &loader->glyph_names );+    T1_Release_Table( &loader->swap_table );+    T1_Release_Table( &loader->subrs );++    /* finalize parser */+    T1_Finalize_Parser( parser );+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Open_Face( T1_Face  face )+  {+    T1_LoaderRec   loader;+    T1_Parser      parser;+    T1_Font        type1 = &face->type1;+    PS_Private     priv  = &type1->private_dict;+    FT_Error       error;++    PSAux_Service  psaux = (PSAux_Service)face->psaux;+++    t1_init_loader( &loader, face );++    /* default values */+    face->ndv_idx          = -1;+    face->cdv_idx          = -1;+    face->len_buildchar    = 0;++    priv->blue_shift       = 7;+    priv->blue_fuzz        = 1;+    priv->lenIV            = 4;+    priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );+    priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );++    parser = &loader.parser;+    error  = T1_New_Parser( parser,+                            face->root.stream,+                            face->root.memory,+                            psaux );+    if ( error )+      goto Exit;++    error = parse_dict( face, &loader,+                        parser->base_dict, parser->base_len );+    if ( error )+      goto Exit;++    error = T1_Get_Private_Dict( parser, psaux );+    if ( error )+      goto Exit;++    error = parse_dict( face, &loader,+                        parser->private_dict, parser->private_len );+    if ( error )+      goto Exit;++    /* ensure even-ness of `num_blue_values' */+    priv->num_blue_values &= ~1;++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT++    if ( face->blend                                                     &&+         face->blend->num_default_design_vector != 0                     &&+         face->blend->num_default_design_vector != face->blend->num_axis )+    {+      /* we don't use it currently so just warn, reset, and ignore */+      FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries "+                 "while there are %u axes.\n",+                 face->blend->num_default_design_vector,+                 face->blend->num_axis ));++      face->blend->num_default_design_vector = 0;+    }++    /* the following can happen for MM instances; we then treat the */+    /* font as a normal PS font                                     */+    if ( face->blend                                             &&+         ( !face->blend->num_designs || !face->blend->num_axis ) )+      T1_Done_Blend( face );++    /* another safety check */+    if ( face->blend )+    {+      FT_UInt  i;+++      for ( i = 0; i < face->blend->num_axis; i++ )+        if ( !face->blend->design_map[i].num_points )+        {+          T1_Done_Blend( face );+          break;+        }+    }++    if ( face->blend )+    {+      if ( face->len_buildchar > 0 )+      {+        FT_Memory  memory = face->root.memory;+++        if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) )+        {+          FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" ));+          face->len_buildchar = 0;+          goto Exit;+        }+      }+    }++#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */++    /* now, propagate the subrs, charstrings, and glyphnames tables */+    /* to the Type1 data                                            */+    type1->num_glyphs = loader.num_glyphs;++    if ( loader.subrs.init )+    {+      loader.subrs.init  = 0;+      type1->num_subrs   = loader.num_subrs;+      type1->subrs_block = loader.subrs.block;+      type1->subrs       = loader.subrs.elements;+      type1->subrs_len   = loader.subrs.lengths;+    }++#ifdef FT_CONFIG_OPTION_INCREMENTAL+    if ( !face->root.internal->incremental_interface )+#endif+      if ( !loader.charstrings.init )+      {+        FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" ));+        error = T1_Err_Invalid_File_Format;+      }++    loader.charstrings.init  = 0;+    type1->charstrings_block = loader.charstrings.block;+    type1->charstrings       = loader.charstrings.elements;+    type1->charstrings_len   = loader.charstrings.lengths;++    /* we copy the glyph names `block' and `elements' fields; */+    /* the `lengths' field must be released later             */+    type1->glyph_names_block    = loader.glyph_names.block;+    type1->glyph_names          = (FT_String**)loader.glyph_names.elements;+    loader.glyph_names.block    = 0;+    loader.glyph_names.elements = 0;++    /* we must now build type1.encoding when we have a custom array */+    if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )+    {+      FT_Int    charcode, idx, min_char, max_char;+      FT_Byte*  char_name;+      FT_Byte*  glyph_name;+++      /* OK, we do the following: for each element in the encoding  */+      /* table, look up the index of the glyph having the same name */+      /* the index is then stored in type1.encoding.char_index, and */+      /* the name to type1.encoding.char_name                       */++      min_char = 0;+      max_char = 0;++      charcode = 0;+      for ( ; charcode < loader.encoding_table.max_elems; charcode++ )+      {+        type1->encoding.char_index[charcode] = 0;+        type1->encoding.char_name [charcode] = (char *)".notdef";++        char_name = loader.encoding_table.elements[charcode];+        if ( char_name )+          for ( idx = 0; idx < type1->num_glyphs; idx++ )+          {+            glyph_name = (FT_Byte*)type1->glyph_names[idx];+            if ( ft_strcmp( (const char*)char_name,+                            (const char*)glyph_name ) == 0 )+            {+              type1->encoding.char_index[charcode] = (FT_UShort)idx;+              type1->encoding.char_name [charcode] = (char*)glyph_name;++              /* Change min/max encoded char only if glyph name is */+              /* not /.notdef                                      */+              if ( ft_strcmp( (const char*)".notdef",+                              (const char*)glyph_name ) != 0 )+              {+                if ( charcode < min_char )+                  min_char = charcode;+                if ( charcode >= max_char )+                  max_char = charcode + 1;+              }+              break;+            }+          }+      }++      type1->encoding.code_first = min_char;+      type1->encoding.code_last  = max_char;+      type1->encoding.num_chars  = loader.num_chars;+    }++  Exit:+    t1_done_loader( &loader );+    return error;+  }+++/* END */
+ src/type1/t1load.h view
@@ -0,0 +1,102 @@+/***************************************************************************/+/*                                                                         */+/*  t1load.h                                                               */+/*                                                                         */+/*    Type 1 font loader (specification).                                  */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2004, 2006, 2007 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1LOAD_H__+#define __T1LOAD_H__+++#include <ft2build.h>+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+#include FT_MULTIPLE_MASTERS_H++#include "t1parse.h"+++FT_BEGIN_HEADER+++  typedef struct  T1_Loader_+  {+    T1_ParserRec  parser;          /* parser used to read the stream */++    FT_Int        num_chars;       /* number of characters in encoding */+    PS_TableRec   encoding_table;  /* PS_Table used to store the       */+                                   /* encoding character names         */++    FT_Int        num_glyphs;+    PS_TableRec   glyph_names;+    PS_TableRec   charstrings;+    PS_TableRec   swap_table;      /* For moving .notdef glyph to index 0. */++    FT_Int        num_subrs;+    PS_TableRec   subrs;+    FT_Bool       fontdata;++    FT_UInt       keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */++  } T1_LoaderRec, *T1_Loader;+++  /* treatment of some keywords differs depending on whether */+  /* they precede or follow certain other keywords           */++#define T1_PRIVATE                ( 1 << 0 )+#define T1_FONTDIR_AFTER_PRIVATE  ( 1 << 1 )+++  FT_LOCAL( FT_Error )+  T1_Open_Face( T1_Face  face );++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT++  FT_LOCAL( FT_Error )+  T1_Get_Multi_Master( T1_Face           face,+                       FT_Multi_Master*  master );++  FT_LOCAL_DEF( FT_Error )+  T1_Get_MM_Var( T1_Face      face,+                 FT_MM_Var*  *master );++  FT_LOCAL( FT_Error )+  T1_Set_MM_Blend( T1_Face    face,+                   FT_UInt    num_coords,+                   FT_Fixed*  coords );++  FT_LOCAL( FT_Error )+  T1_Set_MM_Design( T1_Face   face,+                    FT_UInt   num_coords,+                    FT_Long*  coords );++  FT_LOCAL_DEF( FT_Error )+  T1_Set_Var_Design( T1_Face    face,+                     FT_UInt    num_coords,+                     FT_Fixed*  coords );++  FT_LOCAL( void )+  T1_Done_Blend( T1_Face  face );++#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */+++FT_END_HEADER++#endif /* __T1LOAD_H__ */+++/* END */
+ src/type1/t1objs.c view
@@ -0,0 +1,597 @@+/***************************************************************************/+/*                                                                         */+/*  t1objs.c                                                               */+/*                                                                         */+/*    Type 1 objects manager (body).                                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_CALC_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_TRUETYPE_IDS_H++#include "t1gload.h"+#include "t1load.h"++#include "t1errors.h"++#ifndef T1_CONFIG_OPTION_NO_AFM+#include "t1afm.h"+#endif++#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1objs+++  /*************************************************************************/+  /*                                                                       */+  /*                            SIZE FUNCTIONS                             */+  /*                                                                       */+  /*  note that we store the global hints in the size's "internal" root    */+  /*  field                                                                */+  /*                                                                       */+  /*************************************************************************/+++  static PSH_Globals_Funcs+  T1_Size_Get_Globals_Funcs( T1_Size  size )+  {+    T1_Face           face     = (T1_Face)size->root.face;+    PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;+    FT_Module         module;+++    module = FT_Get_Module( size->root.face->driver->root.library,+                            "pshinter" );+    return ( module && pshinter && pshinter->get_globals_funcs )+           ? pshinter->get_globals_funcs( module )+           : 0 ;+  }+++  FT_LOCAL_DEF( void )+  T1_Size_Done( T1_Size  size )+  {+    if ( size->root.internal )+    {+      PSH_Globals_Funcs  funcs;+++      funcs = T1_Size_Get_Globals_Funcs( size );+      if ( funcs )+        funcs->destroy( (PSH_Globals)size->root.internal );++      size->root.internal = 0;+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Size_Init( T1_Size  size )+  {+    FT_Error           error = T1_Err_Ok;+    PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );+++    if ( funcs )+    {+      PSH_Globals  globals;+      T1_Face      face = (T1_Face)size->root.face;+++      error = funcs->create( size->root.face->memory,+                             &face->type1.private_dict, &globals );+      if ( !error )+        size->root.internal = (FT_Size_Internal)(void*)globals;+    }++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Size_Request( T1_Size          size,+                   FT_Size_Request  req )+  {+    PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );+++    FT_Request_Metrics( size->root.face, req );++    if ( funcs )+      funcs->set_scale( (PSH_Globals)size->root.internal,+                        size->root.metrics.x_scale,+                        size->root.metrics.y_scale,+                        0, 0 );++    return T1_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                            SLOT  FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/++  FT_LOCAL_DEF( void )+  T1_GlyphSlot_Done( T1_GlyphSlot  slot )+  {+    slot->root.internal->glyph_hints = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_GlyphSlot_Init( T1_GlyphSlot  slot )+  {+    T1_Face           face;+    PSHinter_Service  pshinter;+++    face     = (T1_Face)slot->root.face;+    pshinter = (PSHinter_Service)face->pshinter;++    if ( pshinter )+    {+      FT_Module  module;+++      module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" );+      if (module)+      {+        T1_Hints_Funcs  funcs;++        funcs = pshinter->get_t1_funcs( module );+        slot->root.internal->glyph_hints = (void*)funcs;+      }+    }+    return 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /*                            FACE  FUNCTIONS                            */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    T1_Face_Done                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The face object destructor.                                        */+  /*                                                                       */+  /* <Input>                                                               */+  /*    face :: A typeless pointer to the face object to destroy.          */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  T1_Face_Done( T1_Face  face )+  {+    FT_Memory  memory;+    T1_Font    type1;+++    if ( !face )+      return;++    memory = face->root.memory;+    type1  = &face->type1;++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT+    /* release multiple masters information */+    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );++    if ( face->buildchar )+    {+      FT_FREE( face->buildchar );++      face->buildchar     = NULL;+      face->len_buildchar = 0;+    }++    T1_Done_Blend( face );+    face->blend = 0;+#endif++    /* release font info strings */+    {+      PS_FontInfo  info = &type1->font_info;+++      FT_FREE( info->version );+      FT_FREE( info->notice );+      FT_FREE( info->full_name );+      FT_FREE( info->family_name );+      FT_FREE( info->weight );+    }++    /* release top dictionary */+    FT_FREE( type1->charstrings_len );+    FT_FREE( type1->charstrings );+    FT_FREE( type1->glyph_names );++    FT_FREE( type1->subrs );+    FT_FREE( type1->subrs_len );++    FT_FREE( type1->subrs_block );+    FT_FREE( type1->charstrings_block );+    FT_FREE( type1->glyph_names_block );++    FT_FREE( type1->encoding.char_index );+    FT_FREE( type1->encoding.char_name );+    FT_FREE( type1->font_name );++#ifndef T1_CONFIG_OPTION_NO_AFM+    /* release afm data if present */+    if ( face->afm_data )+      T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );+#endif++    /* release unicode map, if any */+#if 0+    FT_FREE( face->unicode_map_rec.maps );+    face->unicode_map_rec.num_maps = 0;+    face->unicode_map              = NULL;+#endif++    face->root.family_name = NULL;+    face->root.style_name  = NULL;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    T1_Face_Init                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    The face object constructor.                                       */+  /*                                                                       */+  /* <Input>                                                               */+  /*    stream     ::  input stream where to load font data.               */+  /*                                                                       */+  /*    face_index :: The index of the font face in the resource.          */+  /*                                                                       */+  /*    num_params :: Number of additional generic parameters.  Ignored.   */+  /*                                                                       */+  /*    params     :: Additional generic parameters.  Ignored.             */+  /*                                                                       */+  /* <InOut>                                                               */+  /*    face       :: The face record to build.                            */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  T1_Face_Init( FT_Stream      stream,+                T1_Face        face,+                FT_Int         face_index,+                FT_Int         num_params,+                FT_Parameter*  params )+  {+    FT_Error            error;+    FT_Service_PsCMaps  psnames;+    PSAux_Service       psaux;+    T1_Font             type1 = &face->type1;+    PS_FontInfo         info = &type1->font_info;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+    FT_UNUSED( stream );+++    face->root.num_faces = 1;++    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );+    face->psnames = psnames;++    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),+                                           "psaux" );+    psaux = (PSAux_Service)face->psaux;++    face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),+                                              "pshinter" );++    /* open the tokenizer; this will also check the font format */+    error = T1_Open_Face( face );+    if ( error )+      goto Exit;++    /* if we just wanted to check the format, leave successfully now */+    if ( face_index < 0 )+      goto Exit;++    /* check the face index */+    if ( face_index > 0 )+    {+      FT_ERROR(( "T1_Face_Init: invalid face index\n" ));+      error = T1_Err_Invalid_Argument;+      goto Exit;+    }++    /* now load the font program into the face object */++    /* initialize the face object fields */++    /* set up root face fields */+    {+      FT_Face  root = (FT_Face)&face->root;+++      root->num_glyphs = type1->num_glyphs;+      root->face_index = 0;++      root->face_flags = FT_FACE_FLAG_SCALABLE    |+                         FT_FACE_FLAG_HORIZONTAL  |+                         FT_FACE_FLAG_GLYPH_NAMES |+                         FT_FACE_FLAG_HINTER;++      if ( info->is_fixed_pitch )+        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      if ( face->blend )+        root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;++      /* XXX: TODO -- add kerning with .afm support */+++      /* The following code to extract the family and the style is very   */+      /* simplistic and might get some things wrong.  For a full-featured */+      /* algorithm you might have a look at the whitepaper given at       */+      /*                                                                  */+      /*   http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */++      /* get style name -- be careful, some broken fonts only */+      /* have a `/FontName' dictionary entry!                 */+      root->family_name = info->family_name;+      root->style_name  = NULL;++      if ( root->family_name )+      {+        char*  full   = info->full_name;+        char*  family = root->family_name;+++        if ( full )+        {+          FT_Bool  the_same = TRUE;+++          while ( *full )+          {+            if ( *full == *family )+            {+              family++;+              full++;+            }+            else+            {+              if ( *full == ' ' || *full == '-' )+                full++;+              else if ( *family == ' ' || *family == '-' )+                family++;+              else+              {+                the_same = FALSE;++                if ( !*family )+                  root->style_name = full;+                break;+              }+            }+          }++          if ( the_same )+            root->style_name = (char *)"Regular";+        }+      }+      else+      {+        /* do we have a `/FontName'? */+        if ( type1->font_name )+          root->family_name = type1->font_name;+      }++      if ( !root->style_name )+      {+        if ( info->weight )+          root->style_name = info->weight;+        else+          /* assume `Regular' style because we don't know better */+          root->style_name = (char *)"Regular";+      }++      /* compute style flags */+      root->style_flags = 0;+      if ( info->italic_angle )+        root->style_flags |= FT_STYLE_FLAG_ITALIC;+      if ( info->weight )+      {+        if ( !ft_strcmp( info->weight, "Bold"  ) ||+             !ft_strcmp( info->weight, "Black" ) )+          root->style_flags |= FT_STYLE_FLAG_BOLD;+      }++      /* no embedded bitmap support */+      root->num_fixed_sizes = 0;+      root->available_sizes = 0;++      root->bbox.xMin =   type1->font_bbox.xMin            >> 16;+      root->bbox.yMin =   type1->font_bbox.yMin            >> 16;+      /* no `U' suffix here to 0xFFFF! */+      root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16;+      root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16;++      /* Set units_per_EM if we didn't set it in parse_font_matrix. */+      if ( !root->units_per_EM )+        root->units_per_EM = 1000;++      root->ascender  = (FT_Short)( root->bbox.yMax );+      root->descender = (FT_Short)( root->bbox.yMin );++      root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 );+      if ( root->height < root->ascender - root->descender )+        root->height = (FT_Short)( root->ascender - root->descender );++      /* now compute the maximum advance width */+      root->max_advance_width =+        (FT_Short)( root->bbox.xMax );+      {+        FT_Pos  max_advance;+++        error = T1_Compute_Max_Advance( face, &max_advance );++        /* in case of error, keep the standard width */+        if ( !error )+          root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance );+        else+          error = T1_Err_Ok;   /* clear error */+      }++      root->max_advance_height = root->height;++      root->underline_position  = (FT_Short)info->underline_position;+      root->underline_thickness = (FT_Short)info->underline_thickness;+    }++    {+      FT_Face  root = &face->root;+++      if ( psnames && psaux )+      {+        FT_CharMapRec    charmap;+        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;+        FT_CMap_Class    clazz;+++        charmap.face = root;++        /* first of all, try to synthesize a Unicode charmap */+        charmap.platform_id = TT_PLATFORM_MICROSOFT;+        charmap.encoding_id = TT_MS_ID_UNICODE_CS;+        charmap.encoding    = FT_ENCODING_UNICODE;++        error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );+        if ( error && FT_Err_No_Unicode_Glyph_Name != error )+          goto Exit;+        error = FT_Err_Ok;++        /* now, generate an Adobe Standard encoding when appropriate */+        charmap.platform_id = TT_PLATFORM_ADOBE;+        clazz               = NULL;++        switch ( type1->encoding_type )+        {+        case T1_ENCODING_TYPE_STANDARD:+          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;+          charmap.encoding_id = TT_ADOBE_ID_STANDARD;+          clazz               = cmap_classes->standard;+          break;++        case T1_ENCODING_TYPE_EXPERT:+          charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;+          charmap.encoding_id = TT_ADOBE_ID_EXPERT;+          clazz               = cmap_classes->expert;+          break;++        case T1_ENCODING_TYPE_ARRAY:+          charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;+          charmap.encoding_id = TT_ADOBE_ID_CUSTOM;+          clazz               = cmap_classes->custom;+          break;++        case T1_ENCODING_TYPE_ISOLATIN1:+          charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;+          charmap.encoding_id = TT_ADOBE_ID_LATIN_1;+          clazz               = cmap_classes->unicode;+          break;++        default:+          ;+        }++        if ( clazz )+          error = FT_CMap_New( clazz, NULL, &charmap, NULL );++#if 0+        /* Select default charmap */+        if (root->num_charmaps)+          root->charmap = root->charmaps[0];+#endif+      }+    }++  Exit:+    return error;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    T1_Driver_Init                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given Type 1 driver object.                          */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target driver object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  T1_Driver_Init( T1_Driver  driver )+  {+    FT_UNUSED( driver );++    return T1_Err_Ok;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    T1_Driver_Done                                                     */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Finalizes a given Type 1 driver.                                   */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target Type 1 driver.                    */+  /*                                                                       */+  FT_LOCAL_DEF( void )+  T1_Driver_Done( T1_Driver  driver )+  {+    FT_UNUSED( driver );+  }+++/* END */
+ src/type1/t1objs.h view
@@ -0,0 +1,171 @@+/***************************************************************************/+/*                                                                         */+/*  t1objs.h                                                               */+/*                                                                         */+/*    Type 1 objects manager (specification).                              */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2006 by                                     */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1OBJS_H__+#define __T1OBJS_H__+++#include <ft2build.h>+#include FT_INTERNAL_OBJECTS_H+#include FT_CONFIG_CONFIG_H+#include FT_INTERNAL_TYPE1_TYPES_H+++FT_BEGIN_HEADER+++  /* The following structures must be defined by the hinter */+  typedef struct T1_Size_Hints_   T1_Size_Hints;+  typedef struct T1_Glyph_Hints_  T1_Glyph_Hints;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_Driver                                                          */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 driver object.                                */+  /*                                                                       */+  typedef struct T1_DriverRec_   *T1_Driver;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_Size                                                            */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 size object.                                  */+  /*                                                                       */+  typedef struct T1_SizeRec_*  T1_Size;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_GlyphSlot                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 glyph slot object.                            */+  /*                                                                       */+  typedef struct T1_GlyphSlotRec_*  T1_GlyphSlot;+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_CharMap                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A handle to a Type 1 character mapping object.                     */+  /*                                                                       */+  /* <Note>                                                                */+  /*    The Type 1 format doesn't use a charmap but an encoding table.     */+  /*    The driver is responsible for making up charmap objects            */+  /*    corresponding to these tables.                                     */+  /*                                                                       */+  typedef struct T1_CharMapRec_*   T1_CharMap;+++  /*************************************************************************/+  /*                                                                       */+  /*                  HERE BEGINS THE TYPE1 SPECIFIC STUFF                 */+  /*                                                                       */+  /*************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_SizeRec                                                         */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Type 1 size record.                                                */+  /*                                                                       */+  typedef struct  T1_SizeRec_+  {+    FT_SizeRec  root;++  } T1_SizeRec;+++  FT_LOCAL( void )+  T1_Size_Done( T1_Size  size );++  FT_LOCAL( FT_Error )+  T1_Size_Request( T1_Size          size,+                   FT_Size_Request  req );++  FT_LOCAL( FT_Error )+  T1_Size_Init( T1_Size  size );+++  /*************************************************************************/+  /*                                                                       */+  /* <Type>                                                                */+  /*    T1_GlyphSlotRec                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Type 1 glyph slot record.                                          */+  /*                                                                       */+  typedef struct  T1_GlyphSlotRec_+  {+    FT_GlyphSlotRec  root;++    FT_Bool          hint;+    FT_Bool          scaled;++    FT_Int           max_points;+    FT_Int           max_contours;++    FT_Fixed         x_scale;+    FT_Fixed         y_scale;++  } T1_GlyphSlotRec;+++  FT_LOCAL( FT_Error )+  T1_Face_Init( FT_Stream      stream,+                T1_Face        face,+                FT_Int         face_index,+                FT_Int         num_params,+                FT_Parameter*  params );++  FT_LOCAL( void )+  T1_Face_Done( T1_Face  face );++  FT_LOCAL( FT_Error )+  T1_GlyphSlot_Init( T1_GlyphSlot  slot );++  FT_LOCAL( void )+  T1_GlyphSlot_Done( T1_GlyphSlot  slot );++  FT_LOCAL( FT_Error )+  T1_Driver_Init( T1_Driver  driver );++  FT_LOCAL( void )+  T1_Driver_Done( T1_Driver  driver );+++FT_END_HEADER++#endif /* __T1OBJS_H__ */+++/* END */
+ src/type1/t1parse.c view
@@ -0,0 +1,486 @@+/***************************************************************************/+/*                                                                         */+/*  t1parse.c                                                              */+/*                                                                         */+/*    Type 1 parser (body).                                                */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* The Type 1 parser is in charge of the following:                      */+  /*                                                                       */+  /*  - provide an implementation of a growing sequence of objects called  */+  /*    a `T1_Table' (used to build various tables needed by the loader).  */+  /*                                                                       */+  /*  - opening .pfb and .pfa files to extract their top-level and private */+  /*    dictionaries.                                                      */+  /*                                                                       */+  /*  - read numbers, arrays & strings from any dictionary.                */+  /*                                                                       */+  /* See `t1load.c' to see how data is loaded from the font file.          */+  /*                                                                       */+  /*************************************************************************/+++#include <ft2build.h>+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H++#include "t1parse.h"++#include "t1errors.h"+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t1parse+++  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+  /*****                                                               *****/+  /*****                   INPUT STREAM PARSER                         *****/+  /*****                                                               *****/+  /*************************************************************************/+  /*************************************************************************/+  /*************************************************************************/+++  /* see Adobe Technical Note 5040.Download_Fonts.pdf */++  static FT_Error+  read_pfb_tag( FT_Stream   stream,+                FT_UShort  *atag,+                FT_ULong   *asize )+  {+    FT_Error   error;+    FT_UShort  tag;+    FT_ULong   size;+++    *atag  = 0;+    *asize = 0;++    if ( !FT_READ_USHORT( tag ) )+    {+      if ( tag == 0x8001U || tag == 0x8002U )+      {+        if ( !FT_READ_ULONG_LE( size ) )+          *asize = size;+      }++      *atag = tag;+    }++    return error;+  }+++  static FT_Error+  check_type1_format( FT_Stream    stream,+                      const char*  header_string,+                      size_t       header_length )+  {+    FT_Error   error;+    FT_UShort  tag;+    FT_ULong   dummy;+++    if ( FT_STREAM_SEEK( 0 ) )+      goto Exit;++    error = read_pfb_tag( stream, &tag, &dummy );+    if ( error )+      goto Exit;++    /* We assume that the first segment in a PFB is always encoded as   */+    /* text.  This might be wrong (and the specification doesn't insist */+    /* on that), but we have never seen a counterexample.               */+    if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) )+      goto Exit;++    if ( !FT_FRAME_ENTER( header_length ) )+    {+      error = T1_Err_Ok;++      if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 )+        error = T1_Err_Unknown_File_Format;++      FT_FRAME_EXIT();+    }++  Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_New_Parser( T1_Parser      parser,+                 FT_Stream      stream,+                 FT_Memory      memory,+                 PSAux_Service  psaux )+  {+    FT_Error   error;+    FT_UShort  tag;+    FT_ULong   size;+++    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );++    parser->stream       = stream;+    parser->base_len     = 0;+    parser->base_dict    = 0;+    parser->private_len  = 0;+    parser->private_dict = 0;+    parser->in_pfb       = 0;+    parser->in_memory    = 0;+    parser->single_block = 0;++    /* check the header format */+    error = check_type1_format( stream, "%!PS-AdobeFont", 14 );+    if ( error )+    {+      if ( error != T1_Err_Unknown_File_Format )+        goto Exit;++      error = check_type1_format( stream, "%!FontType", 10 );+      if ( error )+      {+        FT_TRACE2(( "[not a Type1 font]\n" ));+        goto Exit;+      }+    }++    /******************************************************************/+    /*                                                                */+    /* Here a short summary of what is going on:                      */+    /*                                                                */+    /*   When creating a new Type 1 parser, we try to locate and load */+    /*   the base dictionary if this is possible (i.e., for PFB       */+    /*   files).  Otherwise, we load the whole font into memory.      */+    /*                                                                */+    /*   When `loading' the base dictionary, we only setup pointers   */+    /*   in the case of a memory-based stream.  Otherwise, we         */+    /*   allocate and load the base dictionary in it.                 */+    /*                                                                */+    /*   parser->in_pfb is set if we are in a binary (`.pfb') font.   */+    /*   parser->in_memory is set if we have a memory stream.         */+    /*                                                                */++    /* try to compute the size of the base dictionary;     */+    /* look for a Postscript binary file tag, i.e., 0x8001 */+    if ( FT_STREAM_SEEK( 0L ) )+      goto Exit;++    error = read_pfb_tag( stream, &tag, &size );+    if ( error )+      goto Exit;++    if ( tag != 0x8001U )+    {+      /* assume that this is a PFA file for now; an error will */+      /* be produced later when more things are checked        */+      if ( FT_STREAM_SEEK( 0L ) )+        goto Exit;+      size = stream->size;+    }+    else+      parser->in_pfb = 1;++    /* now, try to load `size' bytes of the `base' dictionary we */+    /* found previously                                          */++    /* if it is a memory-based resource, set up pointers */+    if ( !stream->read )+    {+      parser->base_dict = (FT_Byte*)stream->base + stream->pos;+      parser->base_len  = size;+      parser->in_memory = 1;++      /* check that the `size' field is valid */+      if ( FT_STREAM_SKIP( size ) )+        goto Exit;+    }+    else+    {+      /* read segment in memory -- this is clumsy, but so does the format */+      if ( FT_ALLOC( parser->base_dict, size )       ||+           FT_STREAM_READ( parser->base_dict, size ) )+        goto Exit;+      parser->base_len = size;+    }++    parser->root.base   = parser->base_dict;+    parser->root.cursor = parser->base_dict;+    parser->root.limit  = parser->root.cursor + parser->base_len;++  Exit:+    if ( error && !parser->in_memory )+      FT_FREE( parser->base_dict );++    return error;+  }+++  FT_LOCAL_DEF( void )+  T1_Finalize_Parser( T1_Parser  parser )+  {+    FT_Memory  memory = parser->root.memory;+++    /* always free the private dictionary */+    FT_FREE( parser->private_dict );++    /* free the base dictionary only when we have a disk stream */+    if ( !parser->in_memory )+      FT_FREE( parser->base_dict );++    parser->root.funcs.done( &parser->root );+  }+++  FT_LOCAL_DEF( FT_Error )+  T1_Get_Private_Dict( T1_Parser      parser,+                       PSAux_Service  psaux )+  {+    FT_Stream  stream = parser->stream;+    FT_Memory  memory = parser->root.memory;+    FT_Error   error  = T1_Err_Ok;+    FT_ULong   size;+++    if ( parser->in_pfb )+    {+      /* in the case of the PFB format, the private dictionary can be  */+      /* made of several segments.  We thus first read the number of   */+      /* segments to compute the total size of the private dictionary  */+      /* then re-read them into memory.                                */+      FT_Long    start_pos = FT_STREAM_POS();+      FT_UShort  tag;+++      parser->private_len = 0;+      for (;;)+      {+        error = read_pfb_tag( stream, &tag, &size );+        if ( error )+          goto Fail;++        if ( tag != 0x8002U )+          break;++        parser->private_len += size;++        if ( FT_STREAM_SKIP( size ) )+          goto Fail;+      }++      /* Check that we have a private dictionary there */+      /* and allocate private dictionary buffer        */+      if ( parser->private_len == 0 )+      {+        FT_ERROR(( "T1_Get_Private_Dict:"+                   " invalid private dictionary section\n" ));+        error = T1_Err_Invalid_File_Format;+        goto Fail;+      }++      if ( FT_STREAM_SEEK( start_pos )                           ||+           FT_ALLOC( parser->private_dict, parser->private_len ) )+        goto Fail;++      parser->private_len = 0;+      for (;;)+      {+        error = read_pfb_tag( stream, &tag, &size );+        if ( error || tag != 0x8002U )+        {+          error = T1_Err_Ok;+          break;+        }++        if ( FT_STREAM_READ( parser->private_dict + parser->private_len,+                             size ) )+          goto Fail;++        parser->private_len += size;+      }+    }+    else+    {+      /* We have already `loaded' the whole PFA font file into memory; */+      /* if this is a memory resource, allocate a new block to hold    */+      /* the private dict.  Otherwise, simply overwrite into the base  */+      /* dictionary block in the heap.                                 */++      /* first of all, look at the `eexec' keyword */+      FT_Byte*  cur   = parser->base_dict;+      FT_Byte*  limit = cur + parser->base_len;+      FT_Byte   c;+++    Again:+      for (;;)+      {+        c = cur[0];+        if ( c == 'e' && cur + 9 < limit )  /* 9 = 5 letters for `eexec' + */+                                            /* newline + 4 chars           */+        {+          if ( cur[1] == 'e' &&+               cur[2] == 'x' &&+               cur[3] == 'e' &&+               cur[4] == 'c' )+            break;+        }+        cur++;+        if ( cur >= limit )+        {+          FT_ERROR(( "T1_Get_Private_Dict:"+                     " could not find `eexec' keyword\n" ));+          error = T1_Err_Invalid_File_Format;+          goto Exit;+        }+      }++      /* check whether `eexec' was real -- it could be in a comment */+      /* or string (as e.g. in u003043t.gsf from ghostscript)       */++      parser->root.cursor = parser->base_dict;+      parser->root.limit  = cur + 9;++      cur   = parser->root.cursor;+      limit = parser->root.limit;++      while ( cur < limit )+      {+        if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 )+          goto Found;++        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          break;+        T1_Skip_Spaces  ( parser );+        cur = parser->root.cursor;+      }++      /* we haven't found the correct `eexec'; go back and continue */+      /* searching                                                  */++      cur   = limit;+      limit = parser->base_dict + parser->base_len;+      goto Again;++      /* now determine where to write the _encrypted_ binary private  */+      /* dictionary.  We overwrite the base dictionary for disk-based */+      /* resources and allocate a new block otherwise                 */++    Found:+      parser->root.limit = parser->base_dict + parser->base_len;++      T1_Skip_PS_Token( parser );+      cur = parser->root.cursor;++      /* according to the Type1 spec, the first cipher byte must not be  */+      /* an ASCII whitespace character code (blank, tab, carriage return */+      /* or line feed).  We have seen Type 1 fonts with two line feed    */+      /* characters...  So skip now all whitespace character codes.      */+      while ( cur < limit       &&+              ( *cur == ' '  ||+                *cur == '\t' || +                *cur == '\r' ||+                *cur == '\n' ) )+        ++cur;+      if ( cur >= limit )+      {+        FT_ERROR(( "T1_Get_Private_Dict:"+                   " `eexec' not properly terminated\n" ));+        error = T1_Err_Invalid_File_Format;+        goto Exit;+      }++      size = parser->base_len - ( cur - parser->base_dict );++      if ( parser->in_memory )+      {+        /* note that we allocate one more byte to put a terminating `0' */+        if ( FT_ALLOC( parser->private_dict, size + 1 ) )+          goto Fail;+        parser->private_len = size;+      }+      else+      {+        parser->single_block = 1;+        parser->private_dict = parser->base_dict;+        parser->private_len  = size;+        parser->base_dict    = 0;+        parser->base_len     = 0;+      }++      /* now determine whether the private dictionary is encoded in binary */+      /* or hexadecimal ASCII format -- decode it accordingly              */++      /* we need to access the next 4 bytes (after the final \r following */+      /* the `eexec' keyword); if they all are hexadecimal digits, then   */+      /* we have a case of ASCII storage                                  */++      if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&+           ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )+      {+        /* ASCII hexadecimal encoding */+        FT_Long  len;+++        parser->root.cursor = cur;+        (void)psaux->ps_parser_funcs->to_bytes( &parser->root,+                                                parser->private_dict,+                                                parser->private_len,+                                                &len,+                                                0 );+        parser->private_len = len;++        /* put a safeguard */+        parser->private_dict[len] = '\0';+      }+      else+        /* binary encoding -- copy the private dict */+        FT_MEM_MOVE( parser->private_dict, cur, size );+    }++    /* we now decrypt the encoded binary private dictionary */+    psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U );++    /* replace the four random bytes at the beginning with whitespace */+    parser->private_dict[0] = ' ';+    parser->private_dict[1] = ' ';+    parser->private_dict[2] = ' ';+    parser->private_dict[3] = ' ';++    parser->root.base   = parser->private_dict;+    parser->root.cursor = parser->private_dict;+    parser->root.limit  = parser->root.cursor + parser->private_len;++  Fail:+  Exit:+    return error;+  }+++/* END */
+ src/type1/t1parse.h view
@@ -0,0 +1,135 @@+/***************************************************************************/+/*                                                                         */+/*  t1parse.h                                                              */+/*                                                                         */+/*    Type 1 parser (specification).                                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2008 by                               */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T1PARSE_H__+#define __T1PARSE_H__+++#include <ft2build.h>+#include FT_INTERNAL_TYPE1_TYPES_H+#include FT_INTERNAL_STREAM_H+++FT_BEGIN_HEADER+++  /*************************************************************************/+  /*                                                                       */+  /* <Struct>                                                              */+  /*    T1_ParserRec                                                       */+  /*                                                                       */+  /* <Description>                                                         */+  /*    A PS_ParserRec is an object used to parse a Type 1 fonts very      */+  /*    quickly.                                                           */+  /*                                                                       */+  /* <Fields>                                                              */+  /*    root         :: The root parser.                                   */+  /*                                                                       */+  /*    stream       :: The current input stream.                          */+  /*                                                                       */+  /*    base_dict    :: A pointer to the top-level dictionary.             */+  /*                                                                       */+  /*    base_len     :: The length in bytes of the top dictionary.         */+  /*                                                                       */+  /*    private_dict :: A pointer to the private dictionary.               */+  /*                                                                       */+  /*    private_len  :: The length in bytes of the private dictionary.     */+  /*                                                                       */+  /*    in_pfb       :: A boolean.  Indicates that we are handling a PFB   */+  /*                    file.                                              */+  /*                                                                       */+  /*    in_memory    :: A boolean.  Indicates a memory-based stream.       */+  /*                                                                       */+  /*    single_block :: A boolean.  Indicates that the private dictionary  */+  /*                    is stored in lieu of the base dictionary.          */+  /*                                                                       */+  typedef struct  T1_ParserRec_+  {+    PS_ParserRec  root;+    FT_Stream     stream;++    FT_Byte*      base_dict;+    FT_ULong      base_len;++    FT_Byte*      private_dict;+    FT_ULong      private_len;++    FT_Bool       in_pfb;+    FT_Bool       in_memory;+    FT_Bool       single_block;++  } T1_ParserRec, *T1_Parser;+++#define T1_Add_Table( p, i, o, l )  (p)->funcs.add( (p), i, o, l )+#define T1_Done_Table( p )          \+          do                        \+          {                         \+            if ( (p)->funcs.done )  \+              (p)->funcs.done( p ); \+          } while ( 0 )+#define T1_Release_Table( p )          \+          do                           \+          {                            \+            if ( (p)->funcs.release )  \+              (p)->funcs.release( p ); \+          } while ( 0 )+++#define T1_Skip_Spaces( p )    (p)->root.funcs.skip_spaces( &(p)->root )+#define T1_Skip_PS_Token( p )  (p)->root.funcs.skip_PS_token( &(p)->root )++#define T1_ToInt( p )       (p)->root.funcs.to_int( &(p)->root )+#define T1_ToFixed( p, t )  (p)->root.funcs.to_fixed( &(p)->root, t )++#define T1_ToCoordArray( p, m, c )                           \+          (p)->root.funcs.to_coord_array( &(p)->root, m, c )+#define T1_ToFixedArray( p, m, f, t )                           \+          (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )+#define T1_ToToken( p, t )                          \+          (p)->root.funcs.to_token( &(p)->root, t )+#define T1_ToTokenArray( p, t, m, c )                           \+          (p)->root.funcs.to_token_array( &(p)->root, t, m, c )++#define T1_Load_Field( p, f, o, m, pf )                         \+          (p)->root.funcs.load_field( &(p)->root, f, o, m, pf )++#define T1_Load_Field_Table( p, f, o, m, pf )                         \+          (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf )+++  FT_LOCAL( FT_Error )+  T1_New_Parser( T1_Parser      parser,+                 FT_Stream      stream,+                 FT_Memory      memory,+                 PSAux_Service  psaux );++  FT_LOCAL( FT_Error )+  T1_Get_Private_Dict( T1_Parser      parser,+                       PSAux_Service  psaux );++  FT_LOCAL( void )+  T1_Finalize_Parser( T1_Parser  parser );+++FT_END_HEADER++#endif /* __T1PARSE_H__ */+++/* END */
+ src/type1/t1tokens.h view
@@ -0,0 +1,143 @@+/***************************************************************************/+/*                                                                         */+/*  t1tokens.h                                                             */+/*                                                                         */+/*    Type 1 tokenizer (specification).                                    */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_FontInfoRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_INFO++  T1_FIELD_STRING( "version",            version,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_STRING( "Notice",             notice,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_STRING( "FullName",           full_name,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_STRING( "FamilyName",         family_name,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_STRING( "Weight",             weight,+                   T1_FIELD_DICT_FONTDICT )++  /* we use pointers to detect modifications made by synthetic fonts */+  T1_FIELD_NUM   ( "ItalicAngle",        italic_angle,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_NUM   ( "UnderlinePosition",  underline_position,+                   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness,+                   T1_FIELD_DICT_FONTDICT )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_FontExtraRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_EXTRA++  T1_FIELD_NUM   ( "FSType", fs_type,+                   T1_FIELD_DICT_FONTDICT )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_PrivateRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_PRIVATE++  T1_FIELD_NUM       ( "UniqueID",         unique_id,+                       T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM       ( "lenIV",            lenIV,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM       ( "LanguageGroup",    language_group,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM       ( "password",         password,+                       T1_FIELD_DICT_PRIVATE )++  T1_FIELD_FIXED_1000( "BlueScale",        blue_scale,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM       ( "BlueShift",        blue_shift,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM       ( "BlueFuzz",         blue_fuzz,+                       T1_FIELD_DICT_PRIVATE )++  T1_FIELD_NUM_TABLE ( "BlueValues",       blue_values,        14,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE ( "OtherBlues",       other_blues,        10,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE ( "FamilyBlues",      family_blues,       14,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10,+                       T1_FIELD_DICT_PRIVATE )++  T1_FIELD_NUM_TABLE2( "StdHW",            standard_width,      1,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE2( "StdVW",            standard_height,     1,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE2( "MinFeature",       min_feature,         2,+                       T1_FIELD_DICT_PRIVATE )++  T1_FIELD_NUM_TABLE ( "StemSnapH",        snap_widths,        12,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM_TABLE ( "StemSnapV",        snap_heights,       12,+                       T1_FIELD_DICT_PRIVATE )++  T1_FIELD_FIXED     ( "ExpansionFactor",  expansion_factor,+                       T1_FIELD_DICT_PRIVATE )+  T1_FIELD_BOOL      ( "ForceBold",        force_bold,+                       T1_FIELD_DICT_PRIVATE )+                         ++#undef  FT_STRUCTURE+#define FT_STRUCTURE  T1_FontRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_DICT++  T1_FIELD_KEY  ( "FontName",    font_name,    T1_FIELD_DICT_FONTDICT )+  T1_FIELD_NUM  ( "PaintType",   paint_type,   T1_FIELD_DICT_FONTDICT )+  T1_FIELD_NUM  ( "FontType",    font_type,    T1_FIELD_DICT_FONTDICT )+  T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  FT_BBox+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_BBOX++  T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT )+++#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT++#undef  FT_STRUCTURE+#define FT_STRUCTURE  T1_FaceRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FACE++  T1_FIELD_NUM( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE )+  T1_FIELD_NUM( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE )+++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_BlendRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_BLEND++  T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector,+                      T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT )+++#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */+++/* END */
+ src/type1/type1.c view
@@ -0,0 +1,33 @@+/***************************************************************************/+/*                                                                         */+/*  type1.c                                                                */+/*                                                                         */+/*    FreeType Type 1 driver component (body only).                        */+/*                                                                         */+/*  Copyright 1996-2001 by                                                 */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "t1parse.c"+#include "t1load.c"+#include "t1objs.c"+#include "t1driver.c"+#include "t1gload.c"++#ifndef T1_CONFIG_OPTION_NO_AFM+#include "t1afm.c"+#endif+++/* END */
+ src/type42/t42drivr.c view
@@ -0,0 +1,246 @@+/***************************************************************************/+/*                                                                         */+/*  t42drivr.c                                                             */+/*                                                                         */+/*    High-level Type 42 driver interface (body).                          */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2006, 2007, 2009 by Roberto Alameda.       */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This driver implements Type42 fonts as described in the               */+  /* Technical Note #5012 from Adobe, with these limitations:              */+  /*                                                                       */+  /* 1) CID Fonts are not currently supported.                             */+  /* 2) Incremental fonts making use of the GlyphDirectory keyword         */+  /*    will be loaded, but the rendering will be using the TrueType       */+  /*    tables.                                                            */+  /* 3) As for Type1 fonts, CDevProc is not supported.                     */+  /* 4) The Metrics dictionary is not supported.                           */+  /* 5) AFM metrics are not supported.                                     */+  /*                                                                       */+  /* In other words, this driver supports Type42 fonts derived from        */+  /* TrueType fonts in a non-CID manner, as done by usual conversion       */+  /* programs.                                                             */+  /*                                                                       */+  /*************************************************************************/+++#include "t42drivr.h"+#include "t42objs.h"+#include "t42error.h"+#include FT_INTERNAL_DEBUG_H++#include FT_SERVICE_XFREE86_NAME_H+#include FT_SERVICE_GLYPH_DICT_H+#include FT_SERVICE_POSTSCRIPT_NAME_H+#include FT_SERVICE_POSTSCRIPT_INFO_H++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t42+++  /*+   *+   *  GLYPH DICT SERVICE+   *+   */++  static FT_Error+  t42_get_glyph_name( T42_Face    face,+                      FT_UInt     glyph_index,+                      FT_Pointer  buffer,+                      FT_UInt     buffer_max )+  {+    FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max );++    return T42_Err_Ok;+  }+++  static FT_UInt+  t42_get_name_index( T42_Face    face,+                      FT_String*  glyph_name )+  {+    FT_Int      i;+    FT_String*  gname;+++    for ( i = 0; i < face->type1.num_glyphs; i++ )+    {+      gname = face->type1.glyph_names[i];++      if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) )+        return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] );+    }++    return 0;+  }+++  static const FT_Service_GlyphDictRec  t42_service_glyph_dict =+  {+    (FT_GlyphDict_GetNameFunc)  t42_get_glyph_name,+    (FT_GlyphDict_NameIndexFunc)t42_get_name_index+  };+++  /*+   *+   *  POSTSCRIPT NAME SERVICE+   *+   */++  static const char*+  t42_get_ps_font_name( T42_Face  face )+  {+    return (const char*)face->type1.font_name;+  }+++  static const FT_Service_PsFontNameRec  t42_service_ps_font_name =+  {+    (FT_PsName_GetFunc)t42_get_ps_font_name+  };+++  /*+   *+   *  POSTSCRIPT INFO SERVICE+   *+   */++  static FT_Error+  t42_ps_get_font_info( FT_Face          face,+                        PS_FontInfoRec*  afont_info )+  {+    *afont_info = ((T42_Face)face)->type1.font_info;++    return T42_Err_Ok;+  }+++  static FT_Error+  t42_ps_get_font_extra( FT_Face           face,+                         PS_FontExtraRec*  afont_extra )+  {+    *afont_extra = ((T42_Face)face)->type1.font_extra;++    return T42_Err_Ok;+  }+++  static FT_Int+  t42_ps_has_glyph_names( FT_Face  face )+  {+    FT_UNUSED( face );++    return 1;+  }+++  static FT_Error+  t42_ps_get_font_private( FT_Face         face,+                           PS_PrivateRec*  afont_private )+  {+    *afont_private = ((T42_Face)face)->type1.private_dict;++    return T42_Err_Ok;+  }+++  static const FT_Service_PsInfoRec  t42_service_ps_info =+  {+    (PS_GetFontInfoFunc)   t42_ps_get_font_info,+    (PS_GetFontExtraFunc)   t42_ps_get_font_extra,+    (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names,+    (PS_GetFontPrivateFunc)t42_ps_get_font_private+  };+++  /*+   *+   *  SERVICE LIST+   *+   */++  static const FT_ServiceDescRec  t42_services[] =+  {+    { FT_SERVICE_ID_GLYPH_DICT,           &t42_service_glyph_dict },+    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name },+    { FT_SERVICE_ID_POSTSCRIPT_INFO,      &t42_service_ps_info },+    { FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_TYPE_42 },+    { NULL, NULL }+  };+++  static FT_Module_Interface+  T42_Get_Interface( FT_Driver         driver,+                     const FT_String*  t42_interface )+  {+    FT_UNUSED( driver );++    return ft_service_list_lookup( t42_services, t42_interface );+  }+++  const FT_Driver_ClassRec  t42_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER       |+      FT_MODULE_DRIVER_SCALABLE   |+#ifdef TT_USE_BYTECODE_INTERPRETER+      FT_MODULE_DRIVER_HAS_HINTER,+#else+      0,+#endif++      sizeof ( T42_DriverRec ),++      "type42",+      0x10000L,+      0x20000L,++      0,    /* format interface */++      (FT_Module_Constructor)T42_Driver_Init,+      (FT_Module_Destructor) T42_Driver_Done,+      (FT_Module_Requester)  T42_Get_Interface,+    },++    sizeof ( T42_FaceRec ),+    sizeof ( T42_SizeRec ),+    sizeof ( T42_GlyphSlotRec ),++    (FT_Face_InitFunc)        T42_Face_Init,+    (FT_Face_DoneFunc)        T42_Face_Done,+    (FT_Size_InitFunc)        T42_Size_Init,+    (FT_Size_DoneFunc)        T42_Size_Done,+    (FT_Slot_InitFunc)        T42_GlyphSlot_Init,+    (FT_Slot_DoneFunc)        T42_GlyphSlot_Done,++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    (FT_Slot_LoadFunc)        T42_GlyphSlot_Load,++    (FT_Face_GetKerningFunc)  0,+    (FT_Face_AttachFunc)      0,++    (FT_Face_GetAdvancesFunc) 0,+    (FT_Size_RequestFunc)     T42_Size_Request,+    (FT_Size_SelectFunc)      T42_Size_Select+  };+++/* END */
+ src/type42/t42drivr.h view
@@ -0,0 +1,42 @@+/***************************************************************************/+/*                                                                         */+/*  t42drivr.h                                                             */+/*                                                                         */+/*    High-level Type 42 driver interface (specification).                 */+/*                                                                         */+/*  Copyright 2002 by Roberto Alameda.                                     */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T42DRIVR_H__+#define __T42DRIVR_H__+++#include <ft2build.h>+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif +++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  t42_driver_class;+++FT_END_HEADER+++#endif /* __T42DRIVR_H__ */+++/* END */
+ src/type42/t42error.h view
@@ -0,0 +1,40 @@+/***************************************************************************/+/*                                                                         */+/*  t42error.h                                                             */+/*                                                                         */+/*    Type 42 error codes (specification only).                            */+/*                                                                         */+/*  Copyright 2002, 2003 by                                                */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the Type 42 error enumeration constants.  */+  /*                                                                       */+  /*************************************************************************/++#ifndef __T42ERROR_H__+#define __T42ERROR_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  T42_Err_+#define FT_ERR_BASE    FT_Mod_Err_Type42++#include FT_ERRORS_H++#endif /* __T42ERROR_H__ */+++/* END */
+ src/type42/t42objs.c view
@@ -0,0 +1,652 @@+/***************************************************************************/+/*                                                                         */+/*  t42objs.c                                                              */+/*                                                                         */+/*    Type 42 objects manager (body).                                      */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009               */+/*  by Roberto Alameda.                                                    */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "t42objs.h"+#include "t42parse.h"+#include "t42error.h"+#include FT_INTERNAL_DEBUG_H+#include FT_LIST_H+#include FT_TRUETYPE_IDS_H +++#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t42+++  static FT_Error+  T42_Open_Face( T42_Face  face )+  {+    T42_LoaderRec  loader;+    T42_Parser     parser;+    T1_Font        type1 = &face->type1;+    FT_Memory      memory = face->root.memory;+    FT_Error       error;++    PSAux_Service  psaux  = (PSAux_Service)face->psaux;+++    t42_loader_init( &loader, face );++    parser = &loader.parser;++    if ( FT_ALLOC( face->ttf_data, 12 ) )+      goto Exit;++    error = t42_parser_init( parser,+                             face->root.stream,+                             memory,+                             psaux);+    if ( error )+      goto Exit;++    error = t42_parse_dict( face, &loader,+                            parser->base_dict, parser->base_len );+    if ( error )+      goto Exit;++    if ( type1->font_type != 42 )+    {+      error = T42_Err_Unknown_File_Format;+      goto Exit;+    }++    /* now, propagate the charstrings and glyphnames tables */+    /* to the Type1 data                                    */+    type1->num_glyphs = loader.num_glyphs;++    if ( !loader.charstrings.init )+    {+      FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" ));+      error = T42_Err_Invalid_File_Format;+    }++    loader.charstrings.init  = 0;+    type1->charstrings_block = loader.charstrings.block;+    type1->charstrings       = loader.charstrings.elements;+    type1->charstrings_len   = loader.charstrings.lengths;++    /* we copy the glyph names `block' and `elements' fields; */+    /* the `lengths' field must be released later             */+    type1->glyph_names_block    = loader.glyph_names.block;+    type1->glyph_names          = (FT_String**)loader.glyph_names.elements;+    loader.glyph_names.block    = 0;+    loader.glyph_names.elements = 0;++    /* we must now build type1.encoding when we have a custom array */+    if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )+    {+      FT_Int    charcode, idx, min_char, max_char;+      FT_Byte*  char_name;+      FT_Byte*  glyph_name;+++      /* OK, we do the following: for each element in the encoding   */+      /* table, look up the index of the glyph having the same name  */+      /* as defined in the CharStrings array.                        */+      /* The index is then stored in type1.encoding.char_index, and  */+      /* the name in type1.encoding.char_name                        */++      min_char = 0;+      max_char = 0;++      charcode = 0;+      for ( ; charcode < loader.encoding_table.max_elems; charcode++ )+      {+        type1->encoding.char_index[charcode] = 0;+        type1->encoding.char_name [charcode] = (char *)".notdef";++        char_name = loader.encoding_table.elements[charcode];+        if ( char_name )+          for ( idx = 0; idx < type1->num_glyphs; idx++ )+          {+            glyph_name = (FT_Byte*)type1->glyph_names[idx];+            if ( ft_strcmp( (const char*)char_name,+                            (const char*)glyph_name ) == 0 )+            {+              type1->encoding.char_index[charcode] = (FT_UShort)idx;+              type1->encoding.char_name [charcode] = (char*)glyph_name;++              /* Change min/max encoded char only if glyph name is */+              /* not /.notdef                                      */+              if ( ft_strcmp( (const char*)".notdef",+                              (const char*)glyph_name ) != 0 )+              {+                if ( charcode < min_char )+                  min_char = charcode;+                if ( charcode >= max_char )+                  max_char = charcode + 1;+              }+              break;+            }+          }+      }++      type1->encoding.code_first = min_char;+      type1->encoding.code_last  = max_char;+      type1->encoding.num_chars  = loader.num_chars;+    }++  Exit:+    t42_loader_done( &loader );+    return error;+  }+++  /***************** Driver Functions *************/+++  FT_LOCAL_DEF( FT_Error )+  T42_Face_Init( FT_Stream      stream,+                 T42_Face       face,+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    FT_Error            error;+    FT_Service_PsCMaps  psnames;+    PSAux_Service       psaux;+    FT_Face             root  = (FT_Face)&face->root;+    T1_Font             type1 = &face->type1;+    PS_FontInfo         info  = &type1->font_info;++    FT_UNUSED( num_params );+    FT_UNUSED( params );+    FT_UNUSED( face_index );+    FT_UNUSED( stream );+++    face->ttf_face       = NULL;+    face->root.num_faces = 1;++    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );+    face->psnames = psnames;++    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),+                                           "psaux" );+    psaux = (PSAux_Service)face->psaux;++    /* open the tokenizer, this will also check the font format */+    error = T42_Open_Face( face );+    if ( error )+      goto Exit;++    /* if we just wanted to check the format, leave successfully now */+    if ( face_index < 0 )+      goto Exit;++    /* check the face index */+    if ( face_index > 0 )+    {+      FT_ERROR(( "T42_Face_Init: invalid face index\n" ));+      error = T42_Err_Invalid_Argument;+      goto Exit;+    }++    /* Now load the font program into the face object */++    /* Init the face object fields */+    /* Now set up root face fields */++    root->num_glyphs   = type1->num_glyphs;+    root->num_charmaps = 0;+    root->face_index   = 0;++    root->face_flags = FT_FACE_FLAG_SCALABLE    |+                       FT_FACE_FLAG_HORIZONTAL  |+                       FT_FACE_FLAG_GLYPH_NAMES;++    if ( info->is_fixed_pitch )+      root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++    /* We only set this flag if we have the patented bytecode interpreter. */+    /* There are no known `tricky' Type42 fonts that could be loaded with  */+    /* the unpatented interpreter.                                         */+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER+    root->face_flags |= FT_FACE_FLAG_HINTER;+#endif++    /* XXX: TODO -- add kerning with .afm support */++    /* get style name -- be careful, some broken fonts only */+    /* have a `/FontName' dictionary entry!                 */+    root->family_name = info->family_name;+    /* assume "Regular" style if we don't know better */+    root->style_name = (char *)"Regular";+    if ( root->family_name )+    {+      char*  full   = info->full_name;+      char*  family = root->family_name;+++      if ( full )+      {+        while ( *full )+        {+          if ( *full == *family )+          {+            family++;+            full++;+          }+          else+          {+            if ( *full == ' ' || *full == '-' )+              full++;+            else if ( *family == ' ' || *family == '-' )+              family++;+            else+            {+              if ( !*family )+                root->style_name = full;+              break;+            }+          }+        }+      }+    }+    else+    {+      /* do we have a `/FontName'? */+      if ( type1->font_name )+        root->family_name = type1->font_name;+    }++    /* no embedded bitmap support */+    root->num_fixed_sizes = 0;+    root->available_sizes = 0;++    /* Load the TTF font embedded in the T42 font */+    {+      FT_Open_Args  args;+++      args.flags       = FT_OPEN_MEMORY;+      args.memory_base = face->ttf_data;+      args.memory_size = face->ttf_size;++      if ( num_params )+      {+        args.flags     |= FT_OPEN_PARAMS;+        args.num_params = num_params;+        args.params     = params;+      }++      error = FT_Open_Face( FT_FACE_LIBRARY( face ),+                            &args, 0, &face->ttf_face );+    }++    if ( error )+      goto Exit;++    FT_Done_Size( face->ttf_face->size );++    /* Ignore info in FontInfo dictionary and use the info from the  */+    /* loaded TTF font.  The PostScript interpreter also ignores it. */+    root->bbox         = face->ttf_face->bbox;+    root->units_per_EM = face->ttf_face->units_per_EM;++    root->ascender  = face->ttf_face->ascender;+    root->descender = face->ttf_face->descender;+    root->height    = face->ttf_face->height;++    root->max_advance_width  = face->ttf_face->max_advance_width;+    root->max_advance_height = face->ttf_face->max_advance_height;++    root->underline_position  = (FT_Short)info->underline_position;+    root->underline_thickness = (FT_Short)info->underline_thickness;++    /* compute style flags */+    root->style_flags = 0;+    if ( info->italic_angle )+      root->style_flags |= FT_STYLE_FLAG_ITALIC;++    if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )+      root->style_flags |= FT_STYLE_FLAG_BOLD;++    if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )+      root->face_flags |= FT_FACE_FLAG_VERTICAL;++    {+      if ( psnames && psaux )+      {+        FT_CharMapRec    charmap;+        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;+        FT_CMap_Class    clazz;+++        charmap.face = root;++        /* first of all, try to synthesize a Unicode charmap */+        charmap.platform_id = TT_PLATFORM_MICROSOFT;+        charmap.encoding_id = TT_MS_ID_UNICODE_CS;+        charmap.encoding    = FT_ENCODING_UNICODE;++        error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );+        if ( error && FT_Err_No_Unicode_Glyph_Name != error )+          goto Exit;+        error = FT_Err_Ok;++        /* now, generate an Adobe Standard encoding when appropriate */+        charmap.platform_id = TT_PLATFORM_ADOBE;+        clazz               = NULL;++        switch ( type1->encoding_type )+        {+        case T1_ENCODING_TYPE_STANDARD:+          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;+          charmap.encoding_id = TT_ADOBE_ID_STANDARD;+          clazz               = cmap_classes->standard;+          break;++        case T1_ENCODING_TYPE_EXPERT:+          charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;+          charmap.encoding_id = TT_ADOBE_ID_EXPERT;+          clazz               = cmap_classes->expert;+          break;++        case T1_ENCODING_TYPE_ARRAY:+          charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;+          charmap.encoding_id = TT_ADOBE_ID_CUSTOM;+          clazz               = cmap_classes->custom;+          break;++        case T1_ENCODING_TYPE_ISOLATIN1:+          charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;+          charmap.encoding_id = TT_ADOBE_ID_LATIN_1;+          clazz               = cmap_classes->unicode;+          break;++        default:+          ;+        }++        if ( clazz )+          error = FT_CMap_New( clazz, NULL, &charmap, NULL );++#if 0+        /* Select default charmap */+        if ( root->num_charmaps )+          root->charmap = root->charmaps[0];+#endif+      }+    }+  Exit:+    return error;+  }+++  FT_LOCAL_DEF( void )+  T42_Face_Done( T42_Face  face )+  {+    T1_Font      type1;+    PS_FontInfo  info;+    FT_Memory    memory;+++    if ( !face )+      return;++    type1  = &face->type1;+    info   = &type1->font_info;+    memory = face->root.memory;++    /* delete internal ttf face prior to freeing face->ttf_data */+    if ( face->ttf_face )+      FT_Done_Face( face->ttf_face );++    /* release font info strings */+    FT_FREE( info->version );+    FT_FREE( info->notice );+    FT_FREE( info->full_name );+    FT_FREE( info->family_name );+    FT_FREE( info->weight );++    /* release top dictionary */+    FT_FREE( type1->charstrings_len );+    FT_FREE( type1->charstrings );+    FT_FREE( type1->glyph_names );++    FT_FREE( type1->charstrings_block );+    FT_FREE( type1->glyph_names_block );++    FT_FREE( type1->encoding.char_index );+    FT_FREE( type1->encoding.char_name );+    FT_FREE( type1->font_name );++    FT_FREE( face->ttf_data );++#if 0+    /* release afm data if present */+    if ( face->afm_data )+      T1_Done_AFM( memory, (T1_AFM*)face->afm_data );+#endif++    /* release unicode map, if any */+    FT_FREE( face->unicode_map.maps );+    face->unicode_map.num_maps = 0;++    face->root.family_name = 0;+    face->root.style_name  = 0;+  }+++  /*************************************************************************/+  /*                                                                       */+  /* <Function>                                                            */+  /*    T42_Driver_Init                                                    */+  /*                                                                       */+  /* <Description>                                                         */+  /*    Initializes a given Type 42 driver object.                         */+  /*                                                                       */+  /* <Input>                                                               */+  /*    driver :: A handle to the target driver object.                    */+  /*                                                                       */+  /* <Return>                                                              */+  /*    FreeType error code.  0 means success.                             */+  /*                                                                       */+  FT_LOCAL_DEF( FT_Error )+  T42_Driver_Init( T42_Driver  driver )+  {+    FT_Module  ttmodule;+++    ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" );+    driver->ttclazz = (FT_Driver_Class)ttmodule->clazz;++    return T42_Err_Ok;+  }+++  FT_LOCAL_DEF( void )+  T42_Driver_Done( T42_Driver  driver )+  {+    FT_UNUSED( driver );+  }+++  FT_LOCAL_DEF( FT_Error )+  T42_Size_Init( T42_Size  size )+  {+    FT_Face   face = size->root.face;+    T42_Face  t42face = (T42_Face)face;+    FT_Size   ttsize;+    FT_Error  error   = T42_Err_Ok;+++    error = FT_New_Size( t42face->ttf_face, &ttsize );+    size->ttsize = ttsize;++    FT_Activate_Size( ttsize );++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T42_Size_Request( T42_Size         size,+                    FT_Size_Request  req )+  {+    T42_Face  face = (T42_Face)size->root.face;+    FT_Error  error;+++    FT_Activate_Size( size->ttsize );++    error = FT_Request_Size( face->ttf_face, req );+    if ( !error )+      ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;++    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  T42_Size_Select( T42_Size  size,+                   FT_ULong  strike_index )+  {+    T42_Face  face = (T42_Face)size->root.face;+    FT_Error  error;+++    FT_Activate_Size( size->ttsize );++    error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );+    if ( !error )+      ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;++    return error;++  }+++  FT_LOCAL_DEF( void )+  T42_Size_Done( T42_Size  size )+  {+    FT_Face      face    = size->root.face;+    T42_Face     t42face = (T42_Face)face;+    FT_ListNode  node;+++    node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );+    if ( node )+    {+      FT_Done_Size( size->ttsize );+      size->ttsize = NULL;+    }+  }+++  FT_LOCAL_DEF( FT_Error )+  T42_GlyphSlot_Init( T42_GlyphSlot  slot )+  {+    FT_Face       face    = slot->root.face;+    T42_Face      t42face = (T42_Face)face;+    FT_GlyphSlot  ttslot;+    FT_Error      error   = T42_Err_Ok;+++    if ( face->glyph == NULL )+    {+      /* First glyph slot for this face */+      slot->ttslot = t42face->ttf_face->glyph;+    }+    else+    {+      error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );+      slot->ttslot = ttslot;+    }++    return error;+  }+++  FT_LOCAL_DEF( void )+  T42_GlyphSlot_Done( T42_GlyphSlot slot )+  {+    FT_Done_GlyphSlot( slot->ttslot );+  }+++  static void+  t42_glyphslot_clear( FT_GlyphSlot  slot )+  {+    /* free bitmap if needed */+    ft_glyphslot_free_bitmap( slot );++    /* clear all public fields in the glyph slot */+    FT_ZERO( &slot->metrics );+    FT_ZERO( &slot->outline );+    FT_ZERO( &slot->bitmap );++    slot->bitmap_left   = 0;+    slot->bitmap_top    = 0;+    slot->num_subglyphs = 0;+    slot->subglyphs     = 0;+    slot->control_data  = 0;+    slot->control_len   = 0;+    slot->other         = 0;+    slot->format        = FT_GLYPH_FORMAT_NONE;++    slot->linearHoriAdvance = 0;+    slot->linearVertAdvance = 0;+  }+++  FT_LOCAL_DEF( FT_Error )+  T42_GlyphSlot_Load( FT_GlyphSlot  glyph,+                      FT_Size       size,+                      FT_UInt       glyph_index,+                      FT_Int32      load_flags )+  {+    FT_Error         error;+    T42_GlyphSlot    t42slot = (T42_GlyphSlot)glyph;+    T42_Size         t42size = (T42_Size)size;+    FT_Driver_Class  ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;+++    t42_glyphslot_clear( t42slot->ttslot );+    error = ttclazz->load_glyph( t42slot->ttslot,+                                 t42size->ttsize,+                                 glyph_index,+                                 load_flags | FT_LOAD_NO_BITMAP );++    if ( !error )+    {+      glyph->metrics = t42slot->ttslot->metrics;++      glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;+      glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;++      glyph->format  = t42slot->ttslot->format;+      glyph->outline = t42slot->ttslot->outline;++      glyph->bitmap      = t42slot->ttslot->bitmap;+      glyph->bitmap_left = t42slot->ttslot->bitmap_left;+      glyph->bitmap_top  = t42slot->ttslot->bitmap_top;++      glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;+      glyph->subglyphs     = t42slot->ttslot->subglyphs;++      glyph->control_data  = t42slot->ttslot->control_data;+      glyph->control_len   = t42slot->ttslot->control_len;+    }++    return error;+  }+++/* END */
+ src/type42/t42objs.h view
@@ -0,0 +1,124 @@+/***************************************************************************/+/*                                                                         */+/*  t42objs.h                                                              */+/*                                                                         */+/*    Type 42 objects manager (specification).                             */+/*                                                                         */+/*  Copyright 2002, 2003, 2006, 2007 by Roberto Alameda.                   */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T42OBJS_H__+#define __T42OBJS_H__++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TYPE1_TABLES_H+#include FT_INTERNAL_TYPE1_TYPES_H+#include "t42types.h"+#include FT_INTERNAL_OBJECTS_H+#include FT_INTERNAL_DRIVER_H+#include FT_SERVICE_POSTSCRIPT_CMAPS_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+++FT_BEGIN_HEADER+++  /* Type42 size */+  typedef struct  T42_SizeRec_+  {+    FT_SizeRec  root;+    FT_Size     ttsize;++  } T42_SizeRec, *T42_Size;+++  /* Type42 slot */+  typedef struct  T42_GlyphSlotRec_+  {+    FT_GlyphSlotRec  root;+    FT_GlyphSlot     ttslot;++  } T42_GlyphSlotRec, *T42_GlyphSlot;+++  /* Type 42 driver */+  typedef struct  T42_DriverRec_+  {+    FT_DriverRec     root;+    FT_Driver_Class  ttclazz;+    void*            extension_component;++  } T42_DriverRec, *T42_Driver;+++  /* */+++  FT_LOCAL( FT_Error )+  T42_Face_Init( FT_Stream      stream,+                 T42_Face       face,+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params );+++  FT_LOCAL( void )+  T42_Face_Done( T42_Face  face );+++  FT_LOCAL( FT_Error )+  T42_Size_Init( T42_Size  size );+++  FT_LOCAL( FT_Error )+  T42_Size_Request( T42_Size         size,+                    FT_Size_Request  req );+++  FT_LOCAL( FT_Error )+  T42_Size_Select( T42_Size  size,+                   FT_ULong  strike_index );+++  FT_LOCAL( void )+  T42_Size_Done( T42_Size  size );+++  FT_LOCAL( FT_Error )+  T42_GlyphSlot_Init( T42_GlyphSlot  slot );+++  FT_LOCAL( FT_Error )+  T42_GlyphSlot_Load( FT_GlyphSlot  glyph,+                      FT_Size       size,+                      FT_UInt       glyph_index,+                      FT_Int32      load_flags );++  FT_LOCAL( void )+  T42_GlyphSlot_Done( T42_GlyphSlot slot );+++  FT_LOCAL( FT_Error )+  T42_Driver_Init( T42_Driver  driver );++  FT_LOCAL( void )+  T42_Driver_Done( T42_Driver  driver );++ /* */++FT_END_HEADER+++#endif /* __T42OBJS_H__ */+++/* END */
+ src/type42/t42parse.c view
@@ -0,0 +1,1187 @@+/***************************************************************************/+/*                                                                         */+/*  t42parse.c                                                             */+/*                                                                         */+/*    Type 42 font parser (body).                                          */+/*                                                                         */+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by      */+/*  Roberto Alameda.                                                       */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include "t42parse.h"+#include "t42error.h"+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_t42+++  static void+  t42_parse_font_matrix( T42_Face    face,+                         T42_Loader  loader );+  static void+  t42_parse_encoding( T42_Face    face,+                      T42_Loader  loader );++  static void+  t42_parse_charstrings( T42_Face    face,+                         T42_Loader  loader );++  static void+  t42_parse_sfnts( T42_Face    face,+                   T42_Loader  loader );+++  /* as Type42 fonts have no Private dict,         */+  /* we set the last argument of T1_FIELD_XXX to 0 */+  static const+  T1_FieldRec  t42_keywords[] =+  {++#undef  FT_STRUCTURE+#define FT_STRUCTURE  T1_FontInfo+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_INFO++    T1_FIELD_STRING( "version",            version,             0 )+    T1_FIELD_STRING( "Notice",             notice,              0 )+    T1_FIELD_STRING( "FullName",           full_name,           0 )+    T1_FIELD_STRING( "FamilyName",         family_name,         0 )+    T1_FIELD_STRING( "Weight",             weight,              0 )+    T1_FIELD_NUM   ( "ItalicAngle",        italic_angle,        0 )+    T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch,      0 )+    T1_FIELD_NUM   ( "UnderlinePosition",  underline_position,  0 )+    T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, 0 )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  PS_FontExtraRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_EXTRA++    T1_FIELD_NUM   ( "FSType",             fs_type,             0 )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  T1_FontRec+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_FONT_DICT++    T1_FIELD_KEY  ( "FontName",    font_name,    0 )+    T1_FIELD_NUM  ( "PaintType",   paint_type,   0 )+    T1_FIELD_NUM  ( "FontType",    font_type,    0 )+    T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )++#undef  FT_STRUCTURE+#define FT_STRUCTURE  FT_BBox+#undef  T1CODE+#define T1CODE        T1_FIELD_LOCATION_BBOX++    T1_FIELD_BBOX("FontBBox", xMin, 0 )++    T1_FIELD_CALLBACK( "FontMatrix",  t42_parse_font_matrix, 0 )+    T1_FIELD_CALLBACK( "Encoding",    t42_parse_encoding,    0 )+    T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 )+    T1_FIELD_CALLBACK( "sfnts",       t42_parse_sfnts,       0 )++    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }+  };+++#define T1_Add_Table( p, i, o, l )  (p)->funcs.add( (p), i, o, l )+#define T1_Done_Table( p )          \+          do                        \+          {                         \+            if ( (p)->funcs.done )  \+              (p)->funcs.done( p ); \+          } while ( 0 )+#define T1_Release_Table( p )          \+          do                           \+          {                            \+            if ( (p)->funcs.release )  \+              (p)->funcs.release( p ); \+          } while ( 0 )++#define T1_Skip_Spaces( p )    (p)->root.funcs.skip_spaces( &(p)->root )+#define T1_Skip_PS_Token( p )  (p)->root.funcs.skip_PS_token( &(p)->root )++#define T1_ToInt( p )                          \+          (p)->root.funcs.to_int( &(p)->root )+#define T1_ToBytes( p, b, m, n, d )                          \+          (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d )++#define T1_ToFixedArray( p, m, f, t )                           \+          (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )+#define T1_ToToken( p, t )                          \+          (p)->root.funcs.to_token( &(p)->root, t )++#define T1_Load_Field( p, f, o, m, pf )                         \+          (p)->root.funcs.load_field( &(p)->root, f, o, m, pf )+#define T1_Load_Field_Table( p, f, o, m, pf )                         \+          (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf )+++  /********************* Parsing Functions ******************/++  FT_LOCAL_DEF( FT_Error )+  t42_parser_init( T42_Parser     parser,+                   FT_Stream      stream,+                   FT_Memory      memory,+                   PSAux_Service  psaux )+  {+    FT_Error  error = T42_Err_Ok;+    FT_Long   size;+++    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );++    parser->stream    = stream;+    parser->base_len  = 0;+    parser->base_dict = 0;+    parser->in_memory = 0;++    /*******************************************************************/+    /*                                                                 */+    /* Here a short summary of what is going on:                       */+    /*                                                                 */+    /*   When creating a new Type 42 parser, we try to locate and load */+    /*   the base dictionary, loading the whole font into memory.      */+    /*                                                                 */+    /*   When `loading' the base dictionary, we only set up pointers   */+    /*   in the case of a memory-based stream.  Otherwise, we allocate */+    /*   and load the base dictionary in it.                           */+    /*                                                                 */+    /*   parser->in_memory is set if we have a memory stream.          */+    /*                                                                 */++    if ( FT_STREAM_SEEK( 0L ) ||+         FT_FRAME_ENTER( 17 ) )+      goto Exit;++    if ( ft_memcmp( stream->cursor, "%!PS-TrueTypeFont", 17 ) != 0 )+    {+      FT_TRACE2(( "not a Type42 font\n" ));+      error = T42_Err_Unknown_File_Format;+    }++    FT_FRAME_EXIT();++    if ( error || FT_STREAM_SEEK( 0 ) )+      goto Exit;++    size = stream->size;++    /* now, try to load `size' bytes of the `base' dictionary we */+    /* found previously                                          */++    /* if it is a memory-based resource, set up pointers */+    if ( !stream->read )+    {+      parser->base_dict = (FT_Byte*)stream->base + stream->pos;+      parser->base_len  = size;+      parser->in_memory = 1;++      /* check that the `size' field is valid */+      if ( FT_STREAM_SKIP( size ) )+        goto Exit;+    }+    else+    {+      /* read segment in memory */+      if ( FT_ALLOC( parser->base_dict, size )       ||+           FT_STREAM_READ( parser->base_dict, size ) )+        goto Exit;++      parser->base_len = size;+    }++    parser->root.base   = parser->base_dict;+    parser->root.cursor = parser->base_dict;+    parser->root.limit  = parser->root.cursor + parser->base_len;++  Exit:+    if ( error && !parser->in_memory )+      FT_FREE( parser->base_dict );++    return error;+  }+++  FT_LOCAL_DEF( void )+  t42_parser_done( T42_Parser  parser )+  {+    FT_Memory  memory = parser->root.memory;+++    /* free the base dictionary only when we have a disk stream */+    if ( !parser->in_memory )+      FT_FREE( parser->base_dict );++    parser->root.funcs.done( &parser->root );+  }+++  static int+  t42_is_space( FT_Byte  c )+  {+    return ( c == ' '  || c == '\t'              ||+             c == '\r' || c == '\n' || c == '\f' ||+             c == '\0'                           );+  }+++  static void+  t42_parse_font_matrix( T42_Face    face,+                         T42_Loader  loader )+  {+    T42_Parser  parser = &loader->parser;+    FT_Matrix*  matrix = &face->type1.font_matrix;+    FT_Vector*  offset = &face->type1.font_offset;+    FT_Face     root   = (FT_Face)&face->root;+    FT_Fixed    temp[6];+    FT_Fixed    temp_scale;+++    (void)T1_ToFixedArray( parser, 6, temp, 3 );++    temp_scale = FT_ABS( temp[3] );++    /* Set Units per EM based on FontMatrix values.  We set the value to */+    /* 1000 / temp_scale, because temp_scale was already multiplied by   */+    /* 1000 (in t1_tofixed, from psobjs.c).                              */++    root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,+                                                 temp_scale ) >> 16 );++    /* we need to scale the values by 1.0/temp_scale */+    if ( temp_scale != 0x10000L )+    {+      temp[0] = FT_DivFix( temp[0], temp_scale );+      temp[1] = FT_DivFix( temp[1], temp_scale );+      temp[2] = FT_DivFix( temp[2], temp_scale );+      temp[4] = FT_DivFix( temp[4], temp_scale );+      temp[5] = FT_DivFix( temp[5], temp_scale );+      temp[3] = 0x10000L;+    }++    matrix->xx = temp[0];+    matrix->yx = temp[1];+    matrix->xy = temp[2];+    matrix->yy = temp[3];++    /* note that the offsets must be expressed in integer font units */+    offset->x = temp[4] >> 16;+    offset->y = temp[5] >> 16;+  }+++  static void+  t42_parse_encoding( T42_Face    face,+                      T42_Loader  loader )+  {+    T42_Parser  parser = &loader->parser;+    FT_Byte*    cur;+    FT_Byte*    limit  = parser->root.limit;++    PSAux_Service  psaux  = (PSAux_Service)face->psaux;+++    T1_Skip_Spaces( parser );+    cur = parser->root.cursor;+    if ( cur >= limit )+    {+      FT_ERROR(( "t42_parse_encoding: out of bounds\n" ));+      parser->root.error = T42_Err_Invalid_File_Format;+      return;+    }++    /* if we have a number or `[', the encoding is an array, */+    /* and we must load it now                               */+    if ( ft_isdigit( *cur ) || *cur == '[' )+    {+      T1_Encoding  encode          = &face->type1.encoding;+      FT_UInt      count, n;+      PS_Table     char_table      = &loader->encoding_table;+      FT_Memory    memory          = parser->root.memory;+      FT_Error     error;+      FT_Bool      only_immediates = 0;+++      /* read the number of entries in the encoding; should be 256 */+      if ( *cur == '[' )+      {+        count           = 256;+        only_immediates = 1;+        parser->root.cursor++;+      }+      else+        count = (FT_UInt)T1_ToInt( parser );++      T1_Skip_Spaces( parser );+      if ( parser->root.cursor >= limit )+        return;++      /* we use a T1_Table to store our charnames */+      loader->num_chars = encode->num_chars = count;+      if ( FT_NEW_ARRAY( encode->char_index, count )     ||+           FT_NEW_ARRAY( encode->char_name,  count )     ||+           FT_SET_ERROR( psaux->ps_table_funcs->init(+                           char_table, count, memory ) ) )+      {+        parser->root.error = error;+        return;+      }++      /* We need to `zero' out encoding_table.elements */+      for ( n = 0; n < count; n++ )+      {+        char*  notdef = (char *)".notdef";+++        T1_Add_Table( char_table, n, notdef, 8 );+      }++      /* Now we need to read records of the form                */+      /*                                                        */+      /*   ... charcode /charname ...                           */+      /*                                                        */+      /* for each entry in our table.                           */+      /*                                                        */+      /* We simply look for a number followed by an immediate   */+      /* name.  Note that this ignores correctly the sequence   */+      /* that is often seen in type42 fonts:                    */+      /*                                                        */+      /*   0 1 255 { 1 index exch /.notdef put } for dup        */+      /*                                                        */+      /* used to clean the encoding array before anything else. */+      /*                                                        */+      /* Alternatively, if the array is directly given as       */+      /*                                                        */+      /*   /Encoding [ ... ]                                    */+      /*                                                        */+      /* we only read immediates.                               */++      n = 0;+      T1_Skip_Spaces( parser );++      while ( parser->root.cursor < limit )+      {+        cur = parser->root.cursor;++        /* we stop when we encounter `def' or `]' */+        if ( *cur == 'd' && cur + 3 < limit )+        {+          if ( cur[1] == 'e'          &&+               cur[2] == 'f'          &&+               t42_is_space( cur[3] ) )+          {+            FT_TRACE6(( "encoding end\n" ));+            cur += 3;+            break;+          }+        }+        if ( *cur == ']' )+        {+          FT_TRACE6(( "encoding end\n" ));+          cur++;+          break;+        }++        /* check whether we have found an entry */+        if ( ft_isdigit( *cur ) || only_immediates )+        {+          FT_Int  charcode;+++          if ( only_immediates )+            charcode = n;+          else+          {+            charcode = (FT_Int)T1_ToInt( parser );+            T1_Skip_Spaces( parser );+          }++          cur = parser->root.cursor;++          if ( *cur == '/' && cur + 2 < limit && n < count )+          {+            FT_PtrDist  len;+++            cur++;++            parser->root.cursor = cur;+            T1_Skip_PS_Token( parser );+            if ( parser->root.error )+              return;++            len = parser->root.cursor - cur;++            parser->root.error = T1_Add_Table( char_table, charcode,+                                               cur, len + 1 );+            if ( parser->root.error )+              return;+            char_table->elements[charcode][len] = '\0';++            n++;+          }+        }+        else+        {+          T1_Skip_PS_Token( parser );+          if ( parser->root.error )+            return;+        }++        T1_Skip_Spaces( parser );+      }++      face->type1.encoding_type  = T1_ENCODING_TYPE_ARRAY;+      parser->root.cursor        = cur;+    }++    /* Otherwise, we should have either `StandardEncoding', */+    /* `ExpertEncoding', or `ISOLatin1Encoding'             */+    else+    {+      if ( cur + 17 < limit                                            &&+           ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;++      else if ( cur + 15 < limit                                          &&+                ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;++      else if ( cur + 18 < limit                                             &&+                ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )+        face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;++      else+      {+        FT_ERROR(( "t42_parse_encoding: invalid token\n" ));+        parser->root.error = T42_Err_Invalid_File_Format;+      }+    }+  }+++  typedef enum  T42_Load_Status_+  {+    BEFORE_START,+    BEFORE_TABLE_DIR,+    OTHER_TABLES++  } T42_Load_Status;+++  static void+  t42_parse_sfnts( T42_Face    face,+                   T42_Loader  loader )+  {+    T42_Parser  parser = &loader->parser;+    FT_Memory   memory = parser->root.memory;+    FT_Byte*    cur;+    FT_Byte*    limit  = parser->root.limit;+    FT_Error    error;+    FT_Int      num_tables = 0;+    FT_ULong    count, ttf_size = 0;++    FT_Long     n, string_size, old_string_size, real_size;+    FT_Byte*    string_buf = NULL;+    FT_Bool     allocated  = 0;++    T42_Load_Status  status;+++    /* The format is                                */+    /*                                              */+    /*   /sfnts [ <hexstring> <hexstring> ... ] def */+    /*                                              */+    /* or                                           */+    /*                                              */+    /*   /sfnts [                                   */+    /*      <num_bin_bytes> RD <binary data>        */+    /*      <num_bin_bytes> RD <binary data>        */+    /*      ...                                     */+    /*   ] def                                      */+    /*                                              */+    /* with exactly one space after the `RD' token. */++    T1_Skip_Spaces( parser );++    if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' )+    {+      FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" ));+      error = T42_Err_Invalid_File_Format;+      goto Fail;+    }++    T1_Skip_Spaces( parser );+    status          = BEFORE_START;+    string_size     = 0;+    old_string_size = 0;+    count           = 0;++    while ( parser->root.cursor < limit )+    {+      cur = parser->root.cursor;++      if ( *cur == ']' )+      {+        parser->root.cursor++;+        goto Exit;+      }++      else if ( *cur == '<' )+      {+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;++        /* don't include delimiters */+        string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 );+        if ( FT_REALLOC( string_buf, old_string_size, string_size ) )+          goto Fail;++        allocated = 1;++        parser->root.cursor = cur;+        (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );+        old_string_size = string_size;+        string_size = real_size;+      }++      else if ( ft_isdigit( *cur ) )+      {+        if ( allocated )+        {+          FT_ERROR(( "t42_parse_sfnts: "+                     "can't handle mixed binary and hex strings\n" ));+          error = T42_Err_Invalid_File_Format;+          goto Fail;+        }++        string_size = T1_ToInt( parser );+        if ( string_size < 0 )+        {+          FT_ERROR(( "t42_parse_sfnts: invalid string size\n" ));+          error = T42_Err_Invalid_File_Format;+          goto Fail;+        }++        T1_Skip_PS_Token( parser );             /* `RD' */+        if ( parser->root.error )+          return;++        string_buf = parser->root.cursor + 1;   /* one space after `RD' */++        if ( limit - parser->root.cursor < string_size )+        {+          FT_ERROR(( "t42_parse_sfnts: too many binary data\n" ));+          error = T42_Err_Invalid_File_Format;+          goto Fail;+        }+        else+          parser->root.cursor += string_size + 1;+      }++      if ( !string_buf )+      {+        FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));+        error = T42_Err_Invalid_File_Format;+        goto Fail;+      }++      /* A string can have a trailing zero byte for padding.  Ignore it. */+      if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) )+        string_size--;++      if ( !string_size )+      {+        FT_ERROR(( "t42_parse_sfnts: invalid string\n" ));+        error = T42_Err_Invalid_File_Format;+        goto Fail;+      }++      for ( n = 0; n < string_size; n++ )+      {+        switch ( status )+        {+        case BEFORE_START:+          /* load offset table, 12 bytes */+          if ( count < 12 )+          {+            face->ttf_data[count++] = string_buf[n];+            continue;+          }+          else+          {+            num_tables = 16 * face->ttf_data[4] + face->ttf_data[5];+            status     = BEFORE_TABLE_DIR;+            ttf_size   = 12 + 16 * num_tables;++            if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) )+              goto Fail;+          }+          /* fall through */++        case BEFORE_TABLE_DIR:+          /* the offset table is read; read the table directory */+          if ( count < ttf_size )+          {+            face->ttf_data[count++] = string_buf[n];+            continue;+          }+          else+          {+            int       i;+            FT_ULong  len;+++            for ( i = 0; i < num_tables; i++ )+            {+              FT_Byte*  p = face->ttf_data + 12 + 16 * i + 12;+++              len = FT_PEEK_ULONG( p );++              /* Pad to a 4-byte boundary length */+              ttf_size += ( len + 3 ) & ~3;+            }++            status         = OTHER_TABLES;+            face->ttf_size = ttf_size;++            /* there are no more than 256 tables, so no size check here */+            if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,+                             ttf_size + 1 ) )+              goto Fail;+          }+          /* fall through */++        case OTHER_TABLES:+          /* all other tables are just copied */+          if ( count >= ttf_size )+          {+            FT_ERROR(( "t42_parse_sfnts: too many binary data\n" ));+            error = T42_Err_Invalid_File_Format;+            goto Fail;+          }+          face->ttf_data[count++] = string_buf[n];+        }+      }++      T1_Skip_Spaces( parser );+    }++    /* if control reaches this point, the format was not valid */+    error = T42_Err_Invalid_File_Format;++  Fail:+    parser->root.error = error;++  Exit:+    if ( allocated )+      FT_FREE( string_buf );+  }+++  static void+  t42_parse_charstrings( T42_Face    face,+                         T42_Loader  loader )+  {+    T42_Parser     parser       = &loader->parser;+    PS_Table       code_table   = &loader->charstrings;+    PS_Table       name_table   = &loader->glyph_names;+    PS_Table       swap_table   = &loader->swap_table;+    FT_Memory      memory       = parser->root.memory;+    FT_Error       error;++    PSAux_Service  psaux        = (PSAux_Service)face->psaux;++    FT_Byte*       cur;+    FT_Byte*       limit        = parser->root.limit;+    FT_UInt        n;+    FT_UInt        notdef_index = 0;+    FT_Byte        notdef_found = 0;+++    T1_Skip_Spaces( parser );++    if ( parser->root.cursor >= limit )+    {+      FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));+      error = T42_Err_Invalid_File_Format;+      goto Fail;+    }++    if ( ft_isdigit( *parser->root.cursor ) )+    {+      loader->num_glyphs = (FT_UInt)T1_ToInt( parser );+      if ( parser->root.error )+        return;+    }+    else if ( *parser->root.cursor == '<' )+    {+      /* We have `<< ... >>'.  Count the number of `/' in the dictionary */+      /* to get its size.                                                */+      FT_UInt  count = 0;+++      T1_Skip_PS_Token( parser );+      if ( parser->root.error )+        return;+      T1_Skip_Spaces( parser );+      cur = parser->root.cursor;++      while ( parser->root.cursor < limit )+      {+        if ( *parser->root.cursor == '/' )+          count++;+        else if ( *parser->root.cursor == '>' )+        {+          loader->num_glyphs  = count;+          parser->root.cursor = cur;        /* rewind */+          break;+        }+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          return;+        T1_Skip_Spaces( parser );+      }+    }+    else+    {+      FT_ERROR(( "t42_parse_charstrings: invalid token\n" ));+      error = T42_Err_Invalid_File_Format;+      goto Fail;+    }++    if ( parser->root.cursor >= limit )+    {+      FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));+      error = T42_Err_Invalid_File_Format;+      goto Fail;+    }++    /* initialize tables */++    error = psaux->ps_table_funcs->init( code_table,+                                         loader->num_glyphs,+                                         memory );+    if ( error )+      goto Fail;++    error = psaux->ps_table_funcs->init( name_table,+                                         loader->num_glyphs,+                                         memory );+    if ( error )+      goto Fail;++    /* Initialize table for swapping index notdef_index and */+    /* index 0 names and codes (if necessary).              */++    error = psaux->ps_table_funcs->init( swap_table, 4, memory );+    if ( error )+      goto Fail;++    n = 0;++    for (;;)+    {+      /* The format is simple:                   */+      /*   `/glyphname' + index [+ def]          */++      T1_Skip_Spaces( parser );++      cur = parser->root.cursor;+      if ( cur >= limit )+        break;++      /* We stop when we find an `end' keyword or '>' */+      if ( *cur   == 'e'          &&+           cur + 3 < limit        &&+           cur[1] == 'n'          &&+           cur[2] == 'd'          &&+           t42_is_space( cur[3] ) )+        break;+      if ( *cur == '>' )+        break;++      T1_Skip_PS_Token( parser );+      if ( parser->root.error )+        return;++      if ( *cur == '/' )+      {+        FT_PtrDist  len;+++        if ( cur + 1 >= limit )+        {+          FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));+          error = T42_Err_Invalid_File_Format;+          goto Fail;+        }++        cur++;                              /* skip `/' */+        len = parser->root.cursor - cur;++        error = T1_Add_Table( name_table, n, cur, len + 1 );+        if ( error )+          goto Fail;++        /* add a trailing zero to the name table */+        name_table->elements[n][len] = '\0';++        /* record index of /.notdef */+        if ( *cur == '.'                                              &&+             ft_strcmp( ".notdef",+                        (const char*)(name_table->elements[n]) ) == 0 )+        {+          notdef_index = n;+          notdef_found = 1;+        }++        T1_Skip_Spaces( parser );++        cur = parser->root.cursor;++        (void)T1_ToInt( parser );+        if ( parser->root.cursor >= limit )+        {+          FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));+          error = T42_Err_Invalid_File_Format;+          goto Fail;+        }++        len = parser->root.cursor - cur;++        error = T1_Add_Table( code_table, n, cur, len + 1 );+        if ( error )+          goto Fail;++        code_table->elements[n][len] = '\0';++        n++;+        if ( n >= loader->num_glyphs )+          break;+      }+    }++    loader->num_glyphs = n;++    if ( !notdef_found )+    {+      FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" ));+      error = T42_Err_Invalid_File_Format;+      goto Fail;+    }++    /* if /.notdef does not occupy index 0, do our magic. */+    if ( ft_strcmp( (const char*)".notdef",+                    (const char*)name_table->elements[0] ) )+    {+      /* Swap glyph in index 0 with /.notdef glyph.  First, add index 0  */+      /* name and code entries to swap_table.  Then place notdef_index   */+      /* name and code entries into swap_table.  Then swap name and code */+      /* entries at indices notdef_index and 0 using values stored in    */+      /* swap_table.                                                     */++      /* Index 0 name */+      error = T1_Add_Table( swap_table, 0,+                            name_table->elements[0],+                            name_table->lengths [0] );+      if ( error )+        goto Fail;++      /* Index 0 code */+      error = T1_Add_Table( swap_table, 1,+                            code_table->elements[0],+                            code_table->lengths [0] );+      if ( error )+        goto Fail;++      /* Index notdef_index name */+      error = T1_Add_Table( swap_table, 2,+                            name_table->elements[notdef_index],+                            name_table->lengths [notdef_index] );+      if ( error )+        goto Fail;++      /* Index notdef_index code */+      error = T1_Add_Table( swap_table, 3,+                            code_table->elements[notdef_index],+                            code_table->lengths [notdef_index] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, notdef_index,+                            swap_table->elements[0],+                            swap_table->lengths [0] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, notdef_index,+                            swap_table->elements[1],+                            swap_table->lengths [1] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( name_table, 0,+                            swap_table->elements[2],+                            swap_table->lengths [2] );+      if ( error )+        goto Fail;++      error = T1_Add_Table( code_table, 0,+                            swap_table->elements[3],+                            swap_table->lengths [3] );+      if ( error )+        goto Fail;++    }++    return;++  Fail:+    parser->root.error = error;+  }+++  static FT_Error+  t42_load_keyword( T42_Face    face,+                    T42_Loader  loader,+                    T1_Field    field )+  {+    FT_Error  error;+    void*     dummy_object;+    void**    objects;+    FT_UInt   max_objects = 0;+++    /* if the keyword has a dedicated callback, call it */+    if ( field->type == T1_FIELD_TYPE_CALLBACK )+    {+      field->reader( (FT_Face)face, loader );+      error = loader->parser.root.error;+      goto Exit;+    }++    /* now the keyword is either a simple field or a table of fields; */+    /* we are now going to take care of it                            */++    switch ( field->location )+    {+    case T1_FIELD_LOCATION_FONT_INFO:+      dummy_object = &face->type1.font_info;+      break;++    case T1_FIELD_LOCATION_FONT_EXTRA:+      dummy_object = &face->type1.font_extra;+      break;++    case T1_FIELD_LOCATION_BBOX:+      dummy_object = &face->type1.font_bbox;+      break;++    default:+      dummy_object = &face->type1;+    }++    objects = &dummy_object;++    if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||+         field->type == T1_FIELD_TYPE_FIXED_ARRAY   )+      error = T1_Load_Field_Table( &loader->parser, field,+                                   objects, max_objects, 0 );+    else+      error = T1_Load_Field( &loader->parser, field,+                             objects, max_objects, 0 );++   Exit:+    return error;+  }+++  FT_LOCAL_DEF( FT_Error )+  t42_parse_dict( T42_Face    face,+                  T42_Loader  loader,+                  FT_Byte*    base,+                  FT_Long     size )+  {+    T42_Parser  parser     = &loader->parser;+    FT_Byte*    limit;+    FT_Int      n_keywords = (FT_Int)( sizeof ( t42_keywords ) /+                                         sizeof ( t42_keywords[0] ) );+++    parser->root.cursor = base;+    parser->root.limit  = base + size;+    parser->root.error  = T42_Err_Ok;++    limit = parser->root.limit;++    T1_Skip_Spaces( parser );++    while ( parser->root.cursor < limit )+    {+      FT_Byte*  cur;+++      cur = parser->root.cursor;++      /* look for `FontDirectory' which causes problems for some fonts */+      if ( *cur == 'F' && cur + 25 < limit                    &&+           ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )+      {+        FT_Byte*  cur2;+++        /* skip the `FontDirectory' keyword */+        T1_Skip_PS_Token( parser );+        T1_Skip_Spaces  ( parser );+        cur = cur2 = parser->root.cursor;++        /* look up the `known' keyword */+        while ( cur < limit )+        {+          if ( *cur == 'k' && cur + 5 < limit             &&+                ft_strncmp( (char*)cur, "known", 5 ) == 0 )+            break;++          T1_Skip_PS_Token( parser );+          if ( parser->root.error )+            goto Exit;+          T1_Skip_Spaces  ( parser );+          cur = parser->root.cursor;+        }++        if ( cur < limit )+        {+          T1_TokenRec  token;+++          /* skip the `known' keyword and the token following it */+          T1_Skip_PS_Token( parser );+          T1_ToToken( parser, &token );++          /* if the last token was an array, skip it! */+          if ( token.type == T1_TOKEN_TYPE_ARRAY )+            cur2 = parser->root.cursor;+        }+        parser->root.cursor = cur2;+      }++      /* look for immediates */+      else if ( *cur == '/' && cur + 2 < limit )+      {+        FT_PtrDist  len;+++        cur++;++        parser->root.cursor = cur;+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;++        len = parser->root.cursor - cur;++        if ( len > 0 && len < 22 && parser->root.cursor < limit )+        {+          int  i;+++          /* now compare the immediate name to the keyword table */++          /* loop through all known keywords */+          for ( i = 0; i < n_keywords; i++ )+          {+            T1_Field  keyword = (T1_Field)&t42_keywords[i];+            FT_Byte   *name   = (FT_Byte*)keyword->ident;+++            if ( !name )+              continue;++            if ( cur[0] == name[0]                                  &&+                 len == (FT_PtrDist)ft_strlen( (const char *)name ) &&+                 ft_memcmp( cur, name, len ) == 0                   )+            {+              /* we found it -- run the parsing callback! */+              parser->root.error = t42_load_keyword( face,+                                                     loader,+                                                     keyword );+              if ( parser->root.error )+                return parser->root.error;+              break;+            }+          }+        }+      }+      else+      {+        T1_Skip_PS_Token( parser );+        if ( parser->root.error )+          goto Exit;+      }++      T1_Skip_Spaces( parser );+    }++  Exit:+    return parser->root.error;+  }+++  FT_LOCAL_DEF( void )+  t42_loader_init( T42_Loader  loader,+                   T42_Face    face )+  {+    FT_UNUSED( face );++    FT_MEM_ZERO( loader, sizeof ( *loader ) );+    loader->num_glyphs = 0;+    loader->num_chars  = 0;++    /* initialize the tables -- simply set their `init' field to 0 */+    loader->encoding_table.init = 0;+    loader->charstrings.init    = 0;+    loader->glyph_names.init    = 0;+  }+++  FT_LOCAL_DEF( void )+  t42_loader_done( T42_Loader  loader )+  {+    T42_Parser  parser = &loader->parser;+++    /* finalize tables */+    T1_Release_Table( &loader->encoding_table );+    T1_Release_Table( &loader->charstrings );+    T1_Release_Table( &loader->glyph_names );+    T1_Release_Table( &loader->swap_table );++    /* finalize parser */+    t42_parser_done( parser );+  }+++/* END */
+ src/type42/t42parse.h view
@@ -0,0 +1,90 @@+/***************************************************************************/+/*                                                                         */+/*  t42parse.h                                                             */+/*                                                                         */+/*    Type 42 font parser (specification).                                 */+/*                                                                         */+/*  Copyright 2002, 2003 by Roberto Alameda.                               */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T42PARSE_H__+#define __T42PARSE_H__+++#include "t42objs.h"+#include FT_INTERNAL_POSTSCRIPT_AUX_H+++FT_BEGIN_HEADER++  typedef struct  T42_ParserRec_+  {+    PS_ParserRec  root;+    FT_Stream     stream;++    FT_Byte*      base_dict;+    FT_Long       base_len;++    FT_Bool       in_memory;++  } T42_ParserRec, *T42_Parser;+++  typedef struct  T42_Loader_+  {+    T42_ParserRec  parser;          /* parser used to read the stream */++    FT_UInt        num_chars;       /* number of characters in encoding */+    PS_TableRec    encoding_table;  /* PS_Table used to store the       */+                                    /* encoding character names         */++    FT_UInt        num_glyphs;+    PS_TableRec    glyph_names;+    PS_TableRec    charstrings;+    PS_TableRec    swap_table;      /* For moving .notdef glyph to index 0. */++  } T42_LoaderRec, *T42_Loader;+++  FT_LOCAL( FT_Error )+  t42_parser_init( T42_Parser     parser,+                   FT_Stream      stream,+                   FT_Memory      memory,+                   PSAux_Service  psaux );++  FT_LOCAL( void )+  t42_parser_done( T42_Parser  parser );+++  FT_LOCAL( FT_Error )+  t42_parse_dict( T42_Face    face,+                  T42_Loader  loader,+                  FT_Byte*    base,+                  FT_Long     size );+++  FT_LOCAL( void )+  t42_loader_init( T42_Loader  loader,+                   T42_Face    face );++  FT_LOCAL( void )+  t42_loader_done( T42_Loader  loader );+++ /* */++FT_END_HEADER+++#endif /* __T42PARSE_H__ */+++/* END */
+ src/type42/t42types.h view
@@ -0,0 +1,56 @@+/***************************************************************************/+/*                                                                         */+/*  t42types.h                                                             */+/*                                                                         */+/*    Type 42 font data types (specification only).                        */+/*                                                                         */+/*  Copyright 2002, 2003, 2006, 2008 by Roberto Alameda.                   */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __T42TYPES_H__+#define __T42TYPES_H__+++#include <ft2build.h>+#include FT_FREETYPE_H+#include FT_TYPE1_TABLES_H+#include FT_INTERNAL_TYPE1_TYPES_H+#include FT_INTERNAL_POSTSCRIPT_HINTS_H+++FT_BEGIN_HEADER+++  typedef struct  T42_FaceRec_+  {+    FT_FaceRec      root;+    T1_FontRec      type1;+    const void*     psnames;+    const void*     psaux;+#if 0+    const void*     afm_data;+#endif+    FT_Byte*        ttf_data;+    FT_ULong        ttf_size;+    FT_Face         ttf_face;+    FT_CharMapRec   charmaprecs[2];+    FT_CharMap      charmaps[2];+    PS_UnicodesRec  unicode_map;++  } T42_FaceRec, *T42_Face;+++FT_END_HEADER++#endif /* __T42TYPES_H__ */+++/* END */
+ src/type42/type42.c view
@@ -0,0 +1,25 @@+/***************************************************************************/+/*                                                                         */+/*  type42.c                                                               */+/*                                                                         */+/*    FreeType Type 42 driver component.                                   */+/*                                                                         */+/*  Copyright 2002 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/++#define FT_MAKE_OPTION_SINGLE_OBJECT++#include <ft2build.h>+#include "t42objs.c"+#include "t42parse.c"+#include "t42drivr.c"++/* END */
+ src/winfonts/fnterrs.h view
@@ -0,0 +1,41 @@+/***************************************************************************/+/*                                                                         */+/*  fnterrs.h                                                              */+/*                                                                         */+/*    Win FNT/FON error codes (specification only).                        */+/*                                                                         */+/*  Copyright 2001 by                                                      */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++  /*************************************************************************/+  /*                                                                       */+  /* This file is used to define the Windows FNT/FON error enumeration     */+  /* constants.                                                            */+  /*                                                                       */+  /*************************************************************************/++#ifndef __FNTERRS_H__+#define __FNTERRS_H__++#include FT_MODULE_ERRORS_H++#undef __FTERRORS_H__++#define FT_ERR_PREFIX  FNT_Err_+#define FT_ERR_BASE    FT_Mod_Err_Winfonts++#include FT_ERRORS_H++#endif /* __FNTERRS_H__ */+++/* END */
+ src/winfonts/winfnt.c view
@@ -0,0 +1,1145 @@+/***************************************************************************/+/*                                                                         */+/*  winfnt.c                                                               */+/*                                                                         */+/*    FreeType font driver for Windows FNT/FON files                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 by */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*  Copyright 2003 Huw D M Davies for Codeweavers                          */+/*  Copyright 2007 Dmitry Timoshkov for Codeweavers                        */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#include <ft2build.h>+#include FT_WINFONTS_H+#include FT_INTERNAL_DEBUG_H+#include FT_INTERNAL_STREAM_H+#include FT_INTERNAL_OBJECTS_H+#include FT_TRUETYPE_IDS_H ++#include "winfnt.h"+#include "fnterrs.h"+#include FT_SERVICE_WINFNT_H+#include FT_SERVICE_XFREE86_NAME_H++  /*************************************************************************/+  /*                                                                       */+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */+  /* messages during execution.                                            */+  /*                                                                       */+#undef  FT_COMPONENT+#define FT_COMPONENT  trace_winfnt+++  static const FT_Frame_Field  winmz_header_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinMZ_HeaderRec++    FT_FRAME_START( 64 ),+      FT_FRAME_USHORT_LE ( magic ),+      FT_FRAME_SKIP_BYTES( 29 * 2 ),+      FT_FRAME_ULONG_LE  ( lfanew ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winne_header_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinNE_HeaderRec++    FT_FRAME_START( 40 ),+      FT_FRAME_USHORT_LE ( magic ),+      FT_FRAME_SKIP_BYTES( 34 ),+      FT_FRAME_USHORT_LE ( resource_tab_offset ),+      FT_FRAME_USHORT_LE ( rname_tab_offset ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winpe32_header_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinPE32_HeaderRec++    FT_FRAME_START( 248 ),+      FT_FRAME_ULONG_LE  ( magic ),   /* PE00 */+      FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */+      FT_FRAME_USHORT_LE ( number_of_sections ),+      FT_FRAME_SKIP_BYTES( 12 ),+      FT_FRAME_USHORT_LE ( size_of_optional_header ),+      FT_FRAME_SKIP_BYTES( 2 ),+      FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */+      FT_FRAME_SKIP_BYTES( 110 ),+      FT_FRAME_ULONG_LE  ( rsrc_virtual_address ),+      FT_FRAME_ULONG_LE  ( rsrc_size ),+      FT_FRAME_SKIP_BYTES( 104 ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winpe32_section_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinPE32_SectionRec++    FT_FRAME_START( 40 ),+      FT_FRAME_BYTES     ( name, 8 ),+      FT_FRAME_SKIP_BYTES( 4 ),+      FT_FRAME_ULONG_LE  ( virtual_address ),+      FT_FRAME_ULONG_LE  ( size_of_raw_data ),+      FT_FRAME_ULONG_LE  ( pointer_to_raw_data ),+      FT_FRAME_SKIP_BYTES( 16 ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winpe_rsrc_dir_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinPE_RsrcDirRec++    FT_FRAME_START( 16 ),+      FT_FRAME_ULONG_LE ( characteristics ),+      FT_FRAME_ULONG_LE ( time_date_stamp ),+      FT_FRAME_USHORT_LE( major_version ),+      FT_FRAME_USHORT_LE( minor_version ),+      FT_FRAME_USHORT_LE( number_of_named_entries ),+      FT_FRAME_USHORT_LE( number_of_id_entries ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winpe_rsrc_dir_entry_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinPE_RsrcDirEntryRec++    FT_FRAME_START( 8 ),+      FT_FRAME_ULONG_LE( name ),+      FT_FRAME_ULONG_LE( offset ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winpe_rsrc_data_entry_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  WinPE_RsrcDataEntryRec++    FT_FRAME_START( 16 ),+      FT_FRAME_ULONG_LE( offset_to_data ),+      FT_FRAME_ULONG_LE( size ),+      FT_FRAME_ULONG_LE( code_page ),+      FT_FRAME_ULONG_LE( reserved ),+    FT_FRAME_END+  };++  static const FT_Frame_Field  winfnt_header_fields[] =+  {+#undef  FT_STRUCTURE+#define FT_STRUCTURE  FT_WinFNT_HeaderRec++    FT_FRAME_START( 148 ),+      FT_FRAME_USHORT_LE( version ),+      FT_FRAME_ULONG_LE ( file_size ),+      FT_FRAME_BYTES    ( copyright, 60 ),+      FT_FRAME_USHORT_LE( file_type ),+      FT_FRAME_USHORT_LE( nominal_point_size ),+      FT_FRAME_USHORT_LE( vertical_resolution ),+      FT_FRAME_USHORT_LE( horizontal_resolution ),+      FT_FRAME_USHORT_LE( ascent ),+      FT_FRAME_USHORT_LE( internal_leading ),+      FT_FRAME_USHORT_LE( external_leading ),+      FT_FRAME_BYTE     ( italic ),+      FT_FRAME_BYTE     ( underline ),+      FT_FRAME_BYTE     ( strike_out ),+      FT_FRAME_USHORT_LE( weight ),+      FT_FRAME_BYTE     ( charset ),+      FT_FRAME_USHORT_LE( pixel_width ),+      FT_FRAME_USHORT_LE( pixel_height ),+      FT_FRAME_BYTE     ( pitch_and_family ),+      FT_FRAME_USHORT_LE( avg_width ),+      FT_FRAME_USHORT_LE( max_width ),+      FT_FRAME_BYTE     ( first_char ),+      FT_FRAME_BYTE     ( last_char ),+      FT_FRAME_BYTE     ( default_char ),+      FT_FRAME_BYTE     ( break_char ),+      FT_FRAME_USHORT_LE( bytes_per_row ),+      FT_FRAME_ULONG_LE ( device_offset ),+      FT_FRAME_ULONG_LE ( face_name_offset ),+      FT_FRAME_ULONG_LE ( bits_pointer ),+      FT_FRAME_ULONG_LE ( bits_offset ),+      FT_FRAME_BYTE     ( reserved ),+      FT_FRAME_ULONG_LE ( flags ),+      FT_FRAME_USHORT_LE( A_space ),+      FT_FRAME_USHORT_LE( B_space ),+      FT_FRAME_USHORT_LE( C_space ),+      FT_FRAME_ULONG_LE ( color_table_offset ),+      FT_FRAME_BYTES    ( reserved1, 16 ),+    FT_FRAME_END+  };+++  static void+  fnt_font_done( FNT_Face face )+  {+    FT_Memory  memory = FT_FACE( face )->memory;+    FT_Stream  stream = FT_FACE( face )->stream;+    FNT_Font   font   = face->font;+++    if ( !font )+      return;++    if ( font->fnt_frame )+      FT_FRAME_RELEASE( font->fnt_frame );+    FT_FREE( font->family_name );++    FT_FREE( font );+    face->font = 0;+  }+++  static FT_Error+  fnt_font_load( FNT_Font   font,+                 FT_Stream  stream )+  {+    FT_Error          error;+    FT_WinFNT_Header  header = &font->header;+    FT_Bool           new_format;+    FT_UInt           size;+++    /* first of all, read the FNT header */+    if ( FT_STREAM_SEEK( font->offset )                        ||+         FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) )+      goto Exit;++    /* check header */+    if ( header->version != 0x200 &&+         header->version != 0x300 )+    {+      FT_TRACE2(( "[not a valid FNT file]\n" ));+      error = FNT_Err_Unknown_File_Format;+      goto Exit;+    }++    new_format = FT_BOOL( font->header.version == 0x300 );+    size       = new_format ? 148 : 118;++    if ( header->file_size < size )+    {+      FT_TRACE2(( "[not a valid FNT file]\n" ));+      error = FNT_Err_Unknown_File_Format;+      goto Exit;+    }++    /* Version 2 doesn't have these fields */+    if ( header->version == 0x200 )+    {+      header->flags   = 0;+      header->A_space = 0;+      header->B_space = 0;+      header->C_space = 0;++      header->color_table_offset = 0;+    }++    if ( header->file_type & 1 )+    {+      FT_TRACE2(( "[can't handle vector FNT fonts]\n" ));+      error = FNT_Err_Unknown_File_Format;+      goto Exit;+    }++    /* this is a FNT file/table; extract its frame */+    if ( FT_STREAM_SEEK( font->offset )                         ||+         FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) )+      goto Exit;++  Exit:+    return error;+  }+++  static FT_Error+  fnt_face_get_dll_font( FNT_Face  face,+                         FT_Int    face_index )+  {+    FT_Error         error;+    FT_Stream        stream = FT_FACE( face )->stream;+    FT_Memory        memory = FT_FACE( face )->memory;+    WinMZ_HeaderRec  mz_header;+++    face->font = 0;++    /* does it begin with an MZ header? */+    if ( FT_STREAM_SEEK( 0 )                                      ||+         FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) )+      goto Exit;++    error = FNT_Err_Unknown_File_Format;+    if ( mz_header.magic == WINFNT_MZ_MAGIC )+    {+      /* yes, now look for an NE header in the file */+      WinNE_HeaderRec  ne_header;+++      FT_TRACE2(( "MZ signature found\n" ));++      if ( FT_STREAM_SEEK( mz_header.lfanew )                       ||+           FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )+        goto Exit;++      error = FNT_Err_Unknown_File_Format;+      if ( ne_header.magic == WINFNT_NE_MAGIC )+      {+        /* good, now look into the resource table for each FNT resource */+        FT_ULong   res_offset  = mz_header.lfanew ++                                   ne_header.resource_tab_offset;+        FT_UShort  size_shift;+        FT_UShort  font_count  = 0;+        FT_ULong   font_offset = 0;+++        FT_TRACE2(( "NE signature found\n" ));++        if ( FT_STREAM_SEEK( res_offset )                    ||+             FT_FRAME_ENTER( ne_header.rname_tab_offset -+                             ne_header.resource_tab_offset ) )+          goto Exit;++        size_shift = FT_GET_USHORT_LE();++        for (;;)+        {+          FT_UShort  type_id, count;+++          type_id = FT_GET_USHORT_LE();+          if ( !type_id )+            break;++          count = FT_GET_USHORT_LE();++          if ( type_id == 0x8008U )+          {+            font_count  = count;+            font_offset = (FT_ULong)( FT_STREAM_POS() + 4 ++                                      ( stream->cursor - stream->limit ) );+            break;+          }++          stream->cursor += 4 + count * 12;+        }++        FT_FRAME_EXIT();++        if ( !font_count || !font_offset )+        {+          FT_TRACE2(( "this file doesn't contain any FNT resources\n" ));+          error = FNT_Err_Invalid_File_Format;+          goto Exit;+        }++        /* loading `winfnt_header_fields' needs at least 118 bytes;    */+        /* use this as a rough measure to check the expected font size */+        if ( font_count * 118UL > stream->size )+        {+          FT_TRACE2(( "invalid number of faces\n" ));+          error = FNT_Err_Invalid_File_Format;+          goto Exit;+        }++        face->root.num_faces = font_count;++        if ( face_index >= font_count )+        {+          error = FNT_Err_Invalid_Argument;+          goto Exit;+        }+        else if ( face_index < 0 )+          goto Exit;++        if ( FT_NEW( face->font ) )+          goto Exit;++        if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) ||+             FT_FRAME_ENTER( 12 )                            )+          goto Fail;++        face->font->offset   = (FT_ULong)FT_GET_USHORT_LE() << size_shift;+        face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;++        stream->cursor += 8;++        FT_FRAME_EXIT();++        error = fnt_font_load( face->font, stream );+      }+      else if ( ne_header.magic == WINFNT_PE_MAGIC )+      {+        WinPE32_HeaderRec       pe32_header;+        WinPE32_SectionRec      pe32_section;+        WinPE_RsrcDirRec        root_dir, name_dir, lang_dir;+        WinPE_RsrcDirEntryRec   dir_entry1, dir_entry2, dir_entry3;+        WinPE_RsrcDataEntryRec  data_entry;++        FT_Long    root_dir_offset, name_dir_offset, lang_dir_offset;+        FT_UShort  i, j, k;+++        FT_TRACE2(( "PE signature found\n" ));++        if ( FT_STREAM_SEEK( mz_header.lfanew )                           ||+             FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) )+          goto Exit;++        FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, "+                    "size_of_optional_header %02x\n"+                    "magic32 %02x, rsrc_virtual_address %04lx, "+                    "rsrc_size %04lx\n",+                    pe32_header.magic, pe32_header.machine,+                    pe32_header.number_of_sections,+                    pe32_header.size_of_optional_header,+                    pe32_header.magic32, pe32_header.rsrc_virtual_address,+                    pe32_header.rsrc_size ));++        if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ ||+             pe32_header.machine != 0x014c /* i386 */                        ||+             pe32_header.size_of_optional_header != 0xe0 /* FIXME */         ||+             pe32_header.magic32 != 0x10b                                    )+        {+          FT_TRACE2(( "this file has an invalid PE header\n" ));+          error = FNT_Err_Invalid_File_Format;+          goto Exit;+        }++        face->root.num_faces = 0;++        for ( i = 0; i < pe32_header.number_of_sections; i++ )+        {+          if ( FT_STREAM_READ_FIELDS( winpe32_section_fields,+                                      &pe32_section ) )+            goto Exit;++          FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n",+                      pe32_section.name, pe32_section.virtual_address,+                      pe32_section.size_of_raw_data,+                      pe32_section.pointer_to_raw_data ));++          if ( pe32_header.rsrc_virtual_address ==+                 pe32_section.virtual_address )+            goto Found_rsrc_section;+        }++        FT_TRACE2(( "this file doesn't contain any resources\n" ));+        error = FNT_Err_Invalid_File_Format;+        goto Exit;++      Found_rsrc_section:+        FT_TRACE2(( "found resources section %.8s\n", pe32_section.name ));++        if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data )        ||+             FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) )+          goto Exit;++        root_dir_offset = pe32_section.pointer_to_raw_data;++        for ( i = 0; i < root_dir.number_of_named_entries ++                           root_dir.number_of_id_entries; i++ )+        {+          if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 )      ||+               FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,+                                      &dir_entry1 )                )+            goto Exit;++          if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )+          {+            error = FNT_Err_Invalid_File_Format;+            goto Exit;+          }++          dir_entry1.offset &= ~0x80000000UL;++          name_dir_offset = pe32_section.pointer_to_raw_data ++                            dir_entry1.offset;++          if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ++                               dir_entry1.offset )                       ||+               FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) )+            goto Exit;++          for ( j = 0; j < name_dir.number_of_named_entries ++                             name_dir.number_of_id_entries; j++ )+          {+            if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 )      ||+                 FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,+                                        &dir_entry2 )                )+              goto Exit;++            if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )+            {+              error = FNT_Err_Invalid_File_Format;+              goto Exit;+            }++            dir_entry2.offset &= ~0x80000000UL;++            lang_dir_offset = pe32_section.pointer_to_raw_data ++                                dir_entry2.offset;++            if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ++                                   dir_entry2.offset )                     ||+                 FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) )+              goto Exit;++            for ( k = 0; k < lang_dir.number_of_named_entries ++                               lang_dir.number_of_id_entries; k++ )+            {+              if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 )      ||+                   FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,+                                          &dir_entry3 )                )+                goto Exit;++              if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ )+              {+                error = FNT_Err_Invalid_File_Format;+                goto Exit;+              }++              if ( dir_entry1.name == 8 /* RT_FONT */ )+              {+                if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) ||+                     FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields,+                                            &data_entry )                  )+                  goto Exit;++                FT_TRACE2(( "found font #%lu, offset %04lx, "+                            "size %04lx, cp %lu\n",+                            dir_entry2.name,+                            pe32_section.pointer_to_raw_data ++                              data_entry.offset_to_data -+                              pe32_section.virtual_address,+                            data_entry.size, data_entry.code_page ));++                if ( face_index == face->root.num_faces )+                {+                  if ( FT_NEW( face->font ) )+                    goto Exit;++                  face->font->offset   = pe32_section.pointer_to_raw_data ++                                           data_entry.offset_to_data -+                                           pe32_section.virtual_address;+                  face->font->fnt_size = data_entry.size;++                  error = fnt_font_load( face->font, stream );+                  if ( error )+                  {+                    FT_TRACE2(( "font #%lu load error %d\n",+                                dir_entry2.name, error ));+                    goto Fail;+                  }+                  else+                    FT_TRACE2(( "font #%lu successfully loaded\n",+                                dir_entry2.name ));+                }++                face->root.num_faces++;+              }+            }+          }+        }+      }++      if ( !face->root.num_faces )+      {+        FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" ));+        error = FNT_Err_Invalid_File_Format;+        goto Exit;+      }++      if ( face_index >= face->root.num_faces )+      {+        error = FNT_Err_Invalid_Argument;+        goto Exit;+      }+    }++  Fail:+    if ( error )+      fnt_font_done( face );++  Exit:+    return error;+  }+++  typedef struct  FNT_CMapRec_+  {+    FT_CMapRec  cmap;+    FT_UInt32   first;+    FT_UInt32   count;++  } FNT_CMapRec, *FNT_CMap;+++  static FT_Error+  fnt_cmap_init( FNT_CMap  cmap )+  {+    FNT_Face  face = (FNT_Face)FT_CMAP_FACE( cmap );+    FNT_Font  font = face->font;+++    cmap->first = (FT_UInt32)  font->header.first_char;+    cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 );++    return 0;+  }+++  static FT_UInt+  fnt_cmap_char_index( FNT_CMap   cmap,+                       FT_UInt32  char_code )+  {+    FT_UInt  gindex = 0;+++    char_code -= cmap->first;+    if ( char_code < cmap->count )+      /* we artificially increase the glyph index; */+      /* FNT_Load_Glyph reverts to the right one   */+      gindex = (FT_UInt)( char_code + 1 );+    return gindex;+  }+++  static FT_UInt32+  fnt_cmap_char_next( FNT_CMap    cmap,+                      FT_UInt32  *pchar_code )+  {+    FT_UInt    gindex = 0;+    FT_UInt32  result = 0;+    FT_UInt32  char_code = *pchar_code + 1;+++    if ( char_code <= cmap->first )+    {+      result = cmap->first;+      gindex = 1;+    }+    else+    {+      char_code -= cmap->first;+      if ( char_code < cmap->count )+      {+        result = cmap->first + char_code;+        gindex = (FT_UInt)( char_code + 1 );+      }+    }++    *pchar_code = result;+    return gindex;+  }+++  static const FT_CMap_ClassRec  fnt_cmap_class_rec =+  {+    sizeof ( FNT_CMapRec ),++    (FT_CMap_InitFunc)     fnt_cmap_init,+    (FT_CMap_DoneFunc)     NULL,+    (FT_CMap_CharIndexFunc)fnt_cmap_char_index,+    (FT_CMap_CharNextFunc) fnt_cmap_char_next,++    NULL, NULL, NULL, NULL, NULL+  };++  static FT_CMap_Class const  fnt_cmap_class = &fnt_cmap_class_rec;+++  static void+  FNT_Face_Done( FNT_Face  face )+  {+    FT_Memory  memory;+++    if ( !face )+      return;++    memory = FT_FACE_MEMORY( face );++    fnt_font_done( face );++    FT_FREE( face->root.available_sizes );+    face->root.num_fixed_sizes = 0;+  }+++  static FT_Error+  FNT_Face_Init( FT_Stream      stream,+                 FNT_Face       face,+                 FT_Int         face_index,+                 FT_Int         num_params,+                 FT_Parameter*  params )+  {+    FT_Error   error;+    FT_Memory  memory = FT_FACE_MEMORY( face );++    FT_UNUSED( num_params );+    FT_UNUSED( params );+++    /* try to load font from a DLL */+    error = fnt_face_get_dll_font( face, face_index );+    if ( !error && face_index < 0 )+      goto Exit;++    if ( error == FNT_Err_Unknown_File_Format )+    {+      /* this didn't work; try to load a single FNT font */+      FNT_Font  font;++      if ( FT_NEW( face->font ) )+        goto Exit;++      face->root.num_faces = 1;++      font           = face->font;+      font->offset   = 0;+      font->fnt_size = stream->size;++      error = fnt_font_load( font, stream );++      if ( !error )+      {+        if ( face_index > 0 )+          error = FNT_Err_Invalid_Argument;+        else if ( face_index < 0 )+          goto Exit;+      }+    }++    if ( error )+      goto Fail;++    /* we now need to fill the root FT_Face fields */+    /* with relevant information                   */+    {+      FT_Face     root = FT_FACE( face );+      FNT_Font    font = face->font;+      FT_PtrDist  family_size;+++      root->face_index = face_index;++      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |+                         FT_FACE_FLAG_HORIZONTAL;++      if ( font->header.avg_width == font->header.max_width )+        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;++      if ( font->header.italic )+        root->style_flags |= FT_STYLE_FLAG_ITALIC;++      if ( font->header.weight >= 800 )+        root->style_flags |= FT_STYLE_FLAG_BOLD;++      /* set up the `fixed_sizes' array */+      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )+        goto Fail;++      root->num_fixed_sizes = 1;++      {+        FT_Bitmap_Size*  bsize = root->available_sizes;+        FT_UShort        x_res, y_res;+++        bsize->width  = font->header.avg_width;+        bsize->height = (FT_Short)(+          font->header.pixel_height + font->header.external_leading );+        bsize->size   = font->header.nominal_point_size << 6;++        x_res = font->header.horizontal_resolution;+        if ( !x_res )+          x_res = 72;++        y_res = font->header.vertical_resolution;+        if ( !y_res )+          y_res = 72;++        bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 );+        bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem );++        /*+         * this reads:+         *+         * the nominal height is larger than the bbox's height+         *+         * => nominal_point_size contains incorrect value;+         *    use pixel_height as the nominal height+         */+        if ( bsize->y_ppem > ( font->header.pixel_height << 6 ) )+        {+          FT_TRACE2(( "use pixel_height as the nominal height\n" ));++          bsize->y_ppem = font->header.pixel_height << 6;+          bsize->size   = FT_MulDiv( bsize->y_ppem, 72, y_res );+        }++        bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 );+        bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem );+      }++      {+        FT_CharMapRec  charmap;+++        charmap.encoding    = FT_ENCODING_NONE;+        /* initial platform/encoding should indicate unset status? */+        charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;+        charmap.encoding_id = TT_APPLE_ID_DEFAULT;+        charmap.face        = root;++        if ( font->header.charset == FT_WinFNT_ID_MAC )+        {+          charmap.encoding    = FT_ENCODING_APPLE_ROMAN;+          charmap.platform_id = TT_PLATFORM_MACINTOSH;+/*        charmap.encoding_id = TT_MAC_ID_ROMAN; */+        }++        error = FT_CMap_New( fnt_cmap_class,+                             NULL,+                             &charmap,+                             NULL );+        if ( error )+          goto Fail;++        /* Select default charmap */+        if ( root->num_charmaps )+          root->charmap = root->charmaps[0];+      }++      /* setup remaining flags */++      /* reserve one slot for the .notdef glyph at index 0 */+      root->num_glyphs = font->header.last_char -+                         font->header.first_char + 1 + 1;++      if ( font->header.face_name_offset >= font->header.file_size )+      {+        FT_TRACE2(( "invalid family name offset\n" ));+        error = FNT_Err_Invalid_File_Format;+        goto Fail;+      }+      family_size = font->header.file_size - font->header.face_name_offset;+      /* Some broken fonts don't delimit the face name with a final */+      /* NULL byte -- the frame is erroneously one byte too small.  */+      /* We thus allocate one more byte, setting it explicitly to   */+      /* zero.                                                      */+      if ( FT_ALLOC( font->family_name, family_size + 1 ) )+        goto Fail;++      FT_MEM_COPY( font->family_name,+                   font->fnt_frame + font->header.face_name_offset,+                   family_size );++      font->family_name[family_size] = '\0';++      if ( FT_REALLOC( font->family_name,+                       family_size,+                       ft_strlen( font->family_name ) + 1 ) )+        goto Fail;++      root->family_name = font->family_name;+      root->style_name  = (char *)"Regular";++      if ( root->style_flags & FT_STYLE_FLAG_BOLD )+      {+        if ( root->style_flags & FT_STYLE_FLAG_ITALIC )+          root->style_name = (char *)"Bold Italic";+        else+          root->style_name = (char *)"Bold";+      }+      else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )+        root->style_name = (char *)"Italic";+    }+    goto Exit;++  Fail:+    FNT_Face_Done( face );++  Exit:+    return error;+  }+++  static FT_Error+  FNT_Size_Select( FT_Size  size )+  {+    FNT_Face          face   = (FNT_Face)size->face;+    FT_WinFNT_Header  header = &face->font->header;+++    FT_Select_Metrics( size->face, 0 );++    size->metrics.ascender    = header->ascent * 64;+    size->metrics.descender   = -( header->pixel_height -+                                   header->ascent ) * 64;+    size->metrics.max_advance = header->max_width * 64;++    return FNT_Err_Ok;+  }+++  static FT_Error+  FNT_Size_Request( FT_Size          size,+                    FT_Size_Request  req )+  {+    FNT_Face          face    = (FNT_Face)size->face;+    FT_WinFNT_Header  header  = &face->font->header;+    FT_Bitmap_Size*   bsize   = size->face->available_sizes;+    FT_Error          error   = FNT_Err_Invalid_Pixel_Size;+    FT_Long           height;+++    height = FT_REQUEST_HEIGHT( req );+    height = ( height + 32 ) >> 6;++    switch ( req->type )+    {+    case FT_SIZE_REQUEST_TYPE_NOMINAL:+      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )+        error = FNT_Err_Ok;+      break;++    case FT_SIZE_REQUEST_TYPE_REAL_DIM:+      if ( height == header->pixel_height )+        error = FNT_Err_Ok;+      break;++    default:+      error = FNT_Err_Unimplemented_Feature;+      break;+    }++    if ( error )+      return error;+    else+      return FNT_Size_Select( size );+  }+++  static FT_Error+  FNT_Load_Glyph( FT_GlyphSlot  slot,+                  FT_Size       size,+                  FT_UInt       glyph_index,+                  FT_Int32      load_flags )+  {+    FNT_Face    face   = (FNT_Face)FT_SIZE_FACE( size );+    FNT_Font    font;+    FT_Error    error  = FNT_Err_Ok;+    FT_Byte*    p;+    FT_Int      len;+    FT_Bitmap*  bitmap = &slot->bitmap;+    FT_ULong    offset;+    FT_Bool     new_format;++    FT_UNUSED( load_flags );+++    if ( !face )+    {+      error = FNT_Err_Invalid_Argument;+      goto Exit;+    }++    font = face->font;++    if ( !font ||+         glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) )+    {+      error = FNT_Err_Invalid_Argument;+      goto Exit;+    }++    if ( glyph_index > 0 )+      glyph_index--;                           /* revert to real index */+    else+      glyph_index = font->header.default_char; /* the .notdef glyph */++    new_format = FT_BOOL( font->header.version == 0x300 );+    len        = new_format ? 6 : 4;++    /* jump to glyph entry */+    p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index;++    bitmap->width = FT_NEXT_SHORT_LE( p );++    if ( new_format )+      offset = FT_NEXT_ULONG_LE( p );+    else+      offset = FT_NEXT_USHORT_LE( p );++    if ( offset >= font->header.file_size )+    {+      FT_TRACE2(( "invalid FNT offset\n" ));+      error = FNT_Err_Invalid_File_Format;+      goto Exit;+    }++    /* jump to glyph data */+    p = font->fnt_frame + /* font->header.bits_offset */ + offset;++    /* allocate and build bitmap */+    {+      FT_Memory  memory = FT_FACE_MEMORY( slot->face );+      FT_Int     pitch  = ( bitmap->width + 7 ) >> 3;+      FT_Byte*   column;+      FT_Byte*   write;+++      bitmap->pitch      = pitch;+      bitmap->rows       = font->header.pixel_height;+      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;++      if ( offset + pitch * bitmap->rows >= font->header.file_size )+      {+        FT_TRACE2(( "invalid bitmap width\n" ));+        error = FNT_Err_Invalid_File_Format;+        goto Exit;+      }++      /* note: since glyphs are stored in columns and not in rows we */+      /*       can't use ft_glyphslot_set_bitmap                     */+      if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )+        goto Exit;++      column = (FT_Byte*)bitmap->buffer;++      for ( ; pitch > 0; pitch--, column++ )+      {+        FT_Byte*  limit = p + bitmap->rows;+++        for ( write = column; p < limit; p++, write += bitmap->pitch )+          *write = *p;+      }+    }++    slot->internal->flags = FT_GLYPH_OWN_BITMAP;+    slot->bitmap_left     = 0;+    slot->bitmap_top      = font->header.ascent;+    slot->format          = FT_GLYPH_FORMAT_BITMAP;++    /* now set up metrics */+    slot->metrics.width        = bitmap->width << 6;+    slot->metrics.height       = bitmap->rows << 6;+    slot->metrics.horiAdvance  = bitmap->width << 6;+    slot->metrics.horiBearingX = 0;+    slot->metrics.horiBearingY = slot->bitmap_top << 6;++    ft_synthesize_vertical_metrics( &slot->metrics,+                                    bitmap->rows << 6 );++  Exit:+    return error;+  }+++  static FT_Error+  winfnt_get_header( FT_Face               face,+                     FT_WinFNT_HeaderRec  *aheader )+  {+    FNT_Font  font = ((FNT_Face)face)->font;+++    *aheader = font->header;++    return 0;+  }+++  static const FT_Service_WinFntRec  winfnt_service_rec =+  {+    winfnt_get_header+  };++ /*+  *  SERVICE LIST+  *+  */++  static const FT_ServiceDescRec  winfnt_services[] =+  {+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT },+    { FT_SERVICE_ID_WINFNT,    &winfnt_service_rec },+    { NULL, NULL }+  };+++  static FT_Module_Interface+  winfnt_get_service( FT_Driver         driver,+                      const FT_String*  service_id )+  {+    FT_UNUSED( driver );++    return ft_service_list_lookup( winfnt_services, service_id );+  }+++++  FT_CALLBACK_TABLE_DEF+  const FT_Driver_ClassRec  winfnt_driver_class =+  {+    {+      FT_MODULE_FONT_DRIVER        |+      FT_MODULE_DRIVER_NO_OUTLINES,+      sizeof ( FT_DriverRec ),++      "winfonts",+      0x10000L,+      0x20000L,++      0,++      (FT_Module_Constructor)0,+      (FT_Module_Destructor) 0,+      (FT_Module_Requester)  winfnt_get_service+    },++    sizeof( FNT_FaceRec ),+    sizeof( FT_SizeRec ),+    sizeof( FT_GlyphSlotRec ),++    (FT_Face_InitFunc)        FNT_Face_Init,+    (FT_Face_DoneFunc)        FNT_Face_Done,+    (FT_Size_InitFunc)        0,+    (FT_Size_DoneFunc)        0,+    (FT_Slot_InitFunc)        0,+    (FT_Slot_DoneFunc)        0,++#ifdef FT_CONFIG_OPTION_OLD_INTERNALS+    ft_stub_set_char_sizes,+    ft_stub_set_pixel_sizes,+#endif+    (FT_Slot_LoadFunc)        FNT_Load_Glyph,++    (FT_Face_GetKerningFunc)  0,+    (FT_Face_AttachFunc)      0,+    (FT_Face_GetAdvancesFunc) 0,++    (FT_Size_RequestFunc)     FNT_Size_Request,+    (FT_Size_SelectFunc)      FNT_Size_Select+  };+++/* END */
+ src/winfonts/winfnt.h view
@@ -0,0 +1,171 @@+/***************************************************************************/+/*                                                                         */+/*  winfnt.h                                                               */+/*                                                                         */+/*    FreeType font driver for Windows FNT/FON files                       */+/*                                                                         */+/*  Copyright 1996-2001, 2002, 2003, 2004, 2007 by                         */+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */+/*  Copyright 2007 Dmitry Timoshkov for Codeweavers                        */+/*                                                                         */+/*  This file is part of the FreeType project, and may only be used,       */+/*  modified, and distributed under the terms of the FreeType project      */+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */+/*  this file you indicate that you have read the license and              */+/*  understand and accept it fully.                                        */+/*                                                                         */+/***************************************************************************/+++#ifndef __WINFNT_H__+#define __WINFNT_H__+++#include <ft2build.h>+#include FT_WINFONTS_H+#include FT_INTERNAL_DRIVER_H+++FT_BEGIN_HEADER++#ifdef FT_CONFIG_OPTION_PIC+#error "this module does not support PIC yet"+#endif ++  typedef struct  WinMZ_HeaderRec_+  {+    FT_UShort  magic;+    /* skipped content */+    FT_UShort  lfanew;++  } WinMZ_HeaderRec;+++  typedef struct  WinNE_HeaderRec_+  {+    FT_UShort  magic;+    /* skipped content */+    FT_UShort  resource_tab_offset;+    FT_UShort  rname_tab_offset;++  } WinNE_HeaderRec;+++  typedef struct  WinPE32_HeaderRec_+  {+    FT_ULong   magic;+    FT_UShort  machine;+    FT_UShort  number_of_sections;+    /* skipped content */+    FT_UShort  size_of_optional_header;+    /* skipped content */+    FT_UShort  magic32;+    /* skipped content */+    FT_ULong   rsrc_virtual_address;+    FT_ULong   rsrc_size;+    /* skipped content */++  } WinPE32_HeaderRec;+++  typedef struct  WinPE32_SectionRec_+  {+    FT_Byte   name[8];+    /* skipped content */+    FT_ULong  virtual_address;+    FT_ULong  size_of_raw_data;+    FT_ULong  pointer_to_raw_data;+    /* skipped content */++  } WinPE32_SectionRec;+++  typedef struct  WinPE_RsrcDirRec_+  {+    FT_ULong   characteristics;+    FT_ULong   time_date_stamp;+    FT_UShort  major_version;+    FT_UShort  minor_version;+    FT_UShort  number_of_named_entries;+    FT_UShort  number_of_id_entries;++  } WinPE_RsrcDirRec;+++  typedef struct  WinPE_RsrcDirEntryRec_+  {+    FT_ULong  name;+    FT_ULong  offset;++  } WinPE_RsrcDirEntryRec;+++  typedef struct  WinPE_RsrcDataEntryRec_+  {+    FT_ULong  offset_to_data;+    FT_ULong  size;+    FT_ULong  code_page;+    FT_ULong  reserved;++  } WinPE_RsrcDataEntryRec;+++  typedef struct  WinNameInfoRec_+  {+    FT_UShort  offset;+    FT_UShort  length;+    FT_UShort  flags;+    FT_UShort  id;+    FT_UShort  handle;+    FT_UShort  usage;++  } WinNameInfoRec;+++  typedef struct  WinResourceInfoRec_+  {+    FT_UShort  type_id;+    FT_UShort  count;++  } WinResourceInfoRec;+++#define WINFNT_MZ_MAGIC  0x5A4D+#define WINFNT_NE_MAGIC  0x454E+#define WINFNT_PE_MAGIC  0x4550+++  typedef struct  FNT_FontRec_+  {+    FT_ULong             offset;++    FT_WinFNT_HeaderRec  header;++    FT_Byte*             fnt_frame;+    FT_ULong             fnt_size;+    FT_String*           family_name;++  } FNT_FontRec, *FNT_Font;+++  typedef struct  FNT_FaceRec_+  {+    FT_FaceRec     root;+    FNT_Font       font;++    FT_CharMap     charmap_handle;+    FT_CharMapRec  charmap;  /* a single charmap per face */++  } FNT_FaceRec, *FNT_Face;+++  FT_EXPORT_VAR( const FT_Driver_ClassRec )  winfnt_driver_class;+++FT_END_HEADER+++#endif /* __WINFNT_H__ */+++/* END */