Initial commit
This commit is contained in:
commit
ca93f7224c
52 changed files with 7770 additions and 0 deletions
84
luaharfbuzz/src/harfbuzz.lua
Normal file
84
luaharfbuzz/src/harfbuzz.lua
Normal file
|
@ -0,0 +1,84 @@
|
|||
local hb = require("luaharfbuzz")
|
||||
|
||||
-- special tags
|
||||
hb.Tag.NONE = hb.Tag.new()
|
||||
|
||||
-- special script codes (ISO 15924)
|
||||
hb.Script.COMMON = hb.Script.new("Zyyy")
|
||||
hb.Script.INHERITED = hb.Script.new("Zinh")
|
||||
hb.Script.UNKNOWN = hb.Script.new("Zzzz")
|
||||
hb.Script.INVALID = hb.Script.from_iso15924_tag(hb.Tag.NONE)
|
||||
|
||||
-- directions
|
||||
hb.Direction.INVALID = hb.Direction.new("invalid")
|
||||
hb.Direction.LTR = hb.Direction.new("ltr")
|
||||
hb.Direction.RTL = hb.Direction.new("rtl")
|
||||
hb.Direction.TTB = hb.Direction.new("ttb")
|
||||
hb.Direction.BTT = hb.Direction.new("btt")
|
||||
|
||||
-- special languages
|
||||
hb.Language.INVALID = hb.Language.new()
|
||||
|
||||
hb.shape = function(font, buf, options)
|
||||
options = options or { }
|
||||
|
||||
-- Apply options to buffer if they are set.
|
||||
if options.language then buf:set_language(options.language) end
|
||||
if options.script then buf:set_script(options.script) end
|
||||
if options.direction then buf:set_direction(options.direction) end
|
||||
|
||||
-- Guess segment properties, in case all steps above have failed
|
||||
-- to set the right properties.
|
||||
buf:guess_segment_properties()
|
||||
|
||||
local features = {}
|
||||
|
||||
-- Parse features
|
||||
if type(options.features) == "string" then
|
||||
for fs in string.gmatch(options.features, '([^,]+)') do
|
||||
local feature = hb.Feature.new(fs)
|
||||
if feature then
|
||||
table.insert(features, hb.Feature.new(fs))
|
||||
else
|
||||
error(string.format("Invalid feature string: '%s'", fs))
|
||||
end
|
||||
end
|
||||
elseif type(options.features) == "table" then
|
||||
features = options.features
|
||||
elseif options.features then -- non-nil but not a string or table
|
||||
error("Invalid features option")
|
||||
end
|
||||
|
||||
return hb.shape_full(font,buf,features,options.shapers or {})
|
||||
end
|
||||
|
||||
-- For backward compatibility
|
||||
hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = hb.Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES
|
||||
hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = hb.Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS
|
||||
hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = hb.Buffer.CLUSTER_LEVEL_CHARACTERS
|
||||
hb.Buffer.HB_BUFFER_CLUSTER_LEVEL_DEFAULT = hb.Buffer.CLUSTER_LEVEL_DEFAULT
|
||||
|
||||
hb.Tag.HB_TAG_NONE = hb.Tag.NONE
|
||||
|
||||
hb.Script.HB_SCRIPT_COMMON = hb.Script.COMMON
|
||||
hb.Script.HB_SCRIPT_INHERITED = hb.Script.INHERITED
|
||||
hb.Script.HB_SCRIPT_UNKNOWN = hb.Script.UNKNOWN
|
||||
hb.Script.HB_SCRIPT_INVALID = hb.Script.INVALID
|
||||
|
||||
hb.Language.HB_LANGUAGE_INVALID = hb.Language.INVALID
|
||||
|
||||
hb.Direction.HB_DIRECTION_INVALID = hb.Direction.INVALID
|
||||
hb.Direction.HB_DIRECTION_LTR = hb.Direction.LTR
|
||||
hb.Direction.HB_DIRECTION_RTL = hb.Direction.RTL
|
||||
hb.Direction.HB_DIRECTION_TTB = hb.Direction.TTB
|
||||
hb.Direction.HB_DIRECTION_BTT = hb.Direction.BTT
|
||||
|
||||
hb.Direction.HB_DIRECTION_IS_VALID = hb.Direction.is_valid
|
||||
hb.Direction.HB_DIRECTION_IS_HORIZONTAL = hb.Direction.is_horizontal
|
||||
hb.Direction.HB_DIRECTION_IS_VERTICAL = hb.Direction.is_vertical
|
||||
hb.Direction.HB_DIRECTION_IS_FORWARD = hb.Direction.is_forward
|
||||
hb.Direction.HB_DIRECTION_IS_BACKWARD = hb.Direction.is_backward
|
||||
|
||||
hb.Buffer.get_glyph_infos_and_positions = hb.Buffer.get_glyphs
|
||||
|
||||
return hb
|
535
luaharfbuzz/src/harfbuzz.luadoc
Normal file
535
luaharfbuzz/src/harfbuzz.luadoc
Normal file
|
@ -0,0 +1,535 @@
|
|||
-----------
|
||||
-- Lua bindings to Harfbuzz.
|
||||
-- * [Wiki](http://github.com/ufytex/luaharfbuzz/wiki)
|
||||
-- * [Source on Github](https://github.com/ufytex/luaharfbuzz)
|
||||
-- * [API Coverage Status](https://github.com/ufytex/luaharfbuzz/blob/master/status/done.txt)
|
||||
--
|
||||
-- @author Deepak Jois <<deepak.jois@gmail.com>>
|
||||
-- @copyright 2016
|
||||
-- @license MIT
|
||||
-- @module harfbuzz
|
||||
|
||||
--- Wraps `hb_version`
|
||||
-- @function version
|
||||
|
||||
--- Wraps `hb_shape`.
|
||||
-- @param font `Font` to use for shaping
|
||||
--
|
||||
-- @param buffer `Buffer` to shape
|
||||
--
|
||||
-- @param[opt] options table containing one or more supported options:
|
||||
--
|
||||
-- * `direction`: A `Direction` object representing the object.
|
||||
-- * `script`: A `Script` object representing the script.
|
||||
-- * `language`: A `Language` object representing the language.
|
||||
-- * `features`: features to enable, specified as either of the following.
|
||||
-- - comma-separated list of features. See [feature string syntax reference](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings)
|
||||
-- - table of `Feature` objects
|
||||
-- @function shape
|
||||
|
||||
--- Lua wrapper for `hb_blob_t` type
|
||||
-- @type Blob
|
||||
|
||||
--- Wraps `hb_blob_create`.
|
||||
-- Initializes a new `hb_blob_t`.
|
||||
-- @param data lua string containing binary or character data.
|
||||
-- @function Blob.new
|
||||
|
||||
--- Wraps `hb_blob_create_from_file`.
|
||||
-- Initializes a new `hb_blob_t`.
|
||||
-- @param filename lua string.
|
||||
-- @function Blob.new_from_file
|
||||
|
||||
--- Wraps `hb_blob_get_length`.
|
||||
-- @function Blob:get_length
|
||||
|
||||
--- Wraps `hb_blob_get_data`.
|
||||
-- @function Blob:get_data
|
||||
|
||||
--- Lua wrapper for `hb_face_t` type
|
||||
-- @type Face
|
||||
|
||||
--- Wraps `hb_face_create`.
|
||||
-- Initializes a new `hb_face_t` from a `Blob` object.
|
||||
-- @param blob `Blob` to read the font from.
|
||||
-- @param[opt=0] font_index index of font to read.
|
||||
-- @function Face.new_from_blob
|
||||
|
||||
--- Create a new `Face` from a file.
|
||||
-- Makes a call to `Face:new_from_blob` after creating a `Blob` from the
|
||||
-- file contents.
|
||||
-- @param file path to font file.
|
||||
-- @param[opt=0] font_index index of font to read.
|
||||
-- @function Face.new
|
||||
|
||||
--- Wraps `hb_face_collect_unicodes`.
|
||||
-- @return table of codepoints supported by the face.
|
||||
-- @function Face:collect_unicodes
|
||||
|
||||
--- Wraps `hb_face_get_glyph_count`.
|
||||
-- @function Face:get_glyph_count
|
||||
|
||||
--- Wraps `hb_face_reference_table`.
|
||||
-- @param tag `Tag` object of the table.
|
||||
-- @return `Blob` object for the face table of `tag`.
|
||||
-- @function Face:get_table
|
||||
|
||||
--- Wraps `hb_face_get_table_tags`.
|
||||
-- @return table of `Tag`s representing face table tags.
|
||||
-- @function Face:get_table_tags
|
||||
|
||||
--- Wraps `hb_face_get_upem`.
|
||||
-- @function Face:get_upem
|
||||
|
||||
--- Wraps `hb_ot_color_has_palettes`.
|
||||
-- @function Face:ot_color_has_palettes
|
||||
|
||||
--- Wraps `hb_ot_color_palette_get_count`.
|
||||
-- @function Face:ot_color_palette_get_count
|
||||
|
||||
--- Wraps `hb_ot_color_palette_get_colors`.
|
||||
-- @function Face:ot_color_palette_get_colors
|
||||
|
||||
--- Wraps `hb_ot_color_has_layers`.
|
||||
-- @function Face:ot_color_has_layers
|
||||
|
||||
--- Wraps `hb_ot_color_glyph_get_layers`.
|
||||
-- @function Face:ot_color_glyph_get_layers
|
||||
|
||||
--- Wraps `hb_ot_color_has_png`.
|
||||
-- @function Face:ot_color_has_png
|
||||
|
||||
--- Wraps `hb_ot_layout_table_get_script_tags`.
|
||||
-- @function Face:ot_layout_get_script_tags
|
||||
|
||||
--- Wraps `hb_ot_layout_script_get_language_tags`.
|
||||
-- @function Face:ot_layout_get_language_tags
|
||||
|
||||
--- Wraps `hb_ot_layout_language_get_feature_tags`.
|
||||
-- @function Face:ot_layout_get_feature_tags
|
||||
|
||||
--- Wraps `hb_ot_layout_table_find_script`.
|
||||
-- @function Face:ot_layout_find_script
|
||||
|
||||
--- Wraps `hb_ot_layout_script_find_language`.
|
||||
-- @function Face:ot_layout_find_language
|
||||
|
||||
--- Wraps `hb_ot_layout_language_find_feature`.
|
||||
-- @function Face:ot_layout_find_feature
|
||||
|
||||
|
||||
--- Lua wrapper for `hb_font_t` type
|
||||
-- @type Font
|
||||
|
||||
--- Wraps `hb_font_create`, and sets up some defaults for scale and shaping functions.
|
||||
-- Initializes a new `hb_font_t` from a `Face` object. Sets the default scale
|
||||
-- to the face’s upem value, and sets the font shaping functions by
|
||||
-- calling `hb_ot_font_set_funcs` on it.
|
||||
-- @param face `Face` object.
|
||||
-- @function Font.new
|
||||
|
||||
--- Wraps `hb_font_get_scale`.
|
||||
-- @return two values for the x-scale and y-scale of the font.
|
||||
-- @function Font:get_scale
|
||||
|
||||
--- Wraps `hb_font_set_scale`.
|
||||
-- @param x_scale desired x-scale of font.
|
||||
-- @param y_scale desired y-scale of font.
|
||||
-- @function Font:set_scale
|
||||
|
||||
--- Wraps `hb_font_get_h_extents`.
|
||||
-- @return font extents table for horizontal direction, contains the following
|
||||
-- or `nil` if HarfBuzz fails to load font extents:
|
||||
--
|
||||
-- * `ascender`: typographic ascender.
|
||||
-- * `descender`: typographic descender.
|
||||
-- * `line_gap`: line spacing gap.
|
||||
-- @function Font:get_h_extents
|
||||
|
||||
--- Wraps `hb_font_get_v_extents`.
|
||||
-- @return font extents table for vertical direction, similar to
|
||||
-- `Font:get_h_extents`, or `nil` if HarfBuzz fails to load font extents:
|
||||
-- @function Font:get_v_extents
|
||||
|
||||
--- Wraps `hb_font_get_glyph_extents`.
|
||||
-- @param glyph index inside the font.
|
||||
-- @return extents table contains the following or `nil` if HarfBuzz fails to
|
||||
-- load glyph extents:
|
||||
--
|
||||
-- * `x_bearing`: left side of glyph from origin.
|
||||
-- * `y_bearing`: top side of glyph from origin.
|
||||
-- * `width`: distance from left to right side.
|
||||
-- * `height`: distance from top to bottom side.
|
||||
-- @function Font:get_glyph_extents
|
||||
|
||||
--- Wraps `hb_font_get_glyph_name`.
|
||||
-- @param glyph index inside the font.
|
||||
-- @return name of the glyph or nil.
|
||||
-- @function Font:get_glyph_name
|
||||
|
||||
--- Wraps `hb_font_get_glyph_from_name`.
|
||||
-- @param name of the glyph.
|
||||
-- @return glyph index inside the font or nil.
|
||||
-- @function Font:get_glyph_from_name
|
||||
|
||||
--- Wraps `hb_font_get_glyph_h_advance`.
|
||||
-- @param glyph index inside the font.
|
||||
-- @return advance glyph advance of the glyph in horizontal direction.
|
||||
-- @function Font:get_glyph_h_advance
|
||||
|
||||
--- Wraps `hb_font_get_glyph_v_advance`.
|
||||
-- @param glyph index inside the font.
|
||||
-- @return advance glyph advance of the glyph in vertical direction.
|
||||
-- @function Font:get_glyph_v_advance
|
||||
|
||||
--- Wraps `hb_font_get_nominal_glyph`.
|
||||
-- @param codepoint.
|
||||
-- @return glyph index or `nil` if `codepoint` is not supported by the font.
|
||||
-- @function Font:get_nominal_glyph
|
||||
|
||||
--- Wraps `hb_ot_color_glyph_get_png`.
|
||||
-- @function Font:ot_color_glyph_get_png
|
||||
|
||||
--- Lua wrapper for `hb_buffer_t` type.
|
||||
-- @type Buffer
|
||||
|
||||
--- Wraps `hb_buffer_create`.
|
||||
-- @function Buffer.new
|
||||
|
||||
--- Wraps `hb_buffer_add_utf8`.
|
||||
-- @param text UTF8 encoded string.
|
||||
-- @param[opt=0] item_offset 0-indexed offset in `text`, from where to start adding.
|
||||
-- @param[opt=-1] item_length length to add from `item_offset`. `-1` adds till end of `text`.
|
||||
-- @function Buffer:add_utf8
|
||||
|
||||
--- Wraps `hb_buffer_add_codepoints`.
|
||||
-- @param text table with codepoints as lua numbers.
|
||||
-- @param[opt=0] item_offset 0-indexed offset in `text`, from where to start adding.
|
||||
-- @param[opt=-1] item_length length to add from `item_offset`. `-1` adds till end of `text`.
|
||||
-- @function Buffer:add_codepoints
|
||||
|
||||
--- Wraps `hb_buffer_set_direction`.
|
||||
-- @param dir A `Direction` object.
|
||||
-- @function Buffer:set_direction
|
||||
|
||||
--- Wraps `hb_buffer_get_direction`.
|
||||
-- @return A `Direction` object.
|
||||
-- @function Buffer:get_direction
|
||||
|
||||
--- Wraps `hb_buffer_set_script`.
|
||||
-- @param script A `Script` object.
|
||||
-- @function Buffer:set_script
|
||||
|
||||
--- Wraps `hb_buffer_get_script`.
|
||||
-- @return A `Script` object.
|
||||
-- @function Buffer:get_script
|
||||
|
||||
--- Wraps `hb_buffer_set_language`.
|
||||
-- @param lang A `Language` object
|
||||
-- @function Buffer:set_language
|
||||
|
||||
--- Wraps `hb_buffer_get_language`.
|
||||
-- @return A `Language` object
|
||||
-- @function Buffer:get_language
|
||||
|
||||
--- Wraps `hb_buffer_reverse`.
|
||||
-- @function Buffer:reverse
|
||||
|
||||
--- Wraps `hb_buffer_get_length`.
|
||||
-- @function Buffer:get_length
|
||||
|
||||
--- Wraps `hb_buffer_get_cluster_level`.
|
||||
-- @return see [Cluster Levels](#Cluster_Levels)
|
||||
-- @function Buffer:get_cluster_level
|
||||
|
||||
--- Wraps `hb_buffer_set_cluster_level`.
|
||||
-- @param level see [Cluster Levels](#Cluster_Levels)
|
||||
-- @function Buffer:set_cluster_level
|
||||
|
||||
--- Wraps `hb_buffer_guess_segment_properties`.
|
||||
-- @function Buffer:guess_segment_properties
|
||||
|
||||
--- Helper method to get shaped glyph data.
|
||||
-- Calls `hb_buffer_get_glyph_infos`, `hb_buffer_get_glyph_positions` and
|
||||
-- `hb_glyph_info_get_glyph_flags`, and assembles the data into a Lua table.
|
||||
-- @return table containing data for each glyph, in a nested table. Each nested
|
||||
-- table contains the following:
|
||||
--
|
||||
-- * `x_advance`: horizontal advance.
|
||||
-- * `y_advance`: vertical advance.
|
||||
-- * `x_offset`: horizontal displacement.
|
||||
-- * `y_offset`: vertical displacement.
|
||||
-- * `cluster`: glyph cluster index within input.
|
||||
-- * `codepoint`: glyph index inside the font _(this field name is a bit misleading, but that’s what Harfbuzz uses)_.
|
||||
-- * `flags`: glyph flags
|
||||
-- @function Buffer:get_glyphs
|
||||
|
||||
--- Cluster Levels.
|
||||
-- See [Harfbuzz docs](http://behdad.github.io/harfbuzz/clusters.html) for more details
|
||||
-- about what each of these levels mean.
|
||||
-- @section
|
||||
|
||||
--- Wraps `HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES`.
|
||||
-- @field Buffer.CLUSTER_LEVEL_MONOTONE_GRAPHEMES
|
||||
|
||||
--- Wraps `HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS`.
|
||||
-- @field Buffer.CLUSTER_LEVEL_MONOTONE_CHARACTERS
|
||||
|
||||
--- Wraps `HB_BUFFER_CLUSTER_LEVEL_CHARACTERS`.
|
||||
-- @field Buffer.CLUSTER_LEVEL_CHARACTERS
|
||||
|
||||
--- Wraps `HB_BUFFER_CLUSTER_LEVEL_DEFAULT`.
|
||||
-- @field Buffer.CLUSTER_LEVEL_DEFAULT
|
||||
|
||||
--- Wraps `HB_GLYPH_FLAG_UNSAFE_TO_BREAK`.
|
||||
-- @field Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
|
||||
|
||||
--- Wraps `HB_GLYPH_FLAG_DEFINED`.
|
||||
-- @field Buffer.GLYPH_FLAG_DEFINED
|
||||
|
||||
--- Lua wrapper for `hb_feature_t` type
|
||||
-- @type Feature
|
||||
|
||||
--- Wraps `hb_feature_from_string`
|
||||
-- @param feature_string See [feature string syntax reference](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings)
|
||||
-- @function Feature.new
|
||||
|
||||
--- Wraps `hb_feature_to_string`.
|
||||
-- Enables nice output with `tostring(…)`.
|
||||
-- @function Feature:__tostring
|
||||
|
||||
--- Lua wrapper for `hb_tag_t` type.
|
||||
-- @type Tag
|
||||
|
||||
--- Wraps `hb_tag_from_string`.
|
||||
-- @param string to be converted to a `Tag` object.
|
||||
-- @return a `Tag` object.
|
||||
-- @function Tag.new
|
||||
|
||||
--- Wraps `hb_tag_to_string`. Enable nice output with `tostring(…)`.
|
||||
-- @return Returns a string representation for the tag object.
|
||||
-- @function Tag:__to_string
|
||||
|
||||
--- Enables equality comparisions with `==` between two tags.
|
||||
-- @return `true` or `false` depending on whether the two tags are equal.
|
||||
-- @function Tag:__eq
|
||||
|
||||
|
||||
--- Lua wrapper for `hb_script_t` type.
|
||||
-- @type Script
|
||||
|
||||
--- Wraps `hb_script_from_string`.
|
||||
-- @param script 4-letter script code according to the [ISO 15924 standard](http://www.unicode.org/iso15924/iso15924-num.html).
|
||||
-- @return a `Script` object.
|
||||
-- @function Script.new
|
||||
|
||||
--- Wraps `hb_script_from_iso15924_tag`
|
||||
-- @param tag a `Tag` object representing a [ISO 15924 script](http://www.unicode.org/iso15924/iso15924-num.html).
|
||||
-- @function Script.from_iso15924_tag
|
||||
|
||||
--- Wraps `hb_script_to_iso15924_tag`.
|
||||
-- @return a `Tag` object representing the script.
|
||||
-- @function Script:to_iso15924_tag
|
||||
|
||||
--- Enable nice output with `tostring(…)`
|
||||
-- @return Returns a 4-letter [ISO 15924 script code](http://www.unicode.org/iso15924/iso15924-num.html) for the script object.
|
||||
-- @function Script:__to_string
|
||||
|
||||
--- Enables equality comparisions with `==` between two scripts.
|
||||
-- @return `true` or `false` depending on whether the two scripts are equal.
|
||||
-- @function Script:__eq
|
||||
|
||||
--- Predefined Script Codes.
|
||||
-- Predefined directions that correspond to their original definitions in Harfbuzz.
|
||||
-- @section
|
||||
|
||||
--- Wraps `HB_SCRIPT_COMMON`.
|
||||
-- @field Script.COMMON
|
||||
|
||||
--- Wraps `HB_SCRIPT_INHERITED`.
|
||||
-- @field Script.INHERITED
|
||||
|
||||
--- Wraps `HB_SCRIPT_UNKNOWN`.
|
||||
-- @field Script.UNKNOWN
|
||||
|
||||
--- Wraps `HB_SCRIPT_INVALID`.
|
||||
-- @field Script.INVALID
|
||||
|
||||
--- Lua wrapper for `hb_direction_t` type.
|
||||
-- @type Direction
|
||||
|
||||
--- Wraps `hb_direction_from_string`.
|
||||
-- @param dir can be one of `ltr`, `rtl`, `ttb`, `btt` or `invalid`.
|
||||
-- @return a `Direction` object.
|
||||
-- @function Direction.new
|
||||
|
||||
--- Wraps `hb_direction_to_string`. Enable nice output with `tostring(…)`.
|
||||
-- @return Returns a string representation for direction.
|
||||
-- @function Direction:__to_string
|
||||
|
||||
--- Enables equality comparisions with `==` between two directions.
|
||||
-- @return `true` or `false` depending on whether the two tags are equal.
|
||||
-- @function Direction:__eq
|
||||
|
||||
--- Wraps `HB_DIRECTION_IS_VALID`.
|
||||
-- @return a boolean value
|
||||
-- @function Direction:is_valid
|
||||
|
||||
--- Wraps `HB_DIRECTION_IS_HORIZONTAL`.
|
||||
-- @return a boolean value
|
||||
-- @function Direction:is_horizontal
|
||||
|
||||
--- Wraps `HB_DIRECTION_IS_VERTICAL`.
|
||||
-- @return a boolean value
|
||||
-- @function Direction:is_vertical
|
||||
|
||||
--- Wraps `HB_DIRECTION_IS_FORWARD`.
|
||||
-- @return a boolean value
|
||||
-- @function Direction:is_forward
|
||||
|
||||
--- Wraps `HB_DIRECTION_IS_BACKWARD`.
|
||||
-- @return a boolean value
|
||||
-- @function Direction:is_backward
|
||||
|
||||
--- Predefined directions.
|
||||
-- Predefined directions that correspond to their original definitions in Harfbuzz.
|
||||
-- @section
|
||||
|
||||
--- Wraps `HB_DIRECTION_LTR`.
|
||||
-- @field Direction.LTR
|
||||
|
||||
--- Wraps `HB_DIRECTION_RTL`.
|
||||
-- @field Direction.RTL
|
||||
|
||||
--- Wraps `HB_DIRECTION_TTB`.
|
||||
-- @field Direction.TTB
|
||||
|
||||
--- Wraps `HB_DIRECTION_LTR`.
|
||||
-- @field Direction.BTT
|
||||
|
||||
--- Lua wrapper for `hb_language_t` type.
|
||||
-- @type Language
|
||||
|
||||
--- Wraps `hb_language_from_string`.
|
||||
-- @param lang [three-letter language tag](http://www.microsoft.com/typography/otspec/languagetags.htm) to be converted to a `Language` object.
|
||||
-- @return a `Language` object.
|
||||
-- @function Language.new
|
||||
|
||||
--- Wraps `hb_language_to_string`. Enable nice output with `tostring(…)`.
|
||||
-- @return Returns a string representation for the language object.
|
||||
-- @function Language:__to_string
|
||||
|
||||
--- Enables equality comparisions with `==` between two languages.
|
||||
-- @return `true` or `false` depending on whether the two languages are equal.
|
||||
-- @function Language:__eq
|
||||
|
||||
--- Predefined languages.
|
||||
-- Predefined languages that correspond to their original definitions in Harfbuzz.
|
||||
-- @section
|
||||
|
||||
--- Wraps `HB_LANGUAGE_INVALID`.
|
||||
-- @field Language.INVALID
|
||||
|
||||
|
||||
--- Unicode functions.
|
||||
-- @section
|
||||
|
||||
--- Wraps `hb_unicode_script`
|
||||
-- @param char Unicode codepoint
|
||||
-- @return a `Script` object.
|
||||
-- @function unicode.script
|
||||
|
||||
|
||||
--- Predefined Name IDs.
|
||||
-- Predefined OpenType 'name' table name identifier.
|
||||
-- @section
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_COPYRIGHT`
|
||||
-- @field ot.NAME_ID_COPYRIGHT
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_FONT_FAMILY`
|
||||
-- @field ot.NAME_ID_FONT_FAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_FONT_SUBFAMILY`
|
||||
-- @field ot.NAME_ID_FONT_SUBFAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_UNIQUE_ID`
|
||||
-- @field ot.NAME_ID_UNIQUE_ID
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_FULL_NAME`
|
||||
-- @field ot.NAME_ID_FULL_NAME
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_VERSION_STRING`
|
||||
-- @field ot.NAME_ID_VERSION_STRING
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_POSTSCRIPT_NAME`
|
||||
-- @field ot.NAME_ID_POSTSCRIPT_NAME
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_TRADEMARK`
|
||||
-- @field ot.NAME_ID_TRADEMARK
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_MANUFACTURER`
|
||||
-- @field ot.NAME_ID_MANUFACTURER
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_DESIGNER`
|
||||
-- @field ot.NAME_ID_DESIGNER
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_DESCRIPTION`
|
||||
-- @field ot.NAME_ID_DESCRIPTION
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_VENDOR_URL`
|
||||
-- @field ot.NAME_ID_VENDOR_URL
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_DESIGNER_URL`
|
||||
-- @field ot.NAME_ID_DESIGNER_URL
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_LICENSE`
|
||||
-- @field ot.NAME_ID_LICENSE
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_LICENSE_URL`
|
||||
-- @field ot.NAME_ID_LICENSE_URL
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY`
|
||||
-- @field ot.NAME_ID_TYPOGRAPHIC_FAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY`
|
||||
-- @field ot.NAME_ID_TYPOGRAPHIC_SUBFAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_MAC_FULL_NAME`
|
||||
-- @field ot.NAME_ID_MAC_FULL_NAME
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_SAMPLE_TEXT`
|
||||
-- @field ot.NAME_ID_SAMPLE_TEXT
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_CID_FINDFONT_NAME`
|
||||
-- @field ot.NAME_ID_CID_FINDFONT_NAME
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_WWS_FAMILY`
|
||||
-- @field ot.NAME_ID_WWS_FAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_WWS_SUBFAMILY`
|
||||
-- @field ot.NAME_ID_WWS_SUBFAMILY
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_LIGHT_BACKGROUND`
|
||||
-- @field ot.NAME_ID_LIGHT_BACKGROUND
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_DARK_BACKGROUND`
|
||||
-- @field ot.NAME_ID_DARK_BACKGROUND
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_VARIATIONS_PS_PREFIX`
|
||||
-- @field ot.NAME_ID_VARIATIONS_PS_PREFIX
|
||||
|
||||
--- Wraps `HB_OT_NAME_ID_INVALID`
|
||||
-- @field ot.NAME_ID_INVALID
|
||||
|
||||
--- Wraps `HB_OT_LAYOUT_NO_SCRIPT_INDEX`
|
||||
-- @field ot.LAYOUT_NO_SCRIPT_INDEX
|
||||
|
||||
--- Wraps `HB_OT_LAYOUT_NO_FEATURE_INDEX`
|
||||
-- @field ot.LAYOUT_NO_FEATURE_INDEX
|
||||
|
||||
--- Wraps `HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX`
|
||||
-- @field ot.LAYOUT_DEFAULT_LANGUAGE_INDEX
|
||||
|
||||
--- Wraps `HB_OT_LAYOUT_NO_VARIATIONS_INDEX`
|
||||
-- @field ot.LAYOUT_NO_VARIATIONS_INDEX
|
60
luaharfbuzz/src/luaharfbuzz/blob.c
Normal file
60
luaharfbuzz/src/luaharfbuzz/blob.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int blob_new(lua_State *L) {
|
||||
Blob *b;
|
||||
size_t data_l;
|
||||
const char *data = luaL_checklstring(L, 1, &data_l);
|
||||
|
||||
b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Blob");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = hb_blob_create(data, data_l, HB_MEMORY_MODE_DUPLICATE, (void*)data, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int blob_new_from_file(lua_State *L) {
|
||||
Blob *b;
|
||||
const char *file_name = luaL_checkstring(L, 1);
|
||||
|
||||
b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Blob");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = hb_blob_create_from_file(file_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int blob_get_length(lua_State *L) {
|
||||
Blob *b = (Blob *)luaL_checkudata(L, 1, "harfbuzz.Blob");
|
||||
|
||||
lua_pushinteger(L, hb_blob_get_length(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int blob_get_data(lua_State *L) {
|
||||
Blob *b = (Blob *)luaL_checkudata(L, 1, "harfbuzz.Blob");
|
||||
unsigned int l;
|
||||
const char *d;
|
||||
|
||||
d = hb_blob_get_data(*b, &l);
|
||||
lua_pushlstring(L, d, l);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg blob_methods[] = {
|
||||
{ "get_length", blob_get_length },
|
||||
{ "get_data", blob_get_data },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg blob_functions[] = {
|
||||
{ "new", blob_new },
|
||||
{ "new_from_file", blob_new_from_file },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_blob(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Blob", blob_methods, blob_functions, NULL);
|
||||
}
|
338
luaharfbuzz/src/luaharfbuzz/buffer.c
Normal file
338
luaharfbuzz/src/luaharfbuzz/buffer.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int buffer_new(lua_State *L) {
|
||||
Buffer *b;
|
||||
|
||||
b = (Buffer *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Buffer");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = hb_buffer_create();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_guess_segment_properties(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_buffer_guess_segment_properties(*b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_direction(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
Direction *dp = (Direction *)lua_newuserdata(L, sizeof(*dp));
|
||||
luaL_getmetatable(L, "harfbuzz.Direction");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*dp = hb_buffer_get_direction(*b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_direction(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
Direction* dir = (Direction *)luaL_checkudata(L, 2, "harfbuzz.Direction");
|
||||
|
||||
hb_buffer_set_direction(*b, *dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_flags(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
lua_pushinteger(L, hb_buffer_get_flags(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_flags(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
unsigned int l = luaL_checkinteger(L, 2);
|
||||
|
||||
hb_buffer_set_flags(*b, l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_language(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
Language *lp = (Language *)lua_newuserdata(L, sizeof(*lp));
|
||||
luaL_getmetatable(L, "harfbuzz.Language");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*lp = hb_buffer_get_language(*b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_language(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
Language *lang = (Language *)luaL_checkudata(L, 2, "harfbuzz.Language");
|
||||
|
||||
hb_buffer_set_language(*b, *lang);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_script(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
|
||||
luaL_getmetatable(L, "harfbuzz.Script");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*sp = hb_buffer_get_script(*b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_script(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
Script *script = (Script *)luaL_checkudata(L, 2, "harfbuzz.Script");
|
||||
|
||||
hb_buffer_set_script(*b, *script);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_invisible_glyph(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
lua_pushinteger(L, hb_buffer_get_invisible_glyph(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_invisible_glyph(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_codepoint_t cp = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
|
||||
hb_buffer_set_invisible_glyph(*b, cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_replacement_codepoint(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
lua_pushinteger(L, hb_buffer_get_replacement_codepoint(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_replacement_codepoint(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_codepoint_t cp = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
|
||||
hb_buffer_set_replacement_codepoint(*b, cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_add(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
unsigned int cluster = luaL_checkinteger(L, 3);
|
||||
|
||||
hb_buffer_add(*b, c, cluster);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_add_codepoints(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
unsigned int item_offset;
|
||||
int item_length;
|
||||
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
item_offset = luaL_optinteger(L, 3, 0);
|
||||
item_length = luaL_optinteger(L, 4, -1);
|
||||
|
||||
int n = lua_rawlen(L, 2);
|
||||
|
||||
hb_codepoint_t *text = (hb_codepoint_t *) malloc(n * sizeof(hb_codepoint_t));
|
||||
|
||||
for (unsigned int i = 0; i != n; ++i) {
|
||||
lua_geti(L, 2, i + 1);
|
||||
hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, -1);
|
||||
text[i] = c;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
hb_buffer_add_codepoints(*b, text, n, item_offset, item_length);
|
||||
|
||||
free(text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_clear_contents(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_buffer_clear_contents(*b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_reset(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_buffer_reset(*b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_add_utf8(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
const char *text;
|
||||
unsigned int item_offset;
|
||||
int item_length;
|
||||
|
||||
text = luaL_checkstring(L, 2);
|
||||
item_offset = luaL_optinteger(L, 3, 0);
|
||||
item_length = luaL_optinteger(L, 4, -1);
|
||||
|
||||
hb_buffer_add_utf8(*b, text, -1, item_offset, item_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_destroy(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_buffer_destroy(*b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_glyphs(lua_State *L) {
|
||||
Buffer *buf = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
// Get glyph info and positions out of buffer
|
||||
unsigned int len = hb_buffer_get_length(*buf);
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(*buf, NULL);
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(*buf, NULL);
|
||||
hb_glyph_flags_t flags;
|
||||
unsigned int i;
|
||||
|
||||
// Create Lua table and push glyph data onto it.
|
||||
lua_createtable(L, len, 0); // parent table
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
lua_pushinteger(L, i+1); // 1-indexed key parent table
|
||||
lua_createtable(L, 0, 7); // child table
|
||||
|
||||
lua_pushinteger(L, info[i].codepoint);
|
||||
lua_setfield(L, -2, "codepoint");
|
||||
|
||||
lua_pushinteger(L, info[i].cluster);
|
||||
lua_setfield(L, -2, "cluster");
|
||||
|
||||
lua_pushnumber(L, pos[i].x_advance);
|
||||
lua_setfield(L, -2, "x_advance");
|
||||
|
||||
lua_pushnumber(L, pos[i].y_advance);
|
||||
lua_setfield(L, -2, "y_advance");
|
||||
|
||||
lua_pushnumber(L, pos[i].x_offset);
|
||||
lua_setfield(L, -2, "x_offset");
|
||||
|
||||
lua_pushnumber(L, pos[i].y_offset);
|
||||
lua_setfield(L, -2, "y_offset");
|
||||
|
||||
flags = hb_glyph_info_get_glyph_flags(&(info[i]));
|
||||
if (flags & HB_GLYPH_FLAG_DEFINED) {
|
||||
lua_pushnumber(L, flags);
|
||||
lua_setfield(L, -2, "flags");
|
||||
}
|
||||
|
||||
lua_settable(L, -3); // Add child table at index i+1 to parent table
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_reverse(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
hb_buffer_reverse(*b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_get_length(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
lua_pushinteger(L, hb_buffer_get_length(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_get_cluster_level(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
lua_pushinteger(L, hb_buffer_get_cluster_level(*b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int buffer_set_cluster_level(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
unsigned int l = luaL_checkinteger(L, 2);
|
||||
|
||||
hb_buffer_set_cluster_level(*b, l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_pre_allocate(lua_State *L) {
|
||||
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
|
||||
|
||||
unsigned int n = luaL_checkinteger(L, 2);
|
||||
|
||||
lua_pushboolean(L, hb_buffer_pre_allocate(*b, n));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg buffer_methods[] = {
|
||||
{ "__gc", buffer_destroy },
|
||||
{ "add", buffer_add },
|
||||
{ "add_utf8", buffer_add_utf8 },
|
||||
{ "add_codepoints", buffer_add_codepoints },
|
||||
{ "clear_contents", buffer_clear_contents },
|
||||
{ "set_direction", buffer_set_direction },
|
||||
{ "get_direction", buffer_get_direction },
|
||||
{ "set_flags", buffer_set_flags },
|
||||
{ "get_flags", buffer_get_flags },
|
||||
{ "set_language", buffer_set_language },
|
||||
{ "get_language", buffer_get_language },
|
||||
{ "set_script", buffer_set_script },
|
||||
{ "get_script", buffer_get_script },
|
||||
{ "set_invisible_glyph", buffer_set_invisible_glyph },
|
||||
{ "get_invisible_glyph", buffer_get_invisible_glyph },
|
||||
{ "set_replacement_codepoint", buffer_set_replacement_codepoint },
|
||||
{ "get_replacement_codepoint", buffer_get_replacement_codepoint },
|
||||
{ "get_glyphs", buffer_get_glyphs },
|
||||
{ "guess_segment_properties", buffer_guess_segment_properties },
|
||||
{ "reset", buffer_reset },
|
||||
{ "reverse", buffer_reverse },
|
||||
{ "get_length", buffer_get_length },
|
||||
{ "get_cluster_level", buffer_get_cluster_level },
|
||||
{ "set_cluster_level", buffer_set_cluster_level },
|
||||
{ "pre_allocate", buffer_pre_allocate },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg buffer_functions[] = {
|
||||
{ "new", buffer_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luahb_constant_t buffer_constants[] = {
|
||||
{ "CLUSTER_LEVEL_MONOTONE_GRAPHEMES", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES },
|
||||
{ "CLUSTER_LEVEL_MONOTONE_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS },
|
||||
{ "CLUSTER_LEVEL_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_CHARACTERS },
|
||||
{ "CLUSTER_LEVEL_DEFAULT", HB_BUFFER_CLUSTER_LEVEL_DEFAULT },
|
||||
{ "FLAG_DEFAULT", HB_BUFFER_FLAG_DEFAULT },
|
||||
{ "FLAG_BOT", HB_BUFFER_FLAG_BOT },
|
||||
{ "FLAG_EOT", HB_BUFFER_FLAG_EOT },
|
||||
{ "FLAG_PRESERVE_DEFAULT_IGNORABLES", HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES },
|
||||
{ "FLAG_REMOVE_DEFAULT_IGNORABLES", HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES },
|
||||
{ "FLAG_DO_NOT_INSERT_DOTTED_CIRCLE", HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE },
|
||||
{ "GLYPH_FLAG_UNSAFE_TO_BREAK", HB_GLYPH_FLAG_UNSAFE_TO_BREAK },
|
||||
{ "GLYPH_FLAG_DEFINED", HB_GLYPH_FLAG_DEFINED },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int register_buffer(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Buffer", buffer_methods, buffer_functions, buffer_constants);
|
||||
}
|
25
luaharfbuzz/src/luaharfbuzz/class_utils.c
Normal file
25
luaharfbuzz/src/luaharfbuzz/class_utils.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Utility functions to create Lua classes.
|
||||
#include "luaharfbuzz.h"
|
||||
|
||||
int register_class(lua_State *L, const char *name, const luaL_Reg *methods, const luaL_Reg *functions, const luahb_constant_t *constants) {
|
||||
luaL_newmetatable(L, name);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
if (constants) {
|
||||
while (constants->name) {
|
||||
lua_pushinteger(L, constants->value);
|
||||
lua_setfield(L, -2, constants->name);
|
||||
constants++;
|
||||
}
|
||||
}
|
||||
luaL_setfuncs(L, methods, 0);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, functions, 0);
|
||||
luaL_getmetatable(L, name);
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
84
luaharfbuzz/src/luaharfbuzz/direction.c
Normal file
84
luaharfbuzz/src/luaharfbuzz/direction.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
// harfbuzz.Feature
|
||||
#include "luaharfbuzz.h"
|
||||
|
||||
static int direction_new(lua_State *L) {
|
||||
Direction *d;
|
||||
const char *dir = luaL_checkstring(L, 1);
|
||||
|
||||
d = (Direction *)lua_newuserdata(L, sizeof(*d));
|
||||
luaL_getmetatable(L, "harfbuzz.Direction");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*d = hb_direction_from_string(dir, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_to_string(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushstring(L, hb_direction_to_string(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_equals(lua_State *L) {
|
||||
Direction* lhs = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
Direction* rhs = (Direction *)luaL_checkudata(L, 2, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, *lhs == *rhs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_is_valid(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, HB_DIRECTION_IS_VALID(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_is_horizontal(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, HB_DIRECTION_IS_HORIZONTAL(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_is_vertical(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, HB_DIRECTION_IS_VERTICAL(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_is_forward(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, HB_DIRECTION_IS_FORWARD(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int direction_is_backward(lua_State *L) {
|
||||
Direction* d = (Direction *)luaL_checkudata(L, 1, "harfbuzz.Direction");
|
||||
|
||||
lua_pushboolean(L, HB_DIRECTION_IS_BACKWARD(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg direction_methods[] = {
|
||||
{ "__tostring", direction_to_string },
|
||||
{ "__eq", direction_equals },
|
||||
{ "is_valid", direction_is_valid },
|
||||
{ "is_horizontal", direction_is_horizontal },
|
||||
{ "is_vertical", direction_is_vertical },
|
||||
{ "is_forward", direction_is_forward },
|
||||
{ "is_backward", direction_is_backward },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg direction_functions[] = {
|
||||
{ "new", direction_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_direction(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Direction", direction_methods, direction_functions, NULL);
|
||||
}
|
466
luaharfbuzz/src/luaharfbuzz/face.c
Normal file
466
luaharfbuzz/src/luaharfbuzz/face.c
Normal file
|
@ -0,0 +1,466 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
/* Size of static arrays we use to avoid heap allocating memory when reading
|
||||
* data from HarfBuzz. */
|
||||
#define STATIC_ARRAY_SIZE 128
|
||||
|
||||
static int face_new(lua_State *L) {
|
||||
Face *f;
|
||||
hb_blob_t *blob;
|
||||
hb_face_t *face;
|
||||
const char *file_name = luaL_checkstring(L, 1);
|
||||
unsigned int face_index = (unsigned int) luaL_optinteger(L, 2, 0);
|
||||
|
||||
blob = hb_blob_create_from_file(file_name);
|
||||
face = hb_face_create(blob, face_index);
|
||||
|
||||
if (blob == hb_blob_get_empty() || face == hb_face_get_empty()) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
f = (Face *)lua_newuserdata(L, sizeof(*f));
|
||||
*f = face;
|
||||
luaL_getmetatable(L, "harfbuzz.Face");
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_new_from_blob(lua_State *L) {
|
||||
Face *f;
|
||||
hb_face_t *face;
|
||||
Blob *blob = luaL_checkudata(L, 1, "harfbuzz.Blob");
|
||||
unsigned int face_index = (unsigned int) luaL_optinteger(L, 2, 0);
|
||||
|
||||
face = hb_face_create(*blob, face_index);
|
||||
|
||||
if (*blob == hb_blob_get_empty() || face == hb_face_get_empty()) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
f = (Face *)lua_newuserdata(L, sizeof(*f));
|
||||
*f = face;
|
||||
luaL_getmetatable(L, "harfbuzz.Face");
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_get_glyph_count(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushinteger(L, hb_face_get_glyph_count(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_get_name(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
hb_ot_name_id_t name_id = (hb_ot_name_id_t) luaL_checkinteger(L, 2);
|
||||
hb_language_t lang = HB_LANGUAGE_INVALID;
|
||||
char name[STATIC_ARRAY_SIZE];
|
||||
unsigned int text_size = STATIC_ARRAY_SIZE, len;
|
||||
|
||||
if (lua_gettop(L) > 2)
|
||||
lang = *((Language*)luaL_checkudata(L, 3, "harfbuzz.Language"));
|
||||
|
||||
len = hb_ot_name_get_utf8(*f, name_id, lang, &text_size, name);
|
||||
if (len) {
|
||||
if (len < STATIC_ARRAY_SIZE) {
|
||||
lua_pushstring(L, name);
|
||||
} else {
|
||||
char *name = malloc(len + 1);
|
||||
text_size = len + 1;
|
||||
hb_ot_name_get_utf8(*f, name_id, lang, &text_size, name);
|
||||
lua_pushstring(L, name);
|
||||
free(name);
|
||||
}
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_get_table(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *t = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
Blob *b;
|
||||
|
||||
b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Blob");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = hb_face_reference_table(*f, *t);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_get_table_tags(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
hb_tag_t tags[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_face_get_table_tags(*f, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0);
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_face_get_table_tags(*f, offset, &count, tags);
|
||||
for (i = 0; i < count; i++) {
|
||||
lua_pushnumber(L, offset + i + 1);
|
||||
|
||||
Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
*tp = tags[i];
|
||||
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_layout_get_script_tags(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
|
||||
hb_tag_t tags[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_ot_layout_table_get_script_tags(*face, *table, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0);
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_ot_layout_table_get_script_tags(*face, *table, offset, &count, tags);
|
||||
for (i = 0; i < count; i++) {
|
||||
lua_pushnumber(L, offset + i + 1);
|
||||
|
||||
Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
*tp = tags[i];
|
||||
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_layout_get_language_tags(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
|
||||
|
||||
hb_tag_t tags[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_ot_layout_script_get_language_tags(*face, *table, script_index, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0);
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_ot_layout_script_get_language_tags(*face, *table, script_index, offset, &count, tags);
|
||||
for (i = 0; i < count; i++) {
|
||||
lua_pushnumber(L, offset + i + 1);
|
||||
|
||||
Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
*tp = tags[i];
|
||||
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_layout_get_feature_tags(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
|
||||
unsigned int language_index = (unsigned int) luaL_checkinteger(L, 4);
|
||||
|
||||
hb_tag_t tags[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_ot_layout_language_get_feature_tags(*face, *table, script_index, language_index, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0);
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_ot_layout_language_get_feature_tags(*face, *table, script_index, language_index, offset, &count, tags);
|
||||
for (i = 0; i < count; i++) {
|
||||
lua_pushnumber(L, offset + i + 1);
|
||||
|
||||
Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
*tp = tags[i];
|
||||
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_layout_find_script(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
Tag *script = (Tag *)luaL_checkudata(L, 3, "harfbuzz.Tag");
|
||||
unsigned int index = 0;
|
||||
|
||||
int found = hb_ot_layout_table_find_script(*face, *table, *script, &index);
|
||||
lua_pushboolean(L, found);
|
||||
lua_pushinteger(L, index);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int face_ot_layout_find_language(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
|
||||
Tag *language = (Tag *)luaL_checkudata(L, 4, "harfbuzz.Tag");
|
||||
unsigned int index = 0;
|
||||
|
||||
int found = hb_ot_layout_script_select_language(*face, *table, script_index, 1, &(*language), &index);
|
||||
lua_pushboolean(L, found);
|
||||
lua_pushinteger(L, index);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int face_ot_layout_find_feature(lua_State *L) {
|
||||
Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
Tag *table = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
unsigned int script_index = (unsigned int) luaL_checkinteger(L, 3);
|
||||
unsigned int language_index = (unsigned int) luaL_checkinteger(L, 4);
|
||||
Tag *feature = (Tag *)luaL_checkudata(L, 5, "harfbuzz.Tag");
|
||||
unsigned int index = 0;
|
||||
|
||||
int found = hb_ot_layout_language_find_feature(*face, *table, script_index, language_index, *feature, &index);
|
||||
lua_pushboolean(L, found);
|
||||
lua_pushinteger(L, index);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int face_collect_unicodes(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
hb_set_t *codes = hb_set_create();
|
||||
|
||||
hb_face_collect_unicodes (*f, codes);
|
||||
lua_createtable(L, hb_set_get_population(codes), 0);
|
||||
if (!hb_set_is_empty(codes)) {
|
||||
unsigned int i = 0;
|
||||
hb_codepoint_t c = HB_SET_VALUE_INVALID;
|
||||
|
||||
while (hb_set_next(codes, &c)) {
|
||||
lua_pushnumber(L, ++i);
|
||||
lua_pushnumber(L, c);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_destroy(codes);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_get_upem(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushinteger(L, hb_face_get_upem(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_has_palettes(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushboolean(L, hb_ot_color_has_palettes(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_palette_get_count(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushinteger(L, hb_ot_color_palette_get_count(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_palette_get_colors(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
unsigned int index = (unsigned int) luaL_optinteger(L, 2, 1) - 1;
|
||||
|
||||
hb_color_t colors[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_ot_color_palette_get_colors(*f, index, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0); // parent table
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_ot_color_palette_get_colors(*f, index, offset, &count, colors);
|
||||
for (i = 0; i < count; i++) {
|
||||
hb_color_t color = colors[i];
|
||||
|
||||
lua_pushnumber(L, offset + i + 1); // 1-indexed key parent table
|
||||
lua_createtable(L, 0, 4); // child table
|
||||
|
||||
lua_pushinteger(L, hb_color_get_red(color));
|
||||
lua_setfield(L, -2, "red");
|
||||
|
||||
lua_pushinteger(L, hb_color_get_green(color));
|
||||
lua_setfield(L, -2, "green");
|
||||
|
||||
lua_pushinteger(L, hb_color_get_blue(color));
|
||||
lua_setfield(L, -2, "blue");
|
||||
|
||||
lua_pushinteger(L, hb_color_get_alpha(color));
|
||||
lua_setfield(L, -2, "alpha");
|
||||
|
||||
lua_settable(L, -3); // Add child table at index i+1 to parent table
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_has_layers(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushboolean(L, hb_ot_color_has_layers(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_glyph_get_layers(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
hb_ot_color_layer_t layers[STATIC_ARRAY_SIZE];
|
||||
unsigned int count = hb_ot_color_glyph_get_layers(*f, gid, 0, NULL, NULL);
|
||||
|
||||
if (count) {
|
||||
unsigned int i = 0, offset = 0;
|
||||
lua_createtable(L, count, 0); // parent table
|
||||
do {
|
||||
count = STATIC_ARRAY_SIZE;
|
||||
hb_ot_color_glyph_get_layers(*f, gid, offset, &count, layers);
|
||||
for (i = 0; i < count; i++) {
|
||||
hb_ot_color_layer_t layer = layers[i];
|
||||
unsigned int color_index = layer.color_index;
|
||||
if (color_index != 0xFFFF)
|
||||
color_index++; // make it 1-indexed
|
||||
|
||||
lua_pushnumber(L, offset + i + 1); // 1-indexed key parent table
|
||||
lua_createtable(L, 0, 2); // child table
|
||||
|
||||
lua_pushinteger(L, layer.glyph);
|
||||
lua_setfield(L, -2, "glyph");
|
||||
|
||||
lua_pushinteger(L, color_index);
|
||||
lua_setfield(L, -2, "color_index");
|
||||
|
||||
lua_settable(L, -3); // Add child table at index i+1 to parent table
|
||||
}
|
||||
offset += count;
|
||||
} while (count == STATIC_ARRAY_SIZE);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_has_png(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushboolean(L, hb_ot_color_has_png(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_has_svg(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
lua_pushboolean(L, hb_ot_color_has_svg(*f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_ot_color_glyph_get_svg(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
hb_blob_t* blob = hb_ot_color_glyph_reference_svg(*f, gid);
|
||||
|
||||
if (hb_blob_get_length(blob) != 0) {
|
||||
Blob *b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Blob");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = blob;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int face_destroy(lua_State *L) {
|
||||
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
hb_face_destroy(*f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg face_methods[] = {
|
||||
{ "__gc", face_destroy },
|
||||
{ "collect_unicodes", face_collect_unicodes },
|
||||
{ "get_glyph_count", face_get_glyph_count },
|
||||
{ "get_name", face_get_name },
|
||||
{ "get_table", face_get_table },
|
||||
{ "get_table_tags", face_get_table_tags },
|
||||
{ "get_upem", face_get_upem },
|
||||
{ "ot_color_has_palettes", face_ot_color_has_palettes },
|
||||
{ "ot_color_palette_get_count", face_ot_color_palette_get_count },
|
||||
{ "ot_color_palette_get_colors", face_ot_color_palette_get_colors },
|
||||
{ "ot_color_has_layers", face_ot_color_has_layers },
|
||||
{ "ot_color_glyph_get_layers", face_ot_color_glyph_get_layers },
|
||||
{ "ot_color_has_png", face_ot_color_has_png },
|
||||
{ "ot_color_has_svg", face_ot_color_has_svg },
|
||||
{ "ot_color_glyph_get_svg", face_ot_color_glyph_get_svg },
|
||||
{ "ot_layout_get_script_tags", face_ot_layout_get_script_tags },
|
||||
{ "ot_layout_get_language_tags", face_ot_layout_get_language_tags },
|
||||
{ "ot_layout_get_feature_tags", face_ot_layout_get_feature_tags },
|
||||
{ "ot_layout_find_script", face_ot_layout_find_script },
|
||||
{ "ot_layout_find_language", face_ot_layout_find_language },
|
||||
{ "ot_layout_find_feature", face_ot_layout_find_feature },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg face_functions[] = {
|
||||
{ "new", face_new },
|
||||
{ "new_from_blob", face_new_from_blob },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_face(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Face", face_methods, face_functions, NULL);
|
||||
}
|
110
luaharfbuzz/src/luaharfbuzz/feature.c
Normal file
110
luaharfbuzz/src/luaharfbuzz/feature.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
// harfbuzz.Feature
|
||||
#include "luaharfbuzz.h"
|
||||
|
||||
static int feature_new(lua_State *L) {
|
||||
Feature f;
|
||||
const char *feature = luaL_checkstring(L, 1);
|
||||
|
||||
if (hb_feature_from_string(feature, -1, &f)) {
|
||||
Feature *fp = (Feature *)lua_newuserdata(L, sizeof(*fp));
|
||||
luaL_getmetatable(L, "harfbuzz.Feature");
|
||||
lua_setmetatable(L, -2);
|
||||
*fp = f;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int feature_to_string(lua_State *L) {
|
||||
Feature* f = (Feature *)luaL_checkudata(L, 1, "harfbuzz.Feature");
|
||||
char feature[128];
|
||||
|
||||
hb_feature_to_string(f, feature, 128);
|
||||
lua_pushstring(L, feature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *feature_tag_ptr;
|
||||
static const char *feature_value_ptr;
|
||||
static const char *feature_start_ptr;
|
||||
static const char *feature_end_ptr;
|
||||
|
||||
static int feature_index(lua_State *L) {
|
||||
Feature* f = (Feature *)luaL_checkudata(L, 1, "harfbuzz.Feature");
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if (key == feature_tag_ptr) {
|
||||
Tag *tag = (Tag *)lua_newuserdata(L, sizeof(*tag));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
*tag = f->tag;
|
||||
} else if (key == feature_value_ptr) {
|
||||
lua_pushinteger(L, f->value);
|
||||
} else if (key == feature_start_ptr) {
|
||||
if (f->start == HB_FEATURE_GLOBAL_START)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushinteger(L, f->start);
|
||||
} else if (key == feature_end_ptr) {
|
||||
if (f->end == HB_FEATURE_GLOBAL_END)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushinteger(L, f->end);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int feature_newindex(lua_State *L) {
|
||||
Feature* f = (Feature *)luaL_checkudata(L, 1, "harfbuzz.Feature");
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if (key == feature_tag_ptr) {
|
||||
f->tag = *(Tag *)luaL_checkudata(L, 3, "harfbuzz.Tag");
|
||||
} else if (key == feature_value_ptr) {
|
||||
f->value = luaL_checkinteger(L, 3);
|
||||
} else if (key == feature_start_ptr) {
|
||||
if (lua_toboolean(L, 3))
|
||||
f->start = luaL_checkinteger(L, 3);
|
||||
else
|
||||
f->start = HB_FEATURE_GLOBAL_START;
|
||||
} else if (key == feature_end_ptr) {
|
||||
if (lua_toboolean(L, 3))
|
||||
f->end = luaL_checkinteger(L, 3);
|
||||
else
|
||||
f->end = HB_FEATURE_GLOBAL_END;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg feature_methods[] = {
|
||||
{ "__index", feature_index },
|
||||
{ "__newindex", feature_newindex },
|
||||
{ "__tostring", feature_to_string },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static const struct luaL_Reg feature_functions[] = {
|
||||
{ "new", feature_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_feature(lua_State *L) {
|
||||
lua_pushliteral(L, "tag");
|
||||
feature_tag_ptr = lua_tostring(L, -1);
|
||||
(void) luaL_ref (L, LUA_REGISTRYINDEX);
|
||||
lua_pushliteral(L, "value");
|
||||
feature_value_ptr = lua_tostring(L, -1);
|
||||
(void) luaL_ref (L, LUA_REGISTRYINDEX);
|
||||
lua_pushliteral(L, "start");
|
||||
feature_start_ptr = lua_tostring(L, -1);
|
||||
(void) luaL_ref (L, LUA_REGISTRYINDEX);
|
||||
lua_pushliteral(L, "_end"); /* _end instead of end to avoid Lua keyword */
|
||||
feature_end_ptr = lua_tostring(L, -1);
|
||||
(void) luaL_ref (L, LUA_REGISTRYINDEX);
|
||||
|
||||
return register_class(L, "harfbuzz.Feature", feature_methods, feature_functions, NULL);
|
||||
}
|
218
luaharfbuzz/src/luaharfbuzz/font.c
Normal file
218
luaharfbuzz/src/luaharfbuzz/font.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int font_new(lua_State *L) {
|
||||
Font *f;
|
||||
Face *face = luaL_checkudata(L, 1, "harfbuzz.Face");
|
||||
|
||||
f = (Font *)lua_newuserdata(L, sizeof(*f));
|
||||
luaL_getmetatable(L, "harfbuzz.Font");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*f = hb_font_create(*face);
|
||||
|
||||
// Set default scale to be the face's upem value
|
||||
unsigned int upem = hb_face_get_upem(*face);
|
||||
hb_font_set_scale(*f, upem, upem);
|
||||
|
||||
// Set shaping functions to OpenType functions
|
||||
hb_ot_font_set_funcs(*f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_set_scale(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
int x_scale = luaL_checkinteger(L, 2);
|
||||
int y_scale = luaL_checkinteger(L, 3);
|
||||
|
||||
hb_font_set_scale(*f, x_scale, y_scale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int font_get_scale(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
int x_scale, y_scale;
|
||||
|
||||
hb_font_get_scale(*f, &x_scale, &y_scale);
|
||||
|
||||
lua_pushinteger(L, x_scale);
|
||||
lua_pushinteger(L, y_scale);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int font_get_h_extents(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_font_extents_t extents;
|
||||
|
||||
if (hb_font_get_h_extents(*f, &extents)) {
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
lua_pushnumber(L, extents.ascender);
|
||||
lua_setfield(L, -2, "ascender");
|
||||
|
||||
lua_pushnumber(L, extents.descender);
|
||||
lua_setfield(L, -2, "descender");
|
||||
|
||||
lua_pushnumber(L, extents.line_gap);
|
||||
lua_setfield(L, -2, "line_gap");
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_v_extents(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_font_extents_t extents;
|
||||
|
||||
if (hb_font_get_v_extents(*f, &extents)) {
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
lua_pushnumber(L, extents.ascender);
|
||||
lua_setfield(L, -2, "ascender");
|
||||
|
||||
lua_pushnumber(L, extents.descender);
|
||||
lua_setfield(L, -2, "descender");
|
||||
|
||||
lua_pushnumber(L, extents.line_gap);
|
||||
lua_setfield(L, -2, "line_gap");
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_glyph_extents(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
||||
hb_glyph_extents_t extents;
|
||||
|
||||
if (hb_font_get_glyph_extents(*f, glyph, &extents)) {
|
||||
lua_createtable(L, 0, 4);
|
||||
|
||||
lua_pushnumber(L, extents.x_bearing);
|
||||
lua_setfield(L, -2, "x_bearing");
|
||||
|
||||
lua_pushnumber(L, extents.y_bearing);
|
||||
lua_setfield(L, -2, "y_bearing");
|
||||
|
||||
lua_pushnumber(L, extents.width);
|
||||
lua_setfield(L, -2, "width");
|
||||
|
||||
lua_pushnumber(L, extents.height);
|
||||
lua_setfield(L, -2, "height");
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_glyph_name(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
||||
|
||||
#define NAME_LEN 128
|
||||
char name[NAME_LEN];
|
||||
if (hb_font_get_glyph_name(*f, glyph, name, NAME_LEN))
|
||||
lua_pushstring(L, name);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
#undef NAME_LEN
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_glyph_from_name(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
const char *name = luaL_checkstring(L, 2);
|
||||
hb_codepoint_t glyph;
|
||||
|
||||
if (hb_font_get_glyph_from_name(*f, name, -1, &glyph))
|
||||
lua_pushinteger(L, glyph);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_glyph_h_advance(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
||||
|
||||
lua_pushinteger(L, hb_font_get_glyph_h_advance(*f, glyph));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_glyph_v_advance(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
||||
|
||||
lua_pushinteger(L, hb_font_get_glyph_v_advance(*f, glyph));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int font_get_nominal_glyph(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t uni = luaL_checkinteger(L, 2);
|
||||
hb_codepoint_t glyph;
|
||||
|
||||
if (hb_font_get_nominal_glyph(*f, uni, &glyph))
|
||||
lua_pushinteger(L, glyph);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int font_destroy(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
|
||||
hb_font_destroy(*f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int font_ot_color_glyph_get_png(lua_State *L) {
|
||||
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
||||
hb_blob_t* blob = hb_ot_color_glyph_reference_png(*f, gid);
|
||||
|
||||
if (hb_blob_get_length(blob) != 0) {
|
||||
Blob *b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
||||
luaL_getmetatable(L, "harfbuzz.Blob");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*b = blob;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg font_methods[] = {
|
||||
{ "__gc", font_destroy },
|
||||
{ "set_scale", font_set_scale },
|
||||
{ "get_scale", font_get_scale },
|
||||
{ "get_h_extents", font_get_h_extents },
|
||||
{ "get_v_extents", font_get_v_extents },
|
||||
{ "get_glyph_extents", font_get_glyph_extents },
|
||||
{ "get_glyph_name", font_get_glyph_name },
|
||||
{ "get_glyph_from_name", font_get_glyph_from_name },
|
||||
{ "get_glyph_h_advance", font_get_glyph_h_advance },
|
||||
{ "get_glyph_v_advance", font_get_glyph_v_advance },
|
||||
{ "get_nominal_glyph", font_get_nominal_glyph },
|
||||
{ "ot_color_glyph_get_png", font_ot_color_glyph_get_png },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg font_functions[] = {
|
||||
{ "new", font_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_font(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Font", font_methods, font_functions, NULL);
|
||||
}
|
49
luaharfbuzz/src/luaharfbuzz/language.c
Normal file
49
luaharfbuzz/src/luaharfbuzz/language.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
// harfbuzz.Feature
|
||||
#include "luaharfbuzz.h"
|
||||
|
||||
static int language_new(lua_State *L) {
|
||||
Language *l;
|
||||
|
||||
l = (Language *)lua_newuserdata(L, sizeof(*l));
|
||||
luaL_getmetatable(L, "harfbuzz.Language");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
if (lua_gettop(L) == 1 || lua_isnil(L, -2))
|
||||
*l = HB_LANGUAGE_INVALID;
|
||||
else
|
||||
*l = hb_language_from_string(luaL_checkstring(L, -2), -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int language_to_string(lua_State *L) {
|
||||
Language* l = (Language *)luaL_checkudata(L, 1, "harfbuzz.Language");
|
||||
const char *s = hb_language_to_string(*l);
|
||||
|
||||
lua_pushstring(L, s ? s : "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int language_equals(lua_State *L) {
|
||||
Language* lhs = (Language *)luaL_checkudata(L, 1, "harfbuzz.Language");
|
||||
Language* rhs = (Language *)luaL_checkudata(L, 2, "harfbuzz.Language");
|
||||
|
||||
lua_pushboolean(L, *lhs == *rhs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg language_methods[] = {
|
||||
{ "__tostring", language_to_string },
|
||||
{ "__eq", language_equals },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg language_functions[] = {
|
||||
{ "new", language_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_language(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Language", language_methods, language_functions, NULL);
|
||||
}
|
102
luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
Normal file
102
luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int shape_full (lua_State *L) {
|
||||
Font *font = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
||||
Buffer *buf = (Buffer *)luaL_checkudata(L, 2, "harfbuzz.Buffer");
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
luaL_checktype(L, 4, LUA_TTABLE);
|
||||
|
||||
unsigned int num_features = lua_rawlen(L, 3);
|
||||
Feature *features = (Feature *) malloc (num_features * sizeof(hb_feature_t));
|
||||
|
||||
for (unsigned int i = 0; i != num_features; ++i) {
|
||||
lua_geti(L, 3, i + 1);
|
||||
Feature* f = (Feature *)luaL_checkudata(L, -1, "harfbuzz.Feature");
|
||||
features[i] = *f;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
const char **shapers = NULL;
|
||||
size_t num_shapers = lua_rawlen(L, 4);
|
||||
if (num_shapers) {
|
||||
shapers = (const char**) calloc (num_shapers + 1, sizeof(char*));
|
||||
for (unsigned int i = 0; i != num_shapers; ++i) {
|
||||
lua_geti(L, 4, i + 1);
|
||||
shapers[i] = luaL_checkstring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Shape text
|
||||
lua_pushboolean(L, hb_shape_full(*font, *buf, features, num_features, shapers));
|
||||
|
||||
free(features);
|
||||
free(shapers);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int version (lua_State *L) {
|
||||
lua_pushstring(L, hb_version_string());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int list_shapers (lua_State *L) {
|
||||
const char **shaper_list = hb_shape_list_shapers ();
|
||||
int i = 0;
|
||||
|
||||
for (; *shaper_list; shaper_list++) {
|
||||
i++;
|
||||
lua_pushstring(L, *shaper_list);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg lib_table [] = {
|
||||
{"shape_full", shape_full},
|
||||
{"version", version},
|
||||
{"shapers", list_shapers},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int luaopen_luaharfbuzz (lua_State *L) {
|
||||
lua_newtable(L);
|
||||
|
||||
register_blob(L);
|
||||
lua_setfield(L, -2, "Blob");
|
||||
|
||||
register_face(L);
|
||||
lua_setfield(L, -2, "Face");
|
||||
|
||||
register_font(L);
|
||||
lua_setfield(L, -2, "Font");
|
||||
|
||||
register_buffer(L);
|
||||
lua_setfield(L, -2, "Buffer");
|
||||
|
||||
register_feature(L);
|
||||
lua_setfield(L, -2, "Feature");
|
||||
|
||||
register_tag(L);
|
||||
lua_setfield(L, -2, "Tag");
|
||||
|
||||
register_script(L);
|
||||
lua_setfield(L, -2, "Script");
|
||||
|
||||
register_direction(L);
|
||||
lua_setfield(L, -2, "Direction");
|
||||
|
||||
register_language(L);
|
||||
lua_setfield(L, -2, "Language");
|
||||
|
||||
register_ot(L);
|
||||
lua_setfield(L, -2, "ot");
|
||||
|
||||
register_unicode(L);
|
||||
lua_setfield(L, -2, "unicode");
|
||||
|
||||
luaL_setfuncs(L, lib_table, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
39
luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
Normal file
39
luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
typedef hb_blob_t* Blob;
|
||||
typedef hb_face_t* Face;
|
||||
typedef hb_font_t* Font;
|
||||
typedef hb_buffer_t* Buffer;
|
||||
typedef hb_feature_t Feature;
|
||||
typedef hb_tag_t Tag;
|
||||
typedef hb_script_t Script;
|
||||
typedef hb_direction_t Direction;
|
||||
typedef hb_language_t Language;
|
||||
|
||||
typedef struct luahb_constant_t {
|
||||
const char *name;
|
||||
int value;
|
||||
} luahb_constant_t;
|
||||
|
||||
// Functions to create classes and push them onto the stack
|
||||
int register_class(lua_State *L, const char *name, const luaL_Reg * methods, const luaL_Reg *functions, const luahb_constant_t* constants);
|
||||
int register_blob(lua_State *L);
|
||||
int register_face(lua_State *L);
|
||||
int register_font(lua_State *L);
|
||||
int register_buffer(lua_State *L);
|
||||
int register_feature(lua_State *L);
|
||||
int register_tag(lua_State *L);
|
||||
int register_script(lua_State *L);
|
||||
int register_direction(lua_State *L);
|
||||
int register_language(lua_State *L);
|
||||
int register_ot(lua_State *L);
|
||||
int register_unicode(lua_State *L);
|
47
luaharfbuzz/src/luaharfbuzz/ot.c
Normal file
47
luaharfbuzz/src/luaharfbuzz/ot.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static const struct luahb_constant_t ot_constants[] = {
|
||||
{ "NAME_ID_COPYRIGHT", HB_OT_NAME_ID_COPYRIGHT },
|
||||
{ "NAME_ID_FONT_FAMILY", HB_OT_NAME_ID_FONT_FAMILY },
|
||||
{ "NAME_ID_FONT_SUBFAMILY", HB_OT_NAME_ID_FONT_SUBFAMILY },
|
||||
{ "NAME_ID_UNIQUE_ID", HB_OT_NAME_ID_UNIQUE_ID },
|
||||
{ "NAME_ID_FULL_NAME", HB_OT_NAME_ID_FULL_NAME },
|
||||
{ "NAME_ID_VERSION_STRING", HB_OT_NAME_ID_VERSION_STRING },
|
||||
{ "NAME_ID_POSTSCRIPT_NAME", HB_OT_NAME_ID_POSTSCRIPT_NAME },
|
||||
{ "NAME_ID_TRADEMARK", HB_OT_NAME_ID_TRADEMARK },
|
||||
{ "NAME_ID_MANUFACTURER", HB_OT_NAME_ID_MANUFACTURER },
|
||||
{ "NAME_ID_DESIGNER", HB_OT_NAME_ID_DESIGNER },
|
||||
{ "NAME_ID_DESCRIPTION", HB_OT_NAME_ID_DESCRIPTION },
|
||||
{ "NAME_ID_VENDOR_URL", HB_OT_NAME_ID_VENDOR_URL },
|
||||
{ "NAME_ID_DESIGNER_URL", HB_OT_NAME_ID_DESIGNER_URL },
|
||||
{ "NAME_ID_LICENSE", HB_OT_NAME_ID_LICENSE },
|
||||
{ "NAME_ID_LICENSE_URL", HB_OT_NAME_ID_LICENSE_URL },
|
||||
{ "NAME_ID_TYPOGRAPHIC_FAMILY", HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY },
|
||||
{ "NAME_ID_TYPOGRAPHIC_SUBFAMILY", HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY },
|
||||
{ "NAME_ID_MAC_FULL_NAME", HB_OT_NAME_ID_MAC_FULL_NAME },
|
||||
{ "NAME_ID_SAMPLE_TEXT", HB_OT_NAME_ID_SAMPLE_TEXT },
|
||||
{ "NAME_ID_CID_FINDFONT_NAME", HB_OT_NAME_ID_CID_FINDFONT_NAME },
|
||||
{ "NAME_ID_WWS_FAMILY", HB_OT_NAME_ID_WWS_FAMILY },
|
||||
{ "NAME_ID_WWS_SUBFAMILY", HB_OT_NAME_ID_WWS_SUBFAMILY },
|
||||
{ "NAME_ID_LIGHT_BACKGROUND", HB_OT_NAME_ID_LIGHT_BACKGROUND },
|
||||
{ "NAME_ID_DARK_BACKGROUND", HB_OT_NAME_ID_DARK_BACKGROUND },
|
||||
{ "NAME_ID_VARIATIONS_PS_PREFIX", HB_OT_NAME_ID_VARIATIONS_PS_PREFIX },
|
||||
{ "NAME_ID_INVALID", HB_OT_NAME_ID_INVALID },
|
||||
{ "LAYOUT_NO_SCRIPT_INDEX", HB_OT_LAYOUT_NO_SCRIPT_INDEX },
|
||||
{ "LAYOUT_NO_FEATURE_INDEX", HB_OT_LAYOUT_NO_FEATURE_INDEX },
|
||||
{ "LAYOUT_DEFAULT_LANGUAGE_INDEX", HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX },
|
||||
{ "LAYOUT_NO_VARIATIONS_INDEX", HB_OT_LAYOUT_NO_VARIATIONS_INDEX },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg ot_methods[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg ot_functions[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_ot(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.ot", ot_methods, ot_functions, ot_constants);
|
||||
}
|
71
luaharfbuzz/src/luaharfbuzz/script.c
Normal file
71
luaharfbuzz/src/luaharfbuzz/script.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int new_script_from_string(lua_State *L) {
|
||||
Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
|
||||
luaL_getmetatable(L, "harfbuzz.Script");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
if (lua_gettop(L) == 1 || lua_isnil(L, -2))
|
||||
*sp = HB_SCRIPT_INVALID;
|
||||
else
|
||||
*sp = hb_script_from_string(luaL_checkstring(L, -2), -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int new_script_from_tag(lua_State *L) {
|
||||
Tag* tp = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
|
||||
|
||||
Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
|
||||
luaL_getmetatable(L, "harfbuzz.Script");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*sp = hb_script_from_iso15924_tag(*tp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int script_to_string(lua_State *L) {
|
||||
Script *script = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
|
||||
char s[5];
|
||||
|
||||
hb_tag_to_string(hb_script_to_iso15924_tag(*script), s);
|
||||
s[4] = '\0';
|
||||
lua_pushstring(L, s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int script_to_tag(lua_State *L) {
|
||||
Script *script = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
|
||||
|
||||
Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*tp = hb_script_to_iso15924_tag(*script);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int script_equals(lua_State *L) {
|
||||
Script* lhs = (Script *)luaL_checkudata(L, 1, "harfbuzz.Script");
|
||||
Script* rhs = (Script *)luaL_checkudata(L, 2, "harfbuzz.Script");
|
||||
|
||||
lua_pushboolean(L, *lhs == *rhs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg script_methods[] = {
|
||||
{ "__tostring", script_to_string },
|
||||
{ "__eq", script_equals },
|
||||
{ "to_iso15924_tag", script_to_tag },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg script_functions[] = {
|
||||
{ "new", new_script_from_string },
|
||||
{ "from_iso15924_tag", new_script_from_tag },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_script(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Script", script_methods, script_functions, NULL);
|
||||
}
|
50
luaharfbuzz/src/luaharfbuzz/tag.c
Normal file
50
luaharfbuzz/src/luaharfbuzz/tag.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
// harfbuzz.Feature
|
||||
#include "luaharfbuzz.h"
|
||||
|
||||
static int tag_new(lua_State *L) {
|
||||
Tag *t;
|
||||
|
||||
t = (Tag *)lua_newuserdata(L, sizeof(*t));
|
||||
luaL_getmetatable(L, "harfbuzz.Tag");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
if (lua_gettop(L) == 1 || lua_isnil(L, -2))
|
||||
*t = HB_TAG_NONE;
|
||||
else
|
||||
*t = hb_tag_from_string(luaL_checkstring(L, -2), -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tag_to_string(lua_State *L) {
|
||||
Tag* t = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
|
||||
char tag[5];
|
||||
|
||||
hb_tag_to_string(*t, tag);
|
||||
tag[4] = '\0';
|
||||
lua_pushstring(L, tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tag_equals(lua_State *L) {
|
||||
Tag* lhs = (Tag *)luaL_checkudata(L, 1, "harfbuzz.Tag");
|
||||
Tag* rhs = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
|
||||
|
||||
lua_pushboolean(L, *lhs == *rhs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg tag_methods[] = {
|
||||
{ "__tostring", tag_to_string },
|
||||
{ "__eq", tag_equals },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct luaL_Reg tag_functions[] = {
|
||||
{ "new", tag_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_tag(lua_State *L) {
|
||||
return register_class(L, "harfbuzz.Tag", tag_methods, tag_functions, NULL);
|
||||
}
|
33
luaharfbuzz/src/luaharfbuzz/texput.log
Normal file
33
luaharfbuzz/src/luaharfbuzz/texput.log
Normal file
|
@ -0,0 +1,33 @@
|
|||
This is LuaHBTeX, Version 1.11.2 (TeX Live 2020/dev) (format=luahbtex 2019.12.5) 11 DEC 2019 21:17
|
||||
restricted system commands enabled.
|
||||
**\relax
|
||||
|
||||
*\directlua{print(luaharfbuzz.Tag.new"ab ")}
|
||||
|
||||
*\directlua{print(luaharfbuzz.Tag.new"ab " .. 'c')}
|
||||
[\directlua]:1: attempt to concatenate a harfbuzz.Tag value
|
||||
stack traceback:
|
||||
[\directlua]:1: in main chunk.
|
||||
<*> ...ctlua{print(luaharfbuzz.Tag.new"ab " .. 'c')}
|
||||
|
||||
? \directlua{print(tostring(luaharfbuzz.Tag.new"ab ") .. 'c')}
|
||||
Type <return> to proceed, S to scroll future error messages,
|
||||
R to run without stopping, Q to run quietly,
|
||||
I to insert something,
|
||||
1 or ... or 9 to ignore the next 1 to 9 tokens of input,
|
||||
H for help, X to quit.
|
||||
?
|
||||
|
||||
*\directlua{print(tostring(luaharfbuzz.Tag.new"ab ") .. 'c')}
|
||||
|
||||
*directlua{print(tostring(luaharfbuzz.Tag.new"ab") .. 'c')}
|
||||
|
||||
*\directlua{print(tostring(luaharfbuzz.Tag.new"ab") .. 'c')}
|
||||
|
||||
*
|
||||
! Emergency stop.
|
||||
<*> ...int(tostring(luaharfbuzz.Tag.new"ab") .. 'c')}
|
||||
|
||||
End of file on the terminal!
|
||||
|
||||
! ==> Fatal error occurred, no output PDF file produced!
|
22
luaharfbuzz/src/luaharfbuzz/unicode.c
Normal file
22
luaharfbuzz/src/luaharfbuzz/unicode.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "luaharfbuzz.h"
|
||||
|
||||
static int script(lua_State *L) {
|
||||
hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, -1);
|
||||
|
||||
Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
|
||||
luaL_getmetatable(L, "harfbuzz.Script");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*sp = hb_unicode_script(hb_unicode_funcs_get_default(), c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg unicode_functions[] = {
|
||||
{ "script", script },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int register_unicode(lua_State *L) {
|
||||
luaL_newlib(L, unicode_functions);
|
||||
return 1;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue