aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-02 16:32:31 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-02 16:32:31 -0700
commit07dfe284d1cba355dcc808b9083f4ddd5e330816 (patch)
tree2ca978dcf3d4e4f1d524ac1a4c40c7a55d1c4042 /include
parent69adb19d98114d7a35bf73389b9098de33adf42c (diff)
fix: added include file and fixed calls to free instead of interface
Diffstat (limited to 'include')
-rw-r--r--include/libfont.h363
1 files changed, 363 insertions, 0 deletions
diff --git a/include/libfont.h b/include/libfont.h
new file mode 100644
index 0000000..964c446
--- /dev/null
+++ b/include/libfont.h
@@ -0,0 +1,363 @@
+#pragma once
+
+typedef struct font·Info font·Info;
+typedef struct font·TabElt font·TabElt;
+typedef struct font·Vertex font·Vertex;
+typedef struct font·Bitmap font·Bitmap;
+
+struct font·TabElt
+{
+ int glyph1; // use font·glyph_index
+ int glyph2;
+ int advance;
+};
+
+enum
+{
+ font·Vmove = 1,
+ font·Vline,
+ font·Vcurve,
+ font·Vcubic
+};
+
+struct font·Vertex
+{
+ short x, y;
+ short cx, cy;
+ short cx1, cy1;
+ uchar type, padding;
+};
+
+/* glyph shapes */
+
+/* Query the font vertical metrics without having to create a font first */
+void font·scaledvmetrics(uchar *data, int index, float size, float *ascent, float *descent, float *lineGap);
+
+/*
+ * This function will determine the number of fonts in a font file. TrueType
+ * collection (.ttc) files may contain multiple fonts, while TrueType font
+ * (.ttf) files only contain one font. The number of fonts can be used for
+ * indexing with the previous function where the index is between zero and one
+ * less than the total fonts. If an error occurs, -1 is returned.
+ */
+int font·number(uchar *data);
+
+/*
+ * Each .ttf/.ttc file may have more than one font. Each font has a sequential
+ * index number starting from 0. Call this function to get the font offset for
+ * a given index; it returns -1 if the index is out of range. A regular .ttf
+ * file will only define one font and it always be at offset 0, so it will
+ * return '0' for index 0, and -1 for all other indices.
+ */
+int font·offsetfor(uchar *data, int index);
+
+/*
+ * Given an offset into the file that defines a font, this function builds
+ * the necessary cached info for the rest of the system. Returns nil on failure.
+ */
+font·Info *font·make(uchar *data, int offset, mem·Allocator, void *heap);
+void font·free(font·Info *info);
+
+
+/* character to glyph-index conversion */
+
+/*
+ * If you're going to perform multiple operations on the same character
+ * and you want a speed-up, call this function with the character you're
+ * going to process, then use glyph-based functions instead of the
+ * codepoint-based functions.
+ * Returns 0 if the character codepoint is not defined in the font.
+ */
+int font·glyph_index(font·Info *info, int codepoint);
+
+
+/* character properties */
+
+/*
+ * computes a scale factor to produce a font whose "height" is 'pixels' tall.
+ * Height is measured as the distance from the highest ascender to the lowest
+ * descender; in other words, it's equivalent to calling font·GetFontVMetrics
+ * and computing:
+ * scale = pixels / (ascent - descent)
+ * so if you prefer to measure height by the ascent only, use a similar calculation.
+ */
+float font·scaleheightto(font·Info *info, float pixels);
+
+/*
+ * computes a scale factor to produce a font whose EM size is mapped to
+ * 'pixels' tall. This is probably what traditional APIs compute, but
+ * I'm not positive.
+ */
+float font·scaleheighttoem(font·Info *info, float pixels);
+
+/*
+ * ascent is the coordinate above the baseline the font extends; descent
+ * is the coordinate below the baseline the font extends (i.e. it is typically negative)
+ * linegap is the spacing between one row's descent and the next row's ascent...
+ * so you should advance the vertical position by "*ascent - *descent + *lineGap"
+ * these are expressed in unscaled coordinates, so you must multiply by
+ * the scale factor for a given size
+ */
+void font·vmetrics(font·Info *info, int *ascent, int *descent, int *linegap);
+
+
+/* the bounding box around all possible characters */
+void font·bbox(font·Info *info, int *x0, int *y0, int *x1, int *y1);
+
+/*
+ * leftSideBearing is the offset from the current horizontal position to the left edge of the character
+ * advanceWidth is the offset from the current horizontal position to the next horizontal position
+ * these are expressed in unscaled coordinates
+ */
+void font·code_hmetrics(font·Info *info, int codepoint, int *advance, int *lsb);
+
+/* an additional amount to add to the 'advance' value between ch1 and ch2 */
+int font·code_kernadvance(font·Info *info, int ch1, int ch2);
+
+/* Gets the bounding box of the visible part of the glyph, in unscaled coordinates */
+int font·code_box(font·Info *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
+
+/* as above, but takes one or more glyph indices for greater efficiency */
+void font·glyph_hmetrics(font·Info *info, int glyph_index, int *advance, int *lsb);
+int font·glyph_kernadvance(font·Info *info, int glyph1, int glyph2);
+int font·glyph_box(font·Info *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
+
+/*
+ * Retrieves a complete list of all of the kerning pairs provided by the font
+ * font·kerntab never writes more than table_length entries and returns how many entries it did write.
+ * The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
+ */
+int font·kerntablen(font·Info *info);
+int font·kerntab(font·Info *info, font·TabElt *tab, int len);
+
+/* returns non-zero if nothing is drawn for this glyph */
+int font·glyph_empty(font·Info *info, int glyph_index);
+
+/*
+ * returns # of vertices and fills *vertices with the pointer to them
+ * these are expressed in "unscaled" coordinates
+ *
+ * the shape is a series of contours. Each one starts with
+ * a STBTT_moveto, then consists of a series of mixed
+ * STBTT_lineto and STBTT_curveto segments. A lineto
+ * draws a line from previous endpoint to its x,y; a curveto
+ * draws a quadratic bezier from previous endpoint to
+ * its x,y, using cx,cy as the bezier control point.
+ */
+int font·code_shape(font·Info *info, int unicode_codepoint, font·Vertex **vertices);
+int font·glyph_shape(font·Info *info, int glyph_index, font·Vertex **vertices);
+
+/* frees the data allocated above */
+void font·freeshape(font·Info *info, font·Vertex *verts);
+
+/*
+ * fills svg with the character's SVG data.
+ * returns data size or 0 if SVG not found.
+ */
+int font·code_svg(font·Info *info, int unicode_codepoint, char **svg);
+int font·glyph_svg(font·Info *info, int gl, char **svg);
+
+/* bitmap rendering */
+
+/* frees the bitmap allocated below */
+void font·freebitmap(uchar *bitmap, void *userdata);
+
+/*
+ * allocates a large-enough single-channel 8bpp bitmap and renders the
+ * specified character/glyph at the specified scale into it, with
+ * antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
+ * *width & *height are filled out with the width & height of the bitmap,
+ * which is stored left-to-right, top-to-bottom.
+
+ * xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
+ */
+uchar *font·code_makebitmap(font·Info *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
+
+/*
+ * the same as font·GetCodepoitnBitmap, but you can specify a subpixel
+ * shift for the character
+ */
+uchar *font·code_makebitmap_subpixel(font·Info *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
+
+/*
+ * the same as font·codepointbitmap, but you pass in storage for the bitmap
+ * in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
+ * is clipped to out_w/out_h bytes. Call font·codepointbitmapbox to get the
+ * width and height and positioning info for it first.
+ */
+void font·code_fillbitmap(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
+
+/*
+ * same as font·MakeCodepointBitmap, but you can specify a subpixel
+ * shift for the character
+ */
+void font·code_fillbitmap_subpixel(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
+
+/*
+ * same as font·MakeCodepointBitmapSubpixel, but prefiltering
+ * is performed (see font·PackSetOversampling)
+ */
+void font·code_fillbitmap_subpixel_prefilter(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint);
+
+/*
+ * get the bbox of the bitmap centered around the glyph origin; so the
+ * bitmap width is ix1-ix0, height is iy1-iy0, and location to place
+ * the bitmap top left is (leftSideBearing*scale,iy0).
+ * (Note that the bitmap uses y-increases-down, but the shape uses
+ * y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
+ */
+void font·code_bitmapbox(font·Info *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+/*
+ * same as font·GetCodepointBitmapBox, but you can specify a subpixel
+ * shift for the character
+ */
+void font·code_bitmapbox_subpixel(font·Info *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+/*
+ * the following functions are equivalent to the above functions, but operate
+ * on glyph indices instead of Unicode codepoints (for efficiency)
+ */
+uchar *font·glyph_makebitmap(font·Info *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
+uchar *font·glyph_makebitmap_subpixel(font·Info *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff);
+void font·glyph_fillbitmap(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
+void font·glyph_fillbitmap_subpixel(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
+void font·glyph_fillbitmap_subpixel_prefilter(font·Info *info, uchar *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph);
+void font·glyph_bitmapbox(font·Info *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
+void font·glyph_bitmapbox_subpixel(font·Info *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+/* signed distance function (or field) rendering */
+
+/* frees the SDF bitmap allocated below */
+void font·freesdf(font·Info *info, uchar *bitmap);
+
+/*
+ * These functions compute a discretized SDF field for a single character, suitable for storing
+ * in a single-channel texture, sampling with bilinear filtering, and testing against
+ * larger than some threshold to produce scalable fonts.
+ * info -- the font
+ * scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
+ * glyph/codepoint -- the character to generate the SDF for
+ * padding -- extra "pixels" around the character which are filled with the distance to the character (not 0),
+ * which allows effects like bit outlines
+ * onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
+ * pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
+ * if positive, > onedge_value is inside; if negative, < onedge_value is inside
+ * width,height -- output height & width of the SDF bitmap (including padding)
+ * xoff,yoff -- output origin of the character
+ * return value -- a 2D array of bytes 0..255, width*height in size
+ *
+ * pixel_dist_scale & onedge_value are a scale & bias that allows you to make
+ * optimal use of the limited 0..255 for your application, trading off precision
+ * and special effects. SDF values outside the range 0..255 are clamped to 0..255.
+ *
+ * Example:
+ * scale = font·ScaleForPixelHeight(22)
+ * padding = 5
+ * onedge_value = 180
+ * pixel_dist_scale = 180/5.0 = 36.0
+ *
+ * This will create an SDF bitmap in which the character is about 22 pixels
+ * high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
+ * shape, sample the SDF at each pixel and fill the pixel if the SDF value
+ * is greater than or equal to 180/255. (You'll actually want to antialias,
+ * which is beyond the scope of this example.) Additionally, you can compute
+ * offset outlines (e.g. to stroke the character border inside & outside,
+ * or only outside). For example, to fill outside the character up to 3 SDF
+ * pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
+ * choice of variables maps a range from 5 pixels outside the shape to
+ * 2 pixels inside the shape to 0..255; this is intended primarily for apply
+ * outside effects only (the interior range is needed to allow proper
+ * antialiasing of the font at *smaller* sizes)
+ *
+ * The function computes the SDF analytically at each SDF pixel, not by e.g.
+ * building a higher-res bitmap and approximating it. In theory the quality
+ * should be as high as possible for an SDF of this size & representation, but
+ * unclear if this is true in practice (perhaps building a higher-res bitmap
+ * and computing from that can allow drop-out prevention).
+
+ * The algorithm has not been optimized at all, so expect it to be slow
+ * if computing lots of characters or very large sizes.
+ */
+
+
+uchar *font·glyph_sdf(font·Info *info, float scale, int glyph, int padding, uchar onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
+uchar *font·code_sdf(font·Info *info, float scale, int codepoint, int padding, uchar onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
+
+
+/*
+ * Finding the right font...
+ *
+ * You should really just solve this offline, keep your own tables
+ * of what font is what, and don't try to get it out of the .ttf file.
+ * That's because getting it out of the .ttf file is really hard, because
+ * the names in the file can appear in many possible encodings, in many
+ * possible languages, and e.g. if you need a case-insensitive comparison,
+ * the details of that depend on the encoding & language in a complex way
+ * (actually underspecified in truetype, but also gigantic).
+ *
+ * But you can use the provided functions in two possible ways:
+ * font·findmatchingfont() will use *case-sensitive* comparisons on
+ * unicode-encoded names to try to find the font you want;
+ * you can run this before calling font·init()
+ *
+ * font·getfontnamestring() lets you get any of the various strings
+ * from the file yourself and do your own comparisons on them.
+ * You have to have called font·init() first.
+ */
+
+
+/*
+ * returns the offset (not index) of the font that matches, or -1 if none
+ * if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
+ * if you use any other flag, use a font name like "Arial"; this checks
+ * the 'macStyle' header field; i don't know if fonts set this consistently
+ */
+int font·findmatch(uchar *fontdata, char *name, int flags);
+#define FONT_MACSTYLE_DONTCARE 0
+#define FONT_MACSTYLE_BOLD 1
+#define FONT_MACSTYLE_ITALIC 2
+#define FONT_MACSTYLE_UNDERSCORE 4
+#define FONT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
+
+/*
+ * returns the string (which may be big-endian double byte, e.g. for unicode)
+ * and puts the length in bytes in *length.
+ *
+ * some of the values for the IDs are below; for more see the truetype spec:
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
+ * http://www.microsoft.com/typography/otspec/name.htm
+ */
+
+char *font·name(font·Info *font, int *length, int platformID, int encodingID, int languageID, int nameID);
+
+enum { // platformID
+ font·platform_unicode = 0,
+ font·platform_mac = 1,
+ font·platform_iso = 2,
+};
+
+enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
+ font·unicode_eid_unicode_1_0 = 0,
+ font·unicode_eid_unicode_1_1 = 1,
+ font·unicode_eid_iso_10646 = 2,
+ font·unicode_eid_unicode_2_0_bmp = 3,
+ font·unicode_eid_unicode_2_0_full = 4
+};
+
+enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
+ font·mac_eid_roman =0, font·mac_eid_arabic =4,
+ font·mac_eid_japanese =1, font·mac_eid_hebrew =5,
+ font·mac_eid_chinese_trad =2, font·mac_eid_greek =6,
+ font·mac_eid_korean =3, font·mac_eid_russian =7
+};
+
+enum { // languageID for STBTT_PLATFORM_ID_MAC
+ font·mac_lang_english =0 , font·stbtt_mac_lang_japanese =11,
+ font·mac_lang_arabic =12, font·stbtt_mac_lang_korean =23,
+ font·mac_lang_dutch =4 , font·stbtt_mac_lang_russian =32,
+ font·mac_lang_french =1 , font·stbtt_mac_lang_spanish =6 ,
+ font·mac_lang_german =2 , font·stbtt_mac_lang_swedish =5 ,
+ font·mac_lang_hebrew =10, font·stbtt_mac_lang_chinese_simplified =33,
+ font·mac_lang_italian =3 , font·stbtt_mac_lang_chinese_trad =19
+};