#!/usr/bin/env dub
/+ dub.sdl:
name "font_libraries_outline_sink_raster"
targetPath "build"
libs "harfbuzz"
buildType "checked" {
buildOptions "optimize" "inline" "debugInfo"
}
+/
/**
* From outline to pixels with HarfBuzz as the only C dependency — the outline
* arrives through a callback sink, and the rasterizer is ~100 lines of D.
*
* Demonstrates three of the survey's questions against a real font:
*
* RQ6 — outline access as a SINK. `hb_font_draw_glyph` drives five
* callbacks (`move_to`, `line_to`, `quadratic_to`, `cubic_to`,
* `close_path`) in the font's scaled units; the program counts the
* segments by kind, which tells TrueType (`glyf`, quadratic) from CFF
* (cubic) without asking.
* RQ3 — variation coordinates reach OUTLINES through the same `hb_font_t`
* that shaping uses: `hb_font_set_variations(wght=…)` once, and both
* the advance and the drawn contours move. The glyph is rendered at
* the axis minimum and maximum side by side.
* RQ2 — a from-scratch CPU rasterizer is small. `Rasterizer` below is the
* signed-area accumulation algorithm of font-rs (Raph Levien, 2016;
* the same algorithm stb_truetype v2, fontdue, ab_glyph_rasterizer and
* Go's x/image/vector use): each line deposits signed area into a
* per-row accumulation buffer, and one prefix sum per row yields exact
* coverage. Curves are flattened to lines first. No hinting, no
* gamma — those are the parts that are not small.
*
* Companion to docs/research/font-libraries/comparison.md (RQ2, RQ3, RQ6),
* harfbuzz.md § 5, and fontdue.md / ab-glyph.md / stb-truetype.md on the
* accumulation rasterizer.
*
* Run with: dub run --single outline-sink-raster.d [-- /path/to/font.ttf [char]]
*
* Font resolution: the first argument if given, else `fc-match -f %{file}
* "Noto Sans"`. If nothing resolves (no fontconfig on the host), prints a
* `SKIP:` line and exits 0 so CI stays green.
*/
module (module) font_libraries_outline_sink_rasterFrom outline to pixels with HarfBuzz as the only C dependency — the outline
arrives through a callback sink, and the rasterizer is ~100 lines of D.
Demonstrates three of the survey's questions against a real font:
RQ6 — outline access as a SINK. hb_font_draw_glyph drives five
callbacks (move_to, line_to, quadratic_to, cubic_to,
close_path) in the font's scaled units; the program counts the
segments by kind, which tells TrueType (glyf, quadratic) from CFF
(cubic) without asking.
RQ3 — variation coordinates reach OUTLINES through the same hb_font_t
that shaping uses: hb_font_set_variations(wght=…) once, and both
the advance and the drawn contours move. The glyph is rendered at
the axis minimum and maximum side by side.
RQ2 — a from-scratch CPU rasterizer is small. Rasterizer below is the
signed-area accumulation algorithm of font-rs (Raph Levien, 2016;
the same algorithm stb_truetype v2, fontdue, ab_glyph_rasterizer and
Go's x/image/vector use): each line deposits signed area into a
per-row accumulation buffer, and one prefix sum per row yields exact
coverage. Curves are flattened to lines first. No hinting, no
gamma — those are the parts that are not small.
Companion to docs/research/font-libraries/comparison.md (RQ2, RQ3, RQ6),
harfbuzz.md § 5, and fontdue.md / ab-glyph.md / stb-truetype.md on the
accumulation rasterizer.
Run with: dub run --single outline-sink-raster.d [-- /path/to/font.ttf [char]]
Font resolution: the first argument if given, else fc-match -f %{file}
"Noto Sans". If nothing resolves (no fontconfig on the host), prints a
SKIP: line and exits 0 so CI stays green.
font_libraries_outline_sink_raster;
import (package) stdstd.(module) std.algorithmThis package implements generic algorithms oriented towards the processing of
sequences. Sequences processed by these functions define range-based
interfaces. See also Reference on ranges and
tutorial on ranges.
Algorithms are categorized into the following submodules:
Submodule Functions
| Searching |
all
any
balancedParens
boyerMooreFinder
canFind
commonPrefix
count
countUntil
endsWith
find
findAdjacent
findAmong
findSkip
findSplit
findSplitAfter
findSplitBefore
minCount
maxCount
minElement
maxElement
minIndex
maxIndex
minPos
maxPos
skipOver
startsWith
until
|
| Comparison |
among
castSwitch
clamp
cmp
either
equal
isPermutation
isSameLength
levenshteinDistance
levenshteinDistanceAndPath
max
min
mismatch
predSwitch
|
| Iteration |
cache
cacheBidirectional
chunkBy
cumulativeFold
each
filter
filterBidirectional
fold
group
joiner
map
mean
permutations
reduce
splitWhen
splitter
substitute
sum
uniq
|
| Sorting |
completeSort
isPartitioned
isSorted
isStrictlyMonotonic
ordered
strictlyOrdered
makeIndex
merge
multiSort
nextEvenPermutation
nextPermutation
nthPermutation
partialSort
partition
partition3
schwartzSort
sort
topN
topNCopy
topNIndex
|
| Set operations (setops) |
cartesianProduct
largestPartialIntersection
largestPartialIntersectionWeighted
multiwayMerge
multiwayUnion
setDifference
setIntersection
setSymmetricDifference
|
| Mutation |
bringToFront
copy
fill
initializeAll
move
moveAll
moveSome
moveEmplace
moveEmplaceAll
moveEmplaceSome
remove
reverse
strip
stripLeft
stripRight
swap
swapRanges
uninitializedFill
|
Many functions in this package are parameterized with a predicate.
The predicate may be any suitable callable type
(a function, a delegate, a functor, or a lambda), or a
compile-time string. The string may consist of any legal D
expression that uses the symbol a (for unary functions) or the
symbols a and b (for binary functions). These names will NOT
interfere with other homonym symbols in user code because they are
evaluated in a different context. The default for all binary
comparison predicates is "a == b" for unordered operations and
"a < b" for ordered operations.
Example
int[] a = ...;
static bool greater(int a, int b)
{
return a > b;
}
sort!greater(a); // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a); // predicate as string
// (no ambiguity with array name)
sort(a); // no predicate, "a < b" is implicit
Source
std/algorithm/package.d
algorithm : (alias template) font_libraries_outline_sink_raster.max = std.algorithm.comparison.max(T...)(T args) if (T.length >= 2 && !is(CommonType!T == void))Iterates the passed arguments and returns the maximum value.
max, (alias template) font_libraries_outline_sink_raster.min = std.algorithm.comparison.min(T...)(T args) if (T.length >= 2 && !is(CommonType!T == void))Iterates the passed arguments and returns the minimum value.
min;
import (package) stdstd.(module) std.fileUtilities for manipulating files and scanning directories. Functions
in this module handle files as a unit, e.g., read or write one file
at a time. For opening files and manipulating them via handles refer
to module std.stdio.
Category Functions General exists isDir isFile isSymlink rename thisExePath Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir Files append copy read readText remove slurp write Symlinks symlink readLink Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace
Source
std/file.d
file : (alias template) font_libraries_outline_sink_raster.exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)Determine whether the given file (or directory) exists.
exists;
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) font_libraries_outline_sink_raster.abs = std.math.algebraic.abs(Num)(Num x) if (isIntegral!Num || is(typeof(Num.init >= 0)) && is(typeof(-Num.init)))Calculates the absolute value of a number.
Limitations
When x is a signed integral equal to Num.min the value of x will be returned instead.
Note for 2's complement; -Num.min (= Num.max + 1) is not representable due to overflow.
abs, (alias) font_libraries_outline_sink_raster.ceil = real std.math.rounding.ceil(real x) pure nothrow @nogc @trustedReturns the value of x rounded upward to the next integer
(toward positive infinity).
ceil, (alias) font_libraries_outline_sink_raster.floor = real std.math.rounding.floor(real x) pure nothrow @nogc @trustedReturns the value of x rounded downward to the next integer
(toward negative infinity).
floor, (alias) font_libraries_outline_sink_raster.sqrt = float std.math.algebraic.sqrt(float x) pure nothrow @nogc @safeCompute square root of x.
x sqrt(x) invalid? -0.0 -0.0 no <0.0 yes + + no
sqrt;
import (package) stdstd.(module) std.processFunctions for starting and interacting with other processes, and for
working with the current process' execution environment.
Process handling
`spawnProcess` spawns a new `process`, optionally assigning it an
arbitrary set of standard input, output, and error streams.
The function returns immediately, leaving the child process to execute
in parallel with its parent. All other functions in this module that
spawn processes are built around spawnProcess.
`wait` makes the parent `process` wait for a child `process` to
terminate. In general one should always do this, to avoid
child processes becoming "zombies" when the parent process exits.
Scope guards are perfect for this – see the spawnProcess
documentation for examples. tryWait is similar to wait,
but does not block if the process has not yet terminated.
`pipeProcess` also spawns a child `process` which runs
in parallel with its parent. However, instead of taking
arbitrary streams, it automatically creates a set of
pipes that allow the parent to communicate with the child
through the child's standard input, output, and/or error streams.
This function corresponds roughly to C's popen function.
`execute` starts a new `process` and waits for it
to complete before returning. Additionally, it captures
the process' standard output and error streams and returns
the output of these as a string.
`spawnShell`, `pipeShell` and `executeShell` work like
spawnProcess, pipeProcess and execute, respectively,
except that they take a single command string and run it through
the current user's default command interpreter.
executeShell corresponds roughly to C's system function.
`kill` attempts to terminate a running `process`.
The following table compactly summarises the different process creation
functions and how they relate to each other:
Runs program directly
Runs shell command Low-level process creation spawnProcess spawnShell Automatic input/output redirection using pipes pipeProcess pipeShell Execute and wait for completion, collect output execute executeShell
Other functionality
`pipe` is used to create unidirectional pipes.
`environment` is an interface through which the current `process`'
environment variables can be read and manipulated.
`escapeShellCommand` and `escapeShellFileName` are useful
for constructing shell command lines in a portable way.
Source
std/process.d
Note
Most of the functionality in this module is not available on iOS, tvOS
and watchOS. The only functions available on those platforms are:
environment, thisProcessID and thisThreadID.
process : (alias) font_libraries_outline_sink_raster.execute = std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safeExecutes the given program or shell command and returns its exit
code and output.
execute and executeShell start a new process using
spawnProcess and spawnShell, respectively, and wait
for the process to complete before returning. The functions capture
what the child process prints to both its standard output and
standard error streams, and return this together with its exit code.
auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);
auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);
The args/program/command, env and config
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.
POSIX specific
If the process is terminated by a signal, the status field of
the return value will contain a negative number whose absolute
value is the signal number. (See wait for details.)
execute;
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : (alias template) font_libraries_outline_sink_raster.write = std.stdio.write(T...)(T args) if (!is(T[0] : File))Writes its arguments in text format to standard output (without a trailing newline).
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
write("Input ", count, ": ", line, "\n");
}
}
write, (alias template) font_libraries_outline_sink_raster.writeln = std.stdio.writeln(T...)(T args)Equivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln, (alias template) font_libraries_outline_sink_raster.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))Equivalent to writef(fmt, args, '\n').
writefln;
import (package) stdstd.(module) std.stringString handling functions.
Category Functions Searching column indexOf indexOfAny indexOfNeither lastIndexOf lastIndexOfAny lastIndexOfNeither Comparison isNumeric Mutation capitalize Pruning and Filling center chomp chompPrefix chop detabber detab entab entabber leftJustify outdent rightJustify strip stripLeft stripRight wrap Substitution abbrev soundex soundexer succ tr translate Miscellaneous assumeUTF fromStringz lineSplitter representation splitLines toStringz Objects of types string, wstring, and dstring are value types and cannot be mutated element-by-element. For using mutation during building strings, use char[], wchar[], or dchar[]. The xxxstring types are preferable because they don't exhibit undesired aliasing, thus making code more robust.
The following functions are publicly imported:
Module Functions Publicly imported functions std.algorithm cmp, std,algorithm,comparison count, std,algorithm,searching endsWith, std,algorithm,searching startsWith, std,algorithm,searching std.array join, std,array replace, std,array replaceInPlace, std,array split, std,array empty, std,array std.format format, std,format sformat, std,format std.uni icmp, std,uni toLower, std,uni toLowerInPlace, std,uni toUpper, std,uni toUpperInPlace, std,uni There is a rich set of functions for string handling defined in other modules. Functions related to Unicode and ASCII are found in std.uni and std.ascii, respectively. Other functions that have a wider generality than just strings can be found in std.algorithm and std.range.
Source
std/string.d
string : (alias template) font_libraries_outline_sink_raster.strip = std.string.strip(Range)(Range str) if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range))Strips both leading and trailing whitespace (as defined by
isWhite) or as specified in the second argument.
strip, (alias) font_libraries_outline_sink_raster.toStringz = immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trustedtoStringz;
// ---------------------------------------------------------------------------
// HarfBuzz C ABI, the subset this program needs. Only opaque handles and
// scalars cross; `hb_draw_state_t` is received by pointer and never read.
// ---------------------------------------------------------------------------
extern (C) nothrow @nogc
{
struct (struct) font_libraries_outline_sink_raster.hb_blob_thb_blob_t;
struct (struct) font_libraries_outline_sink_raster.hb_face_thb_face_t;
struct (struct) font_libraries_outline_sink_raster.hb_font_thb_font_t;
struct (struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t;
struct (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t;
alias (alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t = uint;
alias (alias) font_libraries_outline_sink_raster.hb_tag_t = uinthb_tag_t = uint;
struct (struct) font_libraries_outline_sink_raster.hb_variation_thb_variation_t { (alias) font_libraries_outline_sink_raster.hb_tag_t = uinthb_tag_t (field) uint font_libraries_outline_sink_raster.hb_variation_t.tagtag; float (field) float font_libraries_outline_sink_raster.hb_variation_t.valuevalue; }
struct (struct) font_libraries_outline_sink_raster.hb_ot_var_axis_info_thb_ot_var_axis_info_t
{
uint (field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.axis_indexaxis_index; (alias) font_libraries_outline_sink_raster.hb_tag_t = uinthb_tag_t (field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.tagtag; uint (field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.name_idname_id; uint (field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.flagsflags;
float (field) float font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.min_valuemin_value, (field) float font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.default_valuedefault_value, (field) float font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.max_valuemax_value; uint (field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.reservedreserved;
}
alias (alias) font_libraries_outline_sink_raster.MoveToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogcMoveToFn = void function((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void*, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*,
float, float, void*);
alias (alias) font_libraries_outline_sink_raster.QuadToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, void*) nothrow @nogcQuadToFn = void function((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void*, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*,
float, float, float, float, void*);
alias (alias) font_libraries_outline_sink_raster.CubicToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, float, float, void*) nothrow @nogcCubicToFn = void function((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void*, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*,
float, float, float, float, float, float, void*);
alias (alias) font_libraries_outline_sink_raster.CloseFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, void*) nothrow @nogcCloseFn = void function((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void*, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*, void*);
(struct) font_libraries_outline_sink_raster.hb_blob_thb_blob_t* font_libraries_outline_sink_raster.hb_blob_t* font_libraries_outline_sink_raster.hb_blob_create_from_file(const(char)*) nothrow @nogchb_blob_create_from_file(const(char)*);
void void font_libraries_outline_sink_raster.hb_blob_destroy(font_libraries_outline_sink_raster.hb_blob_t*) nothrow @nogchb_blob_destroy((struct) font_libraries_outline_sink_raster.hb_blob_thb_blob_t*);
(struct) font_libraries_outline_sink_raster.hb_face_thb_face_t* font_libraries_outline_sink_raster.hb_face_t* font_libraries_outline_sink_raster.hb_face_create(font_libraries_outline_sink_raster.hb_blob_t*, uint) nothrow @nogchb_face_create((struct) font_libraries_outline_sink_raster.hb_blob_thb_blob_t*, uint);
void void font_libraries_outline_sink_raster.hb_face_destroy(font_libraries_outline_sink_raster.hb_face_t*) nothrow @nogchb_face_destroy((struct) font_libraries_outline_sink_raster.hb_face_thb_face_t*);
uint uint font_libraries_outline_sink_raster.hb_face_get_upem(const(font_libraries_outline_sink_raster.hb_face_t)*) nothrow @nogchb_face_get_upem(const((struct) font_libraries_outline_sink_raster.hb_face_thb_face_t)*);
(struct) font_libraries_outline_sink_raster.hb_font_thb_font_t* font_libraries_outline_sink_raster.hb_font_t* font_libraries_outline_sink_raster.hb_font_create(font_libraries_outline_sink_raster.hb_face_t*) nothrow @nogchb_font_create((struct) font_libraries_outline_sink_raster.hb_face_thb_face_t*);
void void font_libraries_outline_sink_raster.hb_font_destroy(font_libraries_outline_sink_raster.hb_font_t*) nothrow @nogchb_font_destroy((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*);
void void font_libraries_outline_sink_raster.hb_font_set_scale(font_libraries_outline_sink_raster.hb_font_t*, int, int) nothrow @nogchb_font_set_scale((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*, int, int);
void void font_libraries_outline_sink_raster.hb_font_set_variations(font_libraries_outline_sink_raster.hb_font_t*, const(font_libraries_outline_sink_raster.hb_variation_t)*, uint) nothrow @nogchb_font_set_variations((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*, const((struct) font_libraries_outline_sink_raster.hb_variation_thb_variation_t)*, uint);
int int font_libraries_outline_sink_raster.hb_font_get_nominal_glyph(font_libraries_outline_sink_raster.hb_font_t*, uint, uint*) nothrow @nogchb_font_get_nominal_glyph((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*, (alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t, (alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t*);
int int font_libraries_outline_sink_raster.hb_font_get_glyph_h_advance(font_libraries_outline_sink_raster.hb_font_t*, uint) nothrow @nogchb_font_get_glyph_h_advance((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*, (alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t);
uint uint font_libraries_outline_sink_raster.hb_ot_var_get_axis_infos(font_libraries_outline_sink_raster.hb_face_t*, uint, uint*, font_libraries_outline_sink_raster.hb_ot_var_axis_info_t*) nothrow @nogchb_ot_var_get_axis_infos((struct) font_libraries_outline_sink_raster.hb_face_thb_face_t*, uint, uint*, (struct) font_libraries_outline_sink_raster.hb_ot_var_axis_info_thb_ot_var_axis_info_t*);
(struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t* font_libraries_outline_sink_raster.hb_draw_funcs_t* font_libraries_outline_sink_raster.hb_draw_funcs_create() nothrow @nogchb_draw_funcs_create();
void void font_libraries_outline_sink_raster.hb_draw_funcs_destroy(font_libraries_outline_sink_raster.hb_draw_funcs_t*) nothrow @nogchb_draw_funcs_destroy((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_make_immutable(font_libraries_outline_sink_raster.hb_draw_funcs_t*) nothrow @nogchb_draw_funcs_make_immutable((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_set_move_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_move_to_func((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, (alias) font_libraries_outline_sink_raster.MoveToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogcMoveToFn, void*, void*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_set_line_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_line_to_func((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, (alias) font_libraries_outline_sink_raster.MoveToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogcMoveToFn, void*, void*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_set_quadratic_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_quadratic_to_func((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, (alias) font_libraries_outline_sink_raster.QuadToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, void*) nothrow @nogcQuadToFn, void*, void*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_set_cubic_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_cubic_to_func((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, (alias) font_libraries_outline_sink_raster.CubicToFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, float, float, void*) nothrow @nogcCubicToFn, void*, void*);
void void font_libraries_outline_sink_raster.hb_draw_funcs_set_close_path_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_close_path_func((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, (alias) font_libraries_outline_sink_raster.CloseFn = extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, void*) nothrow @nogcCloseFn, void*, void*);
void void font_libraries_outline_sink_raster.hb_font_draw_glyph(font_libraries_outline_sink_raster.hb_font_t*, uint, font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*) nothrow @nogchb_font_draw_glyph((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t*, (alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t, (struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void*);
}
// ---------------------------------------------------------------------------
// The rasterizer: signed-area accumulation (font-rs). Coordinates are pixels,
// y-down, origin at the bitmap's top-left.
// ---------------------------------------------------------------------------
struct (struct) font_libraries_outline_sink_raster.RasterizerRasterizer
{
int (field) int font_libraries_outline_sink_raster.Rasterizer.ww, (field) int font_libraries_outline_sink_raster.Rasterizer.hh;
float[] (field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc; // (w + 2) per row of headroom for the rightmost deposits
this(int (parameter) int ww, int (parameter) int hh) { this.(field) int font_libraries_outline_sink_raster.Rasterizer.ww = (parameter) int ww; this.(field) int font_libraries_outline_sink_raster.Rasterizer.hh = (parameter) int hh; (field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc = new float[((parameter) int ww + 2) * (parameter) int hh]; (field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[] = 0; }
void void font_libraries_outline_sink_raster.Rasterizer.line(float x0, float y0, float x1, float y1) pure nothrow @nogc @safeline(float (parameter) float x0x0, float (parameter) float y0y0, float (parameter) float x1x1, float (parameter) float y1y1) @safe pure nothrow @nogc
{
if ((parameter) float y0y0 == (parameter) float y1y1) return;
float (local variable) float dirdir = 1;
if ((parameter) float y0y0 > (parameter) float y1y1) { (local variable) float dirdir = -1; void font_libraries_outline_sink_raster.swap(ref float a, ref float b) pure nothrow @nogc @safeswap((parameter) float x0x0, (parameter) float x1x1); void font_libraries_outline_sink_raster.swap(ref float a, ref float b) pure nothrow @nogc @safeswap((parameter) float y0y0, (parameter) float y1y1); }
const (local variable) const(float) dxdydxdy = ((parameter) float x1x1 - (parameter) float x0x0) / ((parameter) float y1y1 - (parameter) float y0y0);
float (local variable) float xx = (parameter) float x0x0;
if ((parameter) float y0y0 < 0) (local variable) float xx -= (parameter) float y0y0 * (local variable) const(float) dxdydxdy;
const (local variable) const(int) yEndyEnd = int std.algorithm.comparison.min!(int, int)(int a, int b) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = min(a, b);
static assert(is(typeof(d) == int));
assert(d == 5);
auto e = min(a, b, c);
static assert(is(typeof(e) == double));
assert(e == 2);
ulong f = 0xffff_ffff_ffff;
const uint g = min(f, 0xffff_0000);
assert(g == 0xffff_0000);
dchar h = 100;
uint i = 101;
static assert(is(typeof(min(h, i)) == dchar));
static assert(is(typeof(min(i, h)) == uint));
assert(min(h, i) == 100);
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
int a = -10;
uint f = 10;
static assert(is(typeof(min(a, f)) == int));
assert(min(a, f) == -10);
User-defined types that support comparison with < are supported.
import std.datetime;
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date.min, Date.max) == Date.min);
assert(min(Date.max, Date.min) == Date.min);
min((field) int font_libraries_outline_sink_raster.Rasterizer.hh, cast(int) float std.math.rounding.ceil(float x) pure nothrow @nogc @trustedceil((parameter) float y1y1));
for (int (local variable) int yy = int std.algorithm.comparison.max!(int, int)(int a, int b) pure nothrow @nogc @safeIterates the passed arguments and returns the maximum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = max(a, b);
assert(is(typeof(d) == int));
assert(d == 6);
auto e = min(a, b, c);
assert(is(typeof(e) == double));
assert(e == 2);
max(0, cast(int) (parameter) float y0y0); y < yEnd; ++y)
{
const (local variable) const(int) rowrow = (local variable) int yy * ((field) int font_libraries_outline_sink_raster.Rasterizer.ww + 2);
const (local variable) const(float) dydy = float std.algorithm.comparison.min!(float, float)(float a, float b) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = min(a, b);
static assert(is(typeof(d) == int));
assert(d == 5);
auto e = min(a, b, c);
static assert(is(typeof(e) == double));
assert(e == 2);
ulong f = 0xffff_ffff_ffff;
const uint g = min(f, 0xffff_0000);
assert(g == 0xffff_0000);
dchar h = 100;
uint i = 101;
static assert(is(typeof(min(h, i)) == dchar));
static assert(is(typeof(min(i, h)) == uint));
assert(min(h, i) == 100);
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
int a = -10;
uint f = 10;
static assert(is(typeof(min(a, f)) == int));
assert(min(a, f) == -10);
User-defined types that support comparison with < are supported.
import std.datetime;
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date.min, Date.max) == Date.min);
assert(min(Date.max, Date.min) == Date.min);
min((local variable) int yy + 1.0f, (parameter) float y1y1) - float std.algorithm.comparison.max!(float, float)(float a, float b) pure nothrow @nogc @safeIterates the passed arguments and returns the maximum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = max(a, b);
assert(is(typeof(d) == int));
assert(d == 6);
auto e = min(a, b, c);
assert(is(typeof(e) == double));
assert(e == 2);
max(cast(float) (local variable) int yy, (parameter) float y0y0);
const (local variable) const(float) xnextxnext = (local variable) float xx + (local variable) const(float) dxdydxdy * (local variable) const(float) dydy;
const (local variable) const(float) dd = (local variable) const(float) dydy * (local variable) float dirdir;
const (local variable) const(float) xaxa = float std.algorithm.comparison.min!(float, const(float))(float __param_0, const(float) __param_1) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
min((local variable) float xx, (local variable) const(float) xnextxnext), (local variable) const(float) xbxb = float std.algorithm.comparison.max!(float, const(float))(float __param_0, const(float) __param_1) pure nothrow @nogc @safeIterates the passed arguments and returns the maximum value.
max((local variable) float xx, (local variable) const(float) xnextxnext);
const (local variable) const(float) xaFloorxaFloor = float std.math.rounding.floor(float x) pure nothrow @nogc @trustedfloor((local variable) const(float) xaxa);
const (local variable) const(int) xaixai = cast(int) (local variable) const(float) xaFloorxaFloor;
const (local variable) const(float) xbCeilxbCeil = float std.math.rounding.ceil(float x) pure nothrow @nogc @trustedceil((local variable) const(float) xbxb);
const (local variable) const(int) xbixbi = cast(int) (local variable) const(float) xbCeilxbCeil;
if ((local variable) const(int) xaixai < 0 || (local variable) const(int) xbixbi > (field) int font_libraries_outline_sink_raster.Rasterizer.ww + 1) { (local variable) float xx = (local variable) const(float) xnextxnext; continue; }
if ((local variable) const(int) xbixbi <= (local variable) const(int) xaixai + 1)
{
// The line stays inside one pixel column on this row.
const (local variable) const(float) xmfxmf = 0.5f * ((local variable) float xx + (local variable) const(float) xnextxnext) - (local variable) const(float) xaFloorxaFloor;
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xaixai] += (local variable) const(float) dd - (local variable) const(float) dd * (local variable) const(float) xmfxmf;
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xaixai + 1] += (local variable) const(float) dd * (local variable) const(float) xmfxmf;
}
else
{
// It crosses several columns: trapezoids at both ends, a
// constant slope's worth of area in between.
const (local variable) const(float) ss = 1.0f / ((local variable) const(float) xbxb - (local variable) const(float) xaxa);
const (local variable) const(float) xafxaf = (local variable) const(float) xaxa - (local variable) const(float) xaFloorxaFloor;
const (local variable) const(float) a0a0 = 0.5f * (local variable) const(float) ss * (1 - (local variable) const(float) xafxaf) * (1 - (local variable) const(float) xafxaf);
const (local variable) const(float) xbfxbf = (local variable) const(float) xbxb - (local variable) const(float) xbCeilxbCeil + 1;
const (local variable) const(float) amam = 0.5f * (local variable) const(float) ss * (local variable) const(float) xbfxbf * (local variable) const(float) xbfxbf;
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xaixai] += (local variable) const(float) dd * (local variable) const(float) a0a0;
if ((local variable) const(int) xbixbi == (local variable) const(int) xaixai + 2)
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xaixai + 1] += (local variable) const(float) dd * (1 - (local variable) const(float) a0a0 - (local variable) const(float) amam);
else
{
const (local variable) const(float) a1a1 = (local variable) const(float) ss * (1.5f - (local variable) const(float) xafxaf);
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xaixai + 1] += (local variable) const(float) dd * ((local variable) const(float) a1a1 - (local variable) const(float) a0a0);
foreach ((local variable) int xixi; (local variable) const(int) xaixai + 2 .. (local variable) const(int) xbixbi - 1)
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) int xixi] += (local variable) const(float) dd * (local variable) const(float) ss;
const (local variable) const(float) a2a2 = (local variable) const(float) a1a1 + ((local variable) const(int) xbixbi - (local variable) const(int) xaixai - 3) * (local variable) const(float) ss;
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xbixbi - 1] += (local variable) const(float) dd * (1 - (local variable) const(float) a2a2 - (local variable) const(float) amam);
}
(field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) const(int) rowrow + (local variable) const(int) xbixbi] += (local variable) const(float) dd * (local variable) const(float) amam;
}
(local variable) float xx = (local variable) const(float) xnextxnext;
}
}
/// One prefix sum per row turns deposited area into coverage in [0, 1].
float[] float[] font_libraries_outline_sink_raster.Rasterizer.coverage() const pure nothrow @safeOne prefix sum per row turns deposited area into coverage in [0, 1].
coverage() const @safe pure nothrow
{
auto (local variable) float[] cc = new float[(field) int font_libraries_outline_sink_raster.Rasterizer.ww * (field) int font_libraries_outline_sink_raster.Rasterizer.hh];
foreach ((local variable) int yy; 0 .. (field) int font_libraries_outline_sink_raster.Rasterizer.hh)
{
float (local variable) float sumsum = 0;
foreach ((local variable) int xx; 0 .. (field) int font_libraries_outline_sink_raster.Rasterizer.ww)
{
(local variable) float sumsum += (field) float[] font_libraries_outline_sink_raster.Rasterizer.accacc[(local variable) int yy * ((field) int font_libraries_outline_sink_raster.Rasterizer.ww + 2) + (local variable) int xx];
(local variable) float[] cc[(local variable) int yy * (field) int font_libraries_outline_sink_raster.Rasterizer.ww + (local variable) int xx] = float std.algorithm.comparison.min!(float, float)(float a, float b) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = min(a, b);
static assert(is(typeof(d) == int));
assert(d == 5);
auto e = min(a, b, c);
static assert(is(typeof(e) == double));
assert(e == 2);
ulong f = 0xffff_ffff_ffff;
const uint g = min(f, 0xffff_0000);
assert(g == 0xffff_0000);
dchar h = 100;
uint i = 101;
static assert(is(typeof(min(h, i)) == dchar));
static assert(is(typeof(min(i, h)) == uint));
assert(min(h, i) == 100);
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
int a = -10;
uint f = 10;
static assert(is(typeof(min(a, f)) == int));
assert(min(a, f) == -10);
User-defined types that support comparison with < are supported.
import std.datetime;
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date.min, Date.max) == Date.min);
assert(min(Date.max, Date.min) == Date.min);
min(float std.math.algebraic.abs!float(float x) pure nothrow @nogc @safeCalculates the absolute value of a number.
Limitations
When x is a signed integral equal to Num.min the value of x will be returned instead.
Note for 2's complement; -Num.min (= Num.max + 1) is not representable due to overflow.
Examples
import std.math.traits : isIdentical, isNaN;
assert(isIdentical(abs(-0.0L), 0.0L));
assert(isNaN(abs(real.nan)));
assert(abs(-real.infinity) == real.infinity);
assert(abs(-56) == 56);
assert(abs(2321312L) == 2321312L);
assert(abs(23u) == 23u);
abs((local variable) float sumsum), 1.0f);
}
}
return (local variable) float[] cc;
}
}
void void font_libraries_outline_sink_raster.swap(ref float a, ref float b) pure nothrow @nogc @safeswap(ref float (parameter) float aa, ref float (parameter) float bb) @safe pure nothrow @nogc { const (local variable) const(float) tt = (parameter) float aa; (parameter) float aa = (parameter) float bb; (parameter) float bb = (local variable) const(float) tt; }
// ---------------------------------------------------------------------------
// The sink: HarfBuzz callbacks → flattened lines into the rasterizer.
// ---------------------------------------------------------------------------
struct (struct) font_libraries_outline_sink_raster.SinkSink
{
(struct) font_libraries_outline_sink_raster.RasterizerRasterizer* (field) font_libraries_outline_sink_raster.Rasterizer* font_libraries_outline_sink_raster.Sink.rr;
float (field) float font_libraries_outline_sink_raster.Sink.originXoriginX, (field) float font_libraries_outline_sink_raster.Sink.baselinebaseline; // font units are y-up; flip here, once
float (field) float font_libraries_outline_sink_raster.Sink.pxpx, (field) float font_libraries_outline_sink_raster.Sink.pypy, (field) float font_libraries_outline_sink_raster.Sink.startXstartX, (field) float font_libraries_outline_sink_raster.Sink.startYstartY;
int (field) int font_libraries_outline_sink_raster.Sink.movesmoves, (field) int font_libraries_outline_sink_raster.Sink.lineslines, (field) int font_libraries_outline_sink_raster.Sink.quadsquads, (field) int font_libraries_outline_sink_raster.Sink.cubicscubics;
float float font_libraries_outline_sink_raster.Sink.sx(float x) const nothrow @nogcsx(float (parameter) float xx) const nothrow @nogc => (field) float font_libraries_outline_sink_raster.Sink.originXoriginX + (parameter) float xx;
float float font_libraries_outline_sink_raster.Sink.sy(float y) const nothrow @nogcsy(float (parameter) float yy) const nothrow @nogc => (field) float font_libraries_outline_sink_raster.Sink.baselinebaseline - (parameter) float yy;
void void font_libraries_outline_sink_raster.Sink.lineTo(float x, float y) nothrow @nogclineTo(float (parameter) float xx, float (parameter) float yy) nothrow @nogc
{
(field) font_libraries_outline_sink_raster.Rasterizer* font_libraries_outline_sink_raster.Sink.rr.void font_libraries_outline_sink_raster.Rasterizer.line(float x0, float y0, float x1, float y1) pure nothrow @nogc @safeline(float font_libraries_outline_sink_raster.Sink.sx(float x) const nothrow @nogcsx((field) float font_libraries_outline_sink_raster.Sink.pxpx), float font_libraries_outline_sink_raster.Sink.sy(float y) const nothrow @nogcsy((field) float font_libraries_outline_sink_raster.Sink.pypy), float font_libraries_outline_sink_raster.Sink.sx(float x) const nothrow @nogcsx((parameter) float xx), float font_libraries_outline_sink_raster.Sink.sy(float y) const nothrow @nogcsy((parameter) float yy));
(field) float font_libraries_outline_sink_raster.Sink.pxpx = (parameter) float xx; (field) float font_libraries_outline_sink_raster.Sink.pypy = (parameter) float yy;
}
}
enum (constant) int font_libraries_outline_sink_raster.flattenSteps = 8flattenSteps = 8; // uniform subdivision; adaptive flattening is a refinement
extern (C) nothrow @nogc void void font_libraries_outline_sink_raster.onMove(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float x, float y, void* __param_5) nothrow @nogconMove((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void* (parameter) void* datadata, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*, float (parameter) float xx, float (parameter) float yy, void*)
{
auto (local variable) font_libraries_outline_sink_raster.Sink* ss = cast((struct) font_libraries_outline_sink_raster.SinkSink*) (parameter) void* datadata;
++(local variable) font_libraries_outline_sink_raster.Sink* ss.(field) int font_libraries_outline_sink_raster.Sink.movesmoves;
(local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pxpx = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startXstartX = (parameter) float xx; (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pypy = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startYstartY = (parameter) float yy;
}
extern (C) nothrow @nogc void void font_libraries_outline_sink_raster.onLine(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float x, float y, void* __param_5) nothrow @nogconLine((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void* (parameter) void* datadata, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*, float (parameter) float xx, float (parameter) float yy, void*)
{
auto (local variable) font_libraries_outline_sink_raster.Sink* ss = cast((struct) font_libraries_outline_sink_raster.SinkSink*) (parameter) void* datadata;
++(local variable) font_libraries_outline_sink_raster.Sink* ss.(field) int font_libraries_outline_sink_raster.Sink.lineslines;
(local variable) font_libraries_outline_sink_raster.Sink* ss.void font_libraries_outline_sink_raster.Sink.lineTo(float x, float y) nothrow @nogclineTo((parameter) float xx, (parameter) float yy);
}
extern (C) nothrow @nogc void void font_libraries_outline_sink_raster.onQuad(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float cx, float cy, float x, float y, void* __param_7) nothrow @nogconQuad((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void* (parameter) void* datadata, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*,
float (parameter) float cxcx, float (parameter) float cycy, float (parameter) float xx, float (parameter) float yy, void*)
{
auto (local variable) font_libraries_outline_sink_raster.Sink* ss = cast((struct) font_libraries_outline_sink_raster.SinkSink*) (parameter) void* datadata;
++(local variable) font_libraries_outline_sink_raster.Sink* ss.(field) int font_libraries_outline_sink_raster.Sink.quadsquads;
const (local variable) const(float) x0x0 = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pxpx, (local variable) const(float) y0y0 = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pypy;
foreach ((local variable) int ii; 1 .. (constant) int font_libraries_outline_sink_raster.flattenSteps = 8flattenSteps + 1)
{
const (local variable) const(float) tt = cast(float) (local variable) int ii / (constant) int font_libraries_outline_sink_raster.flattenSteps = 8flattenSteps, (local variable) const(float) uu = 1 - (local variable) const(float) tt;
(local variable) font_libraries_outline_sink_raster.Sink* ss.void font_libraries_outline_sink_raster.Sink.lineTo(float x, float y) nothrow @nogclineTo((local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) x0x0 + 2 * (local variable) const(float) uu * (local variable) const(float) tt * (parameter) float cxcx + (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float xx, (local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) y0y0 + 2 * (local variable) const(float) uu * (local variable) const(float) tt * (parameter) float cycy + (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float yy);
}
}
extern (C) nothrow @nogc void void font_libraries_outline_sink_raster.onCubic(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float c1x, float c1y, float c2x, float c2y, float x, float y, void* __param_9) nothrow @nogconCubic((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void* (parameter) void* datadata, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*,
float (parameter) float c1xc1x, float (parameter) float c1yc1y, float (parameter) float c2xc2x, float (parameter) float c2yc2y, float (parameter) float xx, float (parameter) float yy, void*)
{
auto (local variable) font_libraries_outline_sink_raster.Sink* ss = cast((struct) font_libraries_outline_sink_raster.SinkSink*) (parameter) void* datadata;
++(local variable) font_libraries_outline_sink_raster.Sink* ss.(field) int font_libraries_outline_sink_raster.Sink.cubicscubics;
const (local variable) const(float) x0x0 = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pxpx, (local variable) const(float) y0y0 = (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pypy;
foreach ((local variable) int ii; 1 .. (constant) int font_libraries_outline_sink_raster.flattenSteps = 8flattenSteps + 1)
{
const (local variable) const(float) tt = cast(float) (local variable) int ii / (constant) int font_libraries_outline_sink_raster.flattenSteps = 8flattenSteps, (local variable) const(float) uu = 1 - (local variable) const(float) tt;
(local variable) font_libraries_outline_sink_raster.Sink* ss.void font_libraries_outline_sink_raster.Sink.lineTo(float x, float y) nothrow @nogclineTo((local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) x0x0 + 3 * (local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) tt * (parameter) float c1xc1x + 3 * (local variable) const(float) uu * (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float c2xc2x + (local variable) const(float) tt * (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float xx,
(local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) y0y0 + 3 * (local variable) const(float) uu * (local variable) const(float) uu * (local variable) const(float) tt * (parameter) float c1yc1y + 3 * (local variable) const(float) uu * (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float c2yc2y + (local variable) const(float) tt * (local variable) const(float) tt * (local variable) const(float) tt * (parameter) float yy);
}
}
extern (C) nothrow @nogc void void font_libraries_outline_sink_raster.onClose(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, void* __param_3) nothrow @nogconClose((struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t*, void* (parameter) void* datadata, (struct) font_libraries_outline_sink_raster.hb_draw_state_thb_draw_state_t*, void*)
{
auto (local variable) font_libraries_outline_sink_raster.Sink* ss = cast((struct) font_libraries_outline_sink_raster.SinkSink*) (parameter) void* datadata;
if ((local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pxpx != (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startXstartX || (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.pypy != (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startYstartY)
(local variable) font_libraries_outline_sink_raster.Sink* ss.void font_libraries_outline_sink_raster.Sink.lineTo(float x, float y) nothrow @nogclineTo((local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startXstartX, (local variable) font_libraries_outline_sink_raster.Sink* ss.(field) float font_libraries_outline_sink_raster.Sink.startYstartY);
}
// ---------------------------------------------------------------------------
(alias) object.string = stringstring string font_libraries_outline_sink_raster.resolveFont(string[] args)resolveFont((alias) object.string = stringstring[] (parameter) string[] argsargs)
{
if ((parameter) string[] argsargs.(field) ulong string[].lengthlength > 1 && bool std.file.exists!string(string name) nothrow @nogc @safeDetermine whether the given file (or directory) exists.
exists((parameter) string[] argsargs[1]))
return (parameter) string[] argsargs[1];
try
{
auto (local variable) std.typecons.Tuple!(int, "status", string, "output") rr = std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safeExecutes the given program or shell command and returns its exit
code and output.
execute and executeShell start a new process using
spawnProcess and spawnShell, respectively, and wait
for the process to complete before returning. The functions capture
what the child process prints to both its standard output and
standard error streams, and return this together with its exit code.
auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);
auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);
The args/program/command, env and config
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.
POSIX specific
If the process is terminated by a signal, the status field of
the return value will contain a negative number whose absolute
value is the signal number. (See wait for details.)
execute(["fc-match", "-f", "%{file}", "Noto Sans"]);
if ((local variable) std.typecons.Tuple!(int, "status", string, "output") rr.status == 0 && (field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0r.output.string std.string.strip!string(string str) pure nothrow @nogc @safeStrips both leading and trailing whitespace (as defined by
isWhite) or as specified in the second argument.
Examples
import std.uni : lineSep, paraSep;
assert(strip(" hello world ") ==
"hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
"hello world");
assert(strip("hello world") ==
"hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
"hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
"hello world");
strip.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1length && bool std.file.exists!string(string name) nothrow @nogc @safeDetermine whether the given file (or directory) exists.
exists((local variable) std.typecons.Tuple!(int, "status", string, "output") rr.output.string std.string.strip!string(string str) pure nothrow @nogc @safeStrips both leading and trailing whitespace (as defined by
isWhite) or as specified in the second argument.
Examples
import std.uni : lineSep, paraSep;
assert(strip(" hello world ") ==
"hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
"hello world");
assert(strip("hello world") ==
"hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
"hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
"hello world");
strip))
return (local variable) std.typecons.Tuple!(int, "status", string, "output") rr.output.string std.string.strip!string(string str) pure nothrow @nogc @safeStrips both leading and trailing whitespace (as defined by
isWhite) or as specified in the second argument.
Examples
import std.uni : lineSep, paraSep;
assert(strip(" hello world ") ==
"hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
"hello world");
assert(strip("hello world") ==
"hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
"hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
"hello world");
strip;
}
catch ((class) object.ExceptionThe base class of all errors that are safe to catch and handle.
In principle, only thrown objects derived from this class are safe to catch
inside a catch block. Thrown objects not derived from Exception
represent runtime errors that should not be caught, as certain runtime
guarantees may not hold, making it unsafe to continue program execution.
Examples
bool gotCaught;
try
{
throw new Exception("msg");
}
catch (Exception e)
{
gotCaught = true;
assert(e.msg == "msg");
}
assert(gotCaught);
Exception) {}
return null;
}
enum (constant) string font_libraries_outline_sink_raster.ramp = " .:-=+*#%@"ramp = " .:-=+*#%@";
/// Draws `cp` at `ppem` pixels into a `w`×`h` coverage bitmap.
float[] float[] font_libraries_outline_sink_raster.render(font_libraries_outline_sink_raster.hb_font_t* font, font_libraries_outline_sink_raster.hb_draw_funcs_t* funcs, dchar cp, int w, int h, out font_libraries_outline_sink_raster.Sink sink, out int advance)Draws cp at ppem pixels into a w×h coverage bitmap.
render((struct) font_libraries_outline_sink_raster.hb_font_thb_font_t* (parameter) font_libraries_outline_sink_raster.hb_font_t* fontfont, (struct) font_libraries_outline_sink_raster.hb_draw_funcs_thb_draw_funcs_t* (parameter) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, dchar (parameter) dchar cpcp, int (parameter) int ww, int (parameter) int hh,
out (struct) font_libraries_outline_sink_raster.SinkSink (parameter) font_libraries_outline_sink_raster.Sink sinksink, out int (parameter) int advanceadvance)
{
(alias) font_libraries_outline_sink_raster.hb_codepoint_t = uinthb_codepoint_t (local variable) uint gidgid;
int font_libraries_outline_sink_raster.hb_font_get_nominal_glyph(font_libraries_outline_sink_raster.hb_font_t*, uint, uint*) nothrow @nogchb_font_get_nominal_glyph((parameter) font_libraries_outline_sink_raster.hb_font_t* fontfont, (parameter) dchar cpcp, &(local variable) uint gidgid);
(parameter) int advanceadvance = int font_libraries_outline_sink_raster.hb_font_get_glyph_h_advance(font_libraries_outline_sink_raster.hb_font_t*, uint) nothrow @nogchb_font_get_glyph_h_advance((parameter) font_libraries_outline_sink_raster.hb_font_t* fontfont, (local variable) uint gidgid);
auto (local variable) font_libraries_outline_sink_raster.Rasterizer* rr = new (struct) font_libraries_outline_sink_raster.RasterizerRasterizer((parameter) int ww, (parameter) int hh);
(parameter) font_libraries_outline_sink_raster.Sink sinksink = (struct) font_libraries_outline_sink_raster.SinkSink((local variable) font_libraries_outline_sink_raster.Rasterizer* rr, 1, (parameter) int hh * 0.75f);
void font_libraries_outline_sink_raster.hb_font_draw_glyph(font_libraries_outline_sink_raster.hb_font_t*, uint, font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*) nothrow @nogchb_font_draw_glyph((parameter) font_libraries_outline_sink_raster.hb_font_t* fontfont, (local variable) uint gidgid, (parameter) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &(parameter) font_libraries_outline_sink_raster.Sink sinksink);
return (local variable) font_libraries_outline_sink_raster.Rasterizer* rr.float[] font_libraries_outline_sink_raster.Rasterizer.coverage() const pure nothrow @safeOne prefix sum per row turns deposited area into coverage in [0, 1].
coverage();
}
int int D main(string[] args)main((alias) object.string = stringstring[] (parameter) string[] argsargs)
{
const (local variable) const(string) pathpath = string font_libraries_outline_sink_raster.resolveFont(string[] args)resolveFont((parameter) string[] argsargs);
if ((local variable) const(string) pathpath is null)
{
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("SKIP: no font file resolved (pass a path, or install fontconfig)");
return 0;
}
const dchar (local variable) const(dchar) cpcp = (parameter) string[] argsargs.(field) ulong string[].lengthlength > 2 && (parameter) string[] argsargs[2].(field) ulong string.lengthlength ? (parameter) string[] argsargs[2][0] : 'g';
enum (constant) int font_libraries_outline_sink_raster.main.ppem = 28ppem = 28, (constant) int font_libraries_outline_sink_raster.main.w = 24w = 24, (constant) int font_libraries_outline_sink_raster.main.h = 32h = 32;
auto (local variable) font_libraries_outline_sink_raster.hb_blob_t* blobblob = font_libraries_outline_sink_raster.hb_blob_t* font_libraries_outline_sink_raster.hb_blob_create_from_file(const(char)*) nothrow @nogchb_blob_create_from_file((local variable) const(string) pathpath.immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trustedExamples
import core.stdc.string : strlen;
import std.conv : to;
auto p = toStringz("foo");
assert(strlen(p) == 3);
const(char)[] foo = "abbzxyzzy";
p = toStringz(foo[3 .. 5]);
assert(strlen(p) == 2);
string test = "";
p = toStringz(test);
assert(*p == 0);
test = "\0";
p = toStringz(test);
assert(*p == 0);
test = "foo\0";
p = toStringz(test);
assert(p[0] == 'f' && p[1] == 'o' && p[2] == 'o' && p[3] == 0);
const string test2 = "";
p = toStringz(test2);
assert(*p == 0);
assert(toStringz([]) is toStringz(""));
toStringz);
scope (exit) void font_libraries_outline_sink_raster.hb_blob_destroy(font_libraries_outline_sink_raster.hb_blob_t*) nothrow @nogchb_blob_destroy((local variable) font_libraries_outline_sink_raster.hb_blob_t* blobblob);
auto (local variable) font_libraries_outline_sink_raster.hb_face_t* faceface = font_libraries_outline_sink_raster.hb_face_t* font_libraries_outline_sink_raster.hb_face_create(font_libraries_outline_sink_raster.hb_blob_t*, uint) nothrow @nogchb_face_create((local variable) font_libraries_outline_sink_raster.hb_blob_t* blobblob, 0);
scope (exit) void font_libraries_outline_sink_raster.hb_face_destroy(font_libraries_outline_sink_raster.hb_face_t*) nothrow @nogchb_face_destroy((local variable) font_libraries_outline_sink_raster.hb_face_t* faceface);
auto (local variable) font_libraries_outline_sink_raster.hb_font_t* fontfont = font_libraries_outline_sink_raster.hb_font_t* font_libraries_outline_sink_raster.hb_font_create(font_libraries_outline_sink_raster.hb_face_t*) nothrow @nogchb_font_create((local variable) font_libraries_outline_sink_raster.hb_face_t* faceface);
scope (exit) void font_libraries_outline_sink_raster.hb_font_destroy(font_libraries_outline_sink_raster.hb_font_t*) nothrow @nogchb_font_destroy((local variable) font_libraries_outline_sink_raster.hb_font_t* fontfont);
// Scale so one output unit is one pixel: shaping AND drawing now speak px.
void font_libraries_outline_sink_raster.hb_font_set_scale(font_libraries_outline_sink_raster.hb_font_t*, int, int) nothrow @nogchb_font_set_scale((local variable) font_libraries_outline_sink_raster.hb_font_t* fontfont, (constant) int font_libraries_outline_sink_raster.main.ppem = 28ppem, (constant) int font_libraries_outline_sink_raster.main.ppem = 28ppem);
auto (local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs = font_libraries_outline_sink_raster.hb_draw_funcs_t* font_libraries_outline_sink_raster.hb_draw_funcs_create() nothrow @nogchb_draw_funcs_create();
scope (exit) void font_libraries_outline_sink_raster.hb_draw_funcs_destroy(font_libraries_outline_sink_raster.hb_draw_funcs_t*) nothrow @nogchb_draw_funcs_destroy((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs);
void font_libraries_outline_sink_raster.hb_draw_funcs_set_move_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_move_to_func((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &void font_libraries_outline_sink_raster.onMove(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float x, float y, void* __param_5) nothrow @nogconMove, null, null);
void font_libraries_outline_sink_raster.hb_draw_funcs_set_line_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_line_to_func((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &void font_libraries_outline_sink_raster.onLine(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float x, float y, void* __param_5) nothrow @nogconLine, null, null);
void font_libraries_outline_sink_raster.hb_draw_funcs_set_quadratic_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_quadratic_to_func((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &void font_libraries_outline_sink_raster.onQuad(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float cx, float cy, float x, float y, void* __param_7) nothrow @nogconQuad, null, null);
void font_libraries_outline_sink_raster.hb_draw_funcs_set_cubic_to_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, float, float, float, float, float, float, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_cubic_to_func((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &void font_libraries_outline_sink_raster.onCubic(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, float c1x, float c1y, float c2x, float c2y, float x, float y, void* __param_9) nothrow @nogconCubic, null, null);
void font_libraries_outline_sink_raster.hb_draw_funcs_set_close_path_func(font_libraries_outline_sink_raster.hb_draw_funcs_t*, extern (C) void function(font_libraries_outline_sink_raster.hb_draw_funcs_t*, void*, font_libraries_outline_sink_raster.hb_draw_state_t*, void*) nothrow @nogc, void*, void*) nothrow @nogchb_draw_funcs_set_close_path_func((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, &void font_libraries_outline_sink_raster.onClose(font_libraries_outline_sink_raster.hb_draw_funcs_t* __param_0, void* data, font_libraries_outline_sink_raster.hb_draw_state_t* __param_2, void* __param_3) nothrow @nogconClose, null, null);
void font_libraries_outline_sink_raster.hb_draw_funcs_make_immutable(font_libraries_outline_sink_raster.hb_draw_funcs_t*) nothrow @nogchb_draw_funcs_make_immutable((local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs);
// Find `wght`; a static font renders once at its only weight.
(struct) font_libraries_outline_sink_raster.hb_ot_var_axis_info_thb_ot_var_axis_info_t[16] (local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16] axesaxes;
uint (local variable) uint nn = (local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16] axesaxes.(constant) ulong font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16].length = 16LUlength;
uint font_libraries_outline_sink_raster.hb_ot_var_get_axis_infos(font_libraries_outline_sink_raster.hb_face_t*, uint, uint*, font_libraries_outline_sink_raster.hb_ot_var_axis_info_t*) nothrow @nogchb_ot_var_get_axis_infos((local variable) font_libraries_outline_sink_raster.hb_face_t* faceface, 0, &(local variable) uint nn, (local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16] axesaxes.(constant) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t* font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16].ptr = &axesptr);
float[] (local variable) float[] weightsweights;
foreach ((parameter) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t aa; (local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t[16] axesaxes[0 .. (local variable) uint nn])
if ((local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t aa.(field) uint font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.tagtag == ('w' << 24 | 'g' << 16 | 'h' << 8 | 't'))
(local variable) float[] weightsweights = [(local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t aa.(field) float font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.min_valuemin_value, (local variable) font_libraries_outline_sink_raster.hb_ot_var_axis_info_t aa.(field) float font_libraries_outline_sink_raster.hb_ot_var_axis_info_t.max_valuemax_value];
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safeEquivalent to writef(fmt, args, '\n').
writefln("font: %s", (local variable) const(string) pathpath);
void std.stdio.writefln!(char, dchar, int, string)(in char[] fmt, dchar __param_1, int __param_2, string __param_3) @safeEquivalent to writef(fmt, args, '\n').
writefln("glyph %s at %d ppem; %s", cast(dchar) (local variable) const(dchar) cpcp, (constant) int font_libraries_outline_sink_raster.main.ppem = 28ppem,
(local variable) float[] weightsweights.(field) ulong float[].lengthlength ? "variable: wght min vs max" : "static face (no wght axis)");
float[][] (local variable) float[][] bitmapsbitmaps;
foreach ((parameter) ulong ii, (parameter) float wghtwght; (local variable) float[] weightsweights.(field) ulong float[].lengthlength ? (local variable) float[] weightsweights : [float.(constant) float float.nan = nanFnan])
{
if ((local variable) float wghtwght == (local variable) float wghtwght) // not NaN
{
auto (local variable) font_libraries_outline_sink_raster.hb_variation_t vv = (struct) font_libraries_outline_sink_raster.hb_variation_thb_variation_t('w' << 24 | 'g' << 16 | 'h' << 8 | 't', (local variable) float wghtwght);
void font_libraries_outline_sink_raster.hb_font_set_variations(font_libraries_outline_sink_raster.hb_font_t*, const(font_libraries_outline_sink_raster.hb_variation_t)*, uint) nothrow @nogchb_font_set_variations((local variable) font_libraries_outline_sink_raster.hb_font_t* fontfont, &(local variable) font_libraries_outline_sink_raster.hb_variation_t vv, 1);
}
(struct) font_libraries_outline_sink_raster.SinkSink (local variable) font_libraries_outline_sink_raster.Sink sinksink;
int (local variable) int advadv;
(local variable) float[][] bitmapsbitmaps ~= float[] font_libraries_outline_sink_raster.render(font_libraries_outline_sink_raster.hb_font_t* font, font_libraries_outline_sink_raster.hb_draw_funcs_t* funcs, dchar cp, int w, int h, out font_libraries_outline_sink_raster.Sink sink, out int advance)Draws cp at ppem pixels into a w×h coverage bitmap.
render((local variable) font_libraries_outline_sink_raster.hb_font_t* fontfont, (local variable) font_libraries_outline_sink_raster.hb_draw_funcs_t* funcsfuncs, (local variable) const(dchar) cpcp, (constant) int font_libraries_outline_sink_raster.main.w = 24w, (constant) int font_libraries_outline_sink_raster.main.h = 32h, (local variable) font_libraries_outline_sink_raster.Sink sinksink, (local variable) int advadv);
float (local variable) float inkink = 0;
foreach ((parameter) float cc; (local variable) float[][] bitmapsbitmaps[$ - 1]) (local variable) float inkink += (local variable) float cc;
void std.stdio.writefln!(char, string, int, float, int, int, int, int)(in char[] fmt, string __param_1, int __param_2, float __param_3, int __param_4, int __param_5, int __param_6, int __param_7) @safeEquivalent to writef(fmt, args, '\n').
writefln(" %-10s advance %2d px ink %6.1f px² segments: %d move, %d line, %d quad, %d cubic",
(local variable) float wghtwght == (local variable) float wghtwght ? "wght " ~ (cast(int) (local variable) float wghtwght).string std.conv.to!string.to!int(int __param_0) pure nothrow @safeThe to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
Examples
Converting a value to its own type (useful mostly for generic code)
simply returns its argument.
int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14
Converting among numeric types is a safe way to cast them around.
Conversions from floating-point types to integral types allow loss of
precision (the fractional part of a floating-point number). The
conversion is truncating towards zero, the same way a cast would
truncate. (To round a floating point value when casting to an
integral, use roundTo.)
import std.exception : assertThrown;
int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));
assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);
When converting strings to numeric types, note that D hexadecimal and binary
literals are not handled. Neither the prefixes that indicate the base, nor the
horizontal bar used to separate groups of digits are recognized. This also
applies to the suffixes that indicate the type.
To work around this, you can specify a radix for conversions involving numbers.
auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);
Conversions from integral types to floating-point types always
succeed, but might lose accuracy. The largest integers with a
predecessor representable in floating-point format are 2^24-1 for
float, 2^53-1 for double, and 2^64-1 for real (when
real is 80-bit, e.g. on Intel machines).
// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);
Conversion from string types to char types enforces the input
to consist of a single code point, and said code point must
fit in the target type. Otherwise, ConvException is thrown.
import std.exception : assertThrown;
assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');
// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');
// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));
Converting an array to another array type works by converting each
element in turn. Associative arrays can be converted to associative
arrays as long as keys and values can in turn be converted.
import std.string : split;
int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);
Conversions operate transitively, meaning that they work on arrays and
associative arrays of any complexity.
This conversion works because to`!short` applies to an `int`, to!wstring
applies to a string, to`!string` applies to a `double`, and
to!(double[]) applies to an int[]. The conversion might throw an
exception because ``to!short might fail the range check.
int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);
Object-to-object conversions by dynamic casting throw exception when
the source is non-null and the target is null.
import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));
Stringize conversion from all types is supported.
String to string conversion works for any two string types having
(char, wchar, dchar) character widths and any
combination of qualifiers (mutable, const, or immutable).
Converts array (other than strings) to string.
Each element is converted by calling ``to!T.
Associative array to string conversion.
Each element is converted by calling ``to!T.
Object to string conversion calls toString against the object or
returns "null" if the object is null.
Struct to string conversion calls toString against the struct if
it is defined.
For structs that do not define toString, the conversion to string
produces the list of fields.
Enumerated types are converted to strings as their symbolic names.
Boolean values are converted to "true" or "false".
char, wchar, dchar to a string type.
Unsigned or signed integers to strings.
[special case]
: Convert integral value to string in radix radix.
radix must be a value from 2 to 36.
value is treated as a signed value only if radix is 10.
The characters A through Z are used to represent values 10 through 36
and their case is determined by the letterCase parameter.
All floating point types to all string types.
Pointer to string conversions convert the pointer to a size_t value.
If pointer is char*, treat it as C-style strings.
In that case, this function is @system.
See formatValue on how toString should be defined.
// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");
// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
to!string(associativeArray) == `["1":2, "0":1]`);
// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");
// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);
auto c = to!(wchar[])(b);
assert(c == "abcx");
Strings can be converted to enum types. The enum member with the same name as the
input string is returned. The comparison is case-sensitive.
A ConvException is thrown if the enum does not have the specified member.
import std.exception : assertThrown;
enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to!(alias) object.string = stringstring : "default", (local variable) int advadv, (local variable) float inkink,
(local variable) font_libraries_outline_sink_raster.Sink sinksink.(field) int font_libraries_outline_sink_raster.Sink.movesmoves, (local variable) font_libraries_outline_sink_raster.Sink sinksink.(field) int font_libraries_outline_sink_raster.Sink.lineslines, (local variable) font_libraries_outline_sink_raster.Sink sinksink.(field) int font_libraries_outline_sink_raster.Sink.quadsquads, (local variable) font_libraries_outline_sink_raster.Sink sinksink.(field) int font_libraries_outline_sink_raster.Sink.cubicscubics);
}
foreach ((local variable) int yy; 0 .. (constant) int font_libraries_outline_sink_raster.main.h = 32h)
{
bool (local variable) bool blankblank = true;
foreach ((parameter) float[] bb; (local variable) float[][] bitmapsbitmaps) foreach ((local variable) int xx; 0 .. (constant) int font_libraries_outline_sink_raster.main.w = 24w) if ((local variable) float[] bb[(local variable) int yy * (constant) int font_libraries_outline_sink_raster.main.w = 24w + (local variable) int xx] > 0.05f) (local variable) bool blankblank = false;
if ((local variable) bool blankblank) continue;
foreach ((parameter) ulong bibi, (parameter) float[] bb; (local variable) float[][] bitmapsbitmaps)
{
void std.stdio.write!string(string __param_0) @safeWrites its arguments in text format to standard output (without a trailing newline).
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
write("Input ", count, ": ", line, "\n");
}
}
write((local variable) ulong bibi ? " " : " ");
foreach ((local variable) int xx; 0 .. (constant) int font_libraries_outline_sink_raster.main.w = 24w)
void std.stdio.write!(immutable(char))(immutable(char) __param_0) @safeWrites its arguments in text format to standard output (without a trailing newline).
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
write("Input ", count, ": ", line, "\n");
}
}
write((constant) string font_libraries_outline_sink_raster.ramp = " .:-=+*#%@"ramp[ulong std.algorithm.comparison.min!(ulong, ulong)(ulong a, ulong b) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = min(a, b);
static assert(is(typeof(d) == int));
assert(d == 5);
auto e = min(a, b, c);
static assert(is(typeof(e) == double));
assert(e == 2);
ulong f = 0xffff_ffff_ffff;
const uint g = min(f, 0xffff_0000);
assert(g == 0xffff_0000);
dchar h = 100;
uint i = 101;
static assert(is(typeof(min(h, i)) == dchar));
static assert(is(typeof(min(i, h)) == uint));
assert(min(h, i) == 100);
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
int a = -10;
uint f = 10;
static assert(is(typeof(min(a, f)) == int));
assert(min(a, f) == -10);
User-defined types that support comparison with < are supported.
import std.datetime;
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date.min, Date.max) == Date.min);
assert(min(Date.max, Date.min) == Date.min);
min((constant) string font_libraries_outline_sink_raster.ramp = " .:-=+*#%@"ramp.(constant) ulong " .:-=+*#%@".length = 10LUlength - 1, cast((alias) object.size_t = ulongsize_t)((local variable) float[] bb[(local variable) int yy * (constant) int font_libraries_outline_sink_raster.main.w = 24w + (local variable) int xx] * ((constant) string font_libraries_outline_sink_raster.ramp = " .:-=+*#%@"ramp.(constant) ulong " .:-=+*#%@".length = 10LUlength - 1) + 0.5f))]);
}
void std.stdio.writeln!()() @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln();
}
return 0;
}
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) font_libraries_outline_sink_raster.to = std.conv.to(T)The to template converts a value from one type to another.
The source type is deduced and the target type must be specified, for example the
expression to`!int(42.0)` converts the number 42 from
`double` to `int`. The conversion is "safe", i.e.,
it checks for overflow; to!int(4.2e10) would throw the
ConvOverflowException exception. Overflow checks are only
inserted when necessary, e.g., ``to!double(42) does not do
any checking because any int fits in a double.
Conversions from string to numeric types differ from the C equivalents
atoi() and atol() by checking for overflow and not allowing whitespace.
For conversion of strings to signed types, the grammar recognized is:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
to;