Compare commits

...

110 Commits

Author SHA1 Message Date
Anuj Verma 64d1c20fec [sdf -> bsdf] Added a basic overview of the `bsdf' rasterizer.
* src/sdf/ftbsdf.c: Added the citation of the original paper
  and added a overview of the process for generating SDF
  from bitmaps.
2020-08-15 16:56:50 +05:30
Anuj Verma 41160c8be3 [sdf] Remove a unicode character. 2020-08-15 09:43:56 +05:30
Anuj Verma c3a5a07839 [sdf] Added a basic overview of the `sdf' rasterizer.
* src/sdf/ftsdf.c: Added the citation of the original paper
  and added a overview of the process for generating SDF
  from outlines.

* src/sdf/ftsdf.c (sdf_generate_subdivision): Added comment
  explaining how the optimization works.
2020-08-15 09:41:21 +05:30
Anuj Verma 0db5ba974d [sdf] Fix gcc compiler warnings.
* src/sdf/ftsdf.c, src/sdf/ftbsdf.c (*): Fix
  various compiler warnings, which were caused
  mainly due to unused variables and unused functions.
2020-08-14 09:14:15 +05:30
Anuj Verma e0a2a76b09 [sdf] Bug fix.
* src/sdf/ftsdf.c (sdf_generate_with_overlaps): The
  outside sign will always be 1. And added a missing
  `else'.
2020-08-13 09:05:50 +05:30
Anuj Verma 398cae8398 [base] Fix memory leaks due to FreeType internals.
* src/base/ftobjs.c (ft_remove_renderer): Similar to
  `ft_add_renderer', remover raster's `glyph_format'
  check. Due to this the rasterizers which do not have
  `glyph_format' of `FT_GLYPH_FORMAT_OUTLINE' won't get
  deallocated (the `raster_done' function is no called).
2020-08-12 17:27:29 +05:30
Anuj Verma d2796ed059 [sdf] Fix memory leaks.
* src/sdf/ftsdf.c (sdf_generate_with_overlaps): Deallocate
  the temporary bitmaps, and all the rest of the arrays.
  And also handle the `shape' appropriately so as to not
  cause memory leaks.
2020-08-12 17:21:40 +05:30
Anuj Verma b457aeee67 [sdf] Handle Post-Script fonts for overlap.
* src/sdf/ftsdf.c (sdf_generate_with_overlaps): Handle
  Handle Post-Script fonts for overlap support. Simply
  flip the orientation while combining all the separate
  SDF.
  Also, handle the `flip_sign' property separately so as
  to avoid handling extra cases.
2020-08-12 11:52:16 +05:30
Anuj Verma f644a47aae [sdf] Added overlap support (currently only for TrueType).
* src/sdf/ftsdfrend.h (SDF_Renderer_Module): Removed the
  expermental `optimization' property.
  Added another property `overlaps', which can be used to
  turn on the overlap support.

* src/sdf/ftsdf.h (SDF_Raster_Params): Ditto as above.

* src/sdf/ftsdfrend.c (*): Added functionality to set
  and get the new `overlaps' property.

* src/sdf/ftsdf.c (sdf_raster_render):
  Removed support for all the optimization modes and
  only keep the subdivision optimization and the new
  overlap support function.

* src/sdf/ftsdf.c (sdf_generate_coarse_grid): Turned
  off until we can find a way to make it faster.

* src/sdf/ftsdf.c (sdf_generate_with_overlaps): Added
  a function to generate SDF for shapes with overlapping
  contours. It basically generate SDF for separate contours
  in seperate bitmaps and then combine them to remove
  overlaps.
2020-08-12 10:14:35 +05:30
Anuj Verma 307b0cbd6f [sdf, bsdf] Added better documentation.
* src/sdf/ftsdf.c, src/sdf/ftbsdf.c (*): Added documentation
  of the structs and enums for both the renderers.
2020-08-07 16:47:50 +05:30
Anuj Verma 06bbff76b9 [sdf] Added function to get contour orientation.
* src/sdf/ftsdf.c (SDF_Contour_Orientation): Added
  enum to hold the different orientations of a contour.

* src/sdf/ftsdf.c (get_contour_orientation): Added
  function which can be used to compute the orientation
  of a contour.

* src/sdf/ftbsdf.c (*): Remove completed `[TODO]'s.
2020-08-06 11:42:26 +05:30
Anuj Verma 5014394b3e [sdf -> bsdf] Added documentation for functions of the `bsdf' renderer.
* src/sdf/ftbsdf.c (*) Added function documentation for
  function of the `bsdf' renderer.
2020-08-06 08:59:33 +05:30
Anuj Verma bada3e4162 [sdf] Added documentation for function of the `sdf' renderer.
* src/sdf/ftsdf.c (*): Added function documentation for
  function of the `sdf' renderer, and fixed grammar at a
  few places.
2020-08-06 07:50:57 +05:30
Anuj Verma 45398811c7 [sdf] Added documentation for some structs.
* src/sdf/ftsdfrend.h
      .../ftsdfrend.c
      .../ftsdfcommon.h
      .../ftsdf.h
  : Added documentation for a few structs.
2020-08-05 17:55:02 +05:30
Anuj Verma a9fbef27ab [sdf -> bsdf] Extended to work with monochrome bitmaps.
* src/sdf/ftbsdf.c (bsdf_init_distance_map): Handle
  monochrome bitmaps and convert them to the internal
  intermediate format, which can then be used to
  generate SDF.
2020-08-05 09:12:29 +05:30
Anuj Verma ee9b8e8cc0 * src/sdf/ftsdfrend.c (ft_bsdf_render): Initialize variable.
Initialize the target bitmap so as to avoid crashes due
to uninitialized memory.
2020-08-03 16:19:21 +05:30
Anuj Verma 95846825f6 [sdf -> bsdf] Fixed memory leak.
* src/sdf/ftbsdf.c (bsdf_raster_render): Release the
  allocated distance map.
  Also, added a log of total memory allocated for
  generating SDF from bitmap.
2020-08-03 09:13:53 +05:30
Anuj Verma d7a2e99bb0 [sdf -> bsdf] Fixed a bug with `finalize_sdf'.
* src/sdf/ftbsdf.c (finalize_sdf): First check if the
  value is withing [-spread, spread] and then cast it
  to 6.10 short, otherwise the value can overflow and
  give negative result.
  Also, flip the sign if the property `flip_sign' is
  set to true.
2020-08-02 16:33:22 +05:30
Anuj Verma a62fd640f3 [sdf -> bsdf] Added option to use squared distances.
* src/sdf/ftbsdf.c (bsdf_is_edge): Modified the function
  to use distance map rather than the alpha values from
  the source image.

* src/sdf/ftbsdf.c (bsdf_approximate_edge): Only calculate
  approximate edges for edge pixels. Use `bsdf_is_edge' is
  to check for edge pixels. For non edge pixel assgn far
  away distances.

* src/sdf/ftbsdf.c (finalize_sdf): Handle distances in case
  of squared distances.
  And also use the macro `VECTOR_LENGTH_16D16' in the entire
  code to compute vector length. This takes care of squared
  distances.

* src/sdf/ftsdfcommon.c (VECTOR_LENGTH_16D16): Move the macro
  `VECTOR_LENGTH_16D16' from `ftsdf.c' to this file because
  it is also used by the `bsdf' renderer.
2020-08-02 16:33:21 +05:30
Anuj Verma 436f091db1 * src/sdf/ftbsdf.c (compare_neighbor): Fix bug. 2020-08-02 16:33:21 +05:30
Anuj Verma 903d28725a Fix line endings and typo. 2020-08-02 16:33:21 +05:30
Anuj Verma 77ce541e10 [sdf -> bsdf] Optimized a bit.
* src/sdf/ftbsdf.c (ED: sign => alpha): Renamed sign
  to alphs. This is used to store the alpha of the current
  pixel mapped to the source image. This let's us store
  additional information without increasing memory usage.

* src/sdf/ftbsdf.c (bsdf_init_distance_map): Removed any/all
  kind of edge approximation and edge check from the function.
  The function simply copy the source bitmap to the distance
  map now, preserving alpha values.

* src/sdf/ftbsdf.c (compute_edge_distance): Use the new `alpha'
  parameter to compute gradient and approximate distance.
  Previously we were using the `dist' variable to store alpha
  values, which restricts modifying the `dist' variable because
  we need alpha values of neighbor to compute the gradient.

* src/sdf/ftbsdf.c (bsdf_approximate_edge): Now that we can
  modify the `dist' variable of the distance map, we can
  combine the two nested loops.

* src/sdf/ftbsdf.c (finalize_sdf): Move the `sign' determination
  and assignment to this function.
2020-08-02 16:33:21 +05:30
Anuj Verma 185c88905e * src/sdf/ftbsdf.c (compute_edge_distance): Grammer fix. 2020-08-02 16:33:21 +05:30
Anuj Verma 62b38d2b85 [sdf -> bsdf] Add explanation of the approximation.
* src/sdf/ftbsdf.c (compute_gradient => compute_edge_distance):
  Renamed to make sense of what the function does.
  Also, added the explanation of the algorithm used
  and a high level view of how it works.

* src/sdf/ftbsdf.c (compare_neighbor): Fix a bug related
  to value approximation before calling `FT_Vector_Length'.
2020-08-02 16:33:21 +05:30
Anuj Verma dcdcc65201 * src/sdf/ftsdfcommon.h (*): Fix line endings.
Always use LF line endings.
2020-08-02 16:33:21 +05:30
Anuj Verma f2553d89b2 [sdf,bsdf] Put common propertied and functions in one file.
* src/sdf/ftsdfcommon.h: Added new file which contains
  common function, macros, properties for both `sdf' and
  `bsdf' renderer.

* src/sdf/ftsdf.c, src/sdf/ftsdf.h, src/sdf/ftbsdf.c:
  Remove common properties and include `ftsdfcommon.h'.

* src/sdf/rules.mk (SDF_DRV_H): Add the new `ftsdfcommon.h'
  file to include list.
2020-08-02 16:33:21 +05:30
Anuj Verma aed19e1524 * src/sdf/ftbsdf.c (compute_gradient): Use root(2) for the filter.
Also, use the computed gradient to approximate
the edge distance from a pixel's position according
to the Gustavson's algorithm.
2020-08-02 16:33:21 +05:30
Anuj Verma fbbec7c64d [sdf -> bsdf] Added function to approximate edge distance.
* src/sdf/ftbsdf.c (bsdf_approximate_edge): The function
  uses the Gustavson's algorithm to approximate the edge
  from pixel values.

* src/sdf/ftbsdf.c (compute_gradient): The function uses
  Sobel's operator to compute the gradient at a pixel.
  The is used to detect edge direction.
2020-08-02 16:33:21 +05:30
Anuj Verma ffb6890089 * src/sdf/ftbsdf.c (_pass): Use function for repetitive task.
Use function `compare_neighbor' for comparing the
neighbors. Makes it easier to tweak the algorithm
and looks better.

* src/sdf/ftbsdf.c (compare_neighbor): Added function
  to compare the neighbors and assign values if the
  new distance is the shortest.
2020-08-02 16:33:21 +05:30
Anuj Verma 419633c374 * src/sdf/ftbsdf.c (bsdf_is_edge): Use macros to make it look cleaner.
Use `CHECK_NEIGHBOR' macro to check neighbors while
finding edges. Make the code more readable and look
cleaner.
2020-08-02 16:33:21 +05:30
Anuj Verma 262e9649f3 [sdf -> bsdf] Fix edge detection bug.
* src/sdf/ftbsdf.c (bsdf_is_edge): [BUG] Check all
  neighbors including the diagonal neighbors to
  properly determine the edge.
2020-08-02 16:33:21 +05:30
Anuj Verma f057095bef [sdf -> bsdf] Added edge detection algorithm.
Added edge detection algorithm. It works by checking
the neighboring pixels and if any neighbor is not
filled (i.e. belongs to background) we mark the
pixel as edge by setting it's distance to 0.

* src/sdf/ftbsdf.c (bsdf_is_edge): Added function to
  detect if the pixel is an edge.
2020-08-02 16:33:21 +05:30
Anuj Verma 8564d5caf2 [sdf -> bsdf] Added the second pass of the '8SED'.
Added the second pass of the 8SED algorithm. The second pass
transverse the bitmap from bottom to top and for each row
it sweeps forward and backward assigning distances to the
grid points.

* src/sdf/ftbsdf.c (second_pas): Added function to do the
  second pass of the 8SED algorithm on the bitmap.
2020-08-02 16:33:21 +05:30
Anuj Verma 6214e58893 [sdf -> bsdf] Optimize the first pass of the 8SED.
* src/sdf/ftbsdf.c (first_pass): Optimize the first
  pass by first approximating the neighbor's distance
  by adding an offset. The offset will be max root(2)
  because the maximum be add to a vector is (1, 1).
  By approximating we can reduce the number of
  `FT_Vector_Length' calls and thus make the process
  faster.
2020-08-02 16:33:21 +05:30
Anuj Verma 6ccbf0ecf6 [sdf] Fix GNU Make build.
* src/sdf/rules.mk (SDF_DRV_H): Manually add source files
  as there is a `ftbsdf.c' file without any `ftbsdf.h'.

* src/sdf/ftbsdf.c: Include `fttrigon.h' for `multi' builds.
2020-08-02 16:33:21 +05:30
Anuj Verma 470131db91 [sdf -> bsdf] Added first pass of the '8SED' algorithm.
Added the first pass of the 8SED algorithm. The first pass
transverse the bitmap from top to bottom and for each row
it sweeps forward and backward assigning distances to the
grid points.

* src/sdf/ftbsdf.c (ED): Added additional parameter `sign'.

* src/sdf/ftbsdf.c (edt8): Added function to convert bitmap
  to SDF using the 8SED algorithm.

* src/sdf/ftbsdf.c (first_pass): Added function to do the
  first pass of the 8SED algorithm on the bitmap.

* src/sdf/ftbsdf.c (finalize_sdf): Added function to assign
  the final SDF data to the target bitmap.

* src/sdf/ftbsdf.c (*): Various minor or experimental changes.

* src/sdf/ftsdfrend.c (ft_bsdf_render): Fix spacing.
2020-08-02 16:33:20 +05:30
Anuj Verma 59d340878a * src/sdf/ftbsdf.c (*): Rename `SDF_TRaster' => `BSDF_TRaster'.
`SDF_TRaster' is for the `sdf' renderer.
2020-08-02 16:33:20 +05:30
Anuj Verma ea5114acfd * src/sdf/ftbsdf.c: Typo. `FT_16D16' is 16.16 representation. 2020-08-02 16:33:20 +05:30
Anuj Verma 13180a3cd4 [sdf -> bsdf renderer] Hold a refrence to `FT_Memory'.
Due to the way the 8SED algorithm works we need to keep
a track of distances and nearest point of all the pixels/
grid points.

* src/sdf/ftbsdf.c (BSDF_TRaster): Added struct to
  hold the `FT_Memory' reference, to be used to allocate
  memory.

* src/sdf/ftbsdf.c (ED, BSDF_Worker): Added few more
  essential struct. `ED' contains infomation about the
  nearest point. `BSDF_Worker' is used to combine all
  the essentail parameters to functions.

* src/sdf/ftbsdf.c (bsdf_copy_source_to_target => 
  bsdf_init_distance_map): Renamed.

* src/sdf/ftbsdf.c (*): Various minor changes.

* src/sdf/sdf.c: Change the order of source include
  because `ftsdf.c' change some internal freetype
  defines which are required in `ftbsdf.c'.
2020-08-02 16:33:20 +05:30
Anuj Verma 99a4759290 [sdf -> bsdf renderer] Convert 8bit bitmap to 16bit.
* src/sdf/ftbsdf.c (bsdf_copy_source_to_target): Added
  extra parameter to flip the bitmap vertically.

* src/sdf/ftbsdf.c (bsdf_copy_source_to_target):
  Implemented functionality to convert 8bits per
  pixel bitmap to a 16bits per pixel bitmap, which
  will be used to generate SDF.
2020-08-02 16:33:20 +05:30
Anuj Verma 2c77a8acb2 [sdf] Started the `bsdf' rasterier.
* src/sdf/ftbsdf.c (*): Fix line endings.

* src/sdf/ftbsdf.c (bsdf_copy_source_to_target): Added
  function to copy the source bitmap to the center of
  the target bitmap and also convert it to normalized
  16 bits per pixel bitmap.
2020-08-02 16:33:20 +05:30
Anuj Verma 1d51c5ef7b [sdf] Added interface functions for `bsdf' converter.
* src/base/ftobjs.c (FT_Render_Glyph_Internal): Remove
  the bitmap check which prevent calling renderers
  if the glyph is already a bitmap. The `bsdf' renderer
  requires a bitmap for conversion.

* src/base/ftobjs.c (ft_add_renderer): Remove the glyph
  format check which ensures that the glyph format for
  a renderer is `FT_GLYPH_FORMAT_OUTLINE', again the `bsdf'
  renderer has `FT_GLYPH_FORMAT_BITMAP' as a glyph format,
  so we need to remove the condition to initialize the
  renderer properly.

* src/sdf/ftbsdf.c (*): Added a rasterizer for the
  `bsdf' renderer and created necessary functions.

* src/sdf/ftbsdf.h: Add forward declaration of the
  rasterizer.

* src/sdf/ftsdfrend.c (ft_bitmap_sdf_renderer_class):
  Define the new `bsdf' rendere and add the
  `FT_Renderer_RenderFunc' function, the rest is
  same as the `sdf' renderer.

* src/sdf/ftsdfrend.h: Add forward declaration of the
  renderer.

* src/sdf/rules.mk (SDF_DRV_SRC): Add the new `ftbsdf.c'
  file to the compile list.

* src/sdf/sdf.c: Inclue the `ftbsdf.c' file if making
  single object.
2020-08-02 16:33:20 +05:30
Anuj Verma ddfa07c5da [sdf] Add alloc/free functions.
* src/sdf/ftsdf.c (*): Add `sdf_alloc' and `sdf_free'
  to allocate and deallocate memory respectively.
  By using function we can directly use them in the
  conditional statements, which is not possible when
  using `do {} while ( 0 )'.

* src/sdf/ftsdf.c (SDF_MEMORY_TRACKER_): When not
  debugging don't leave the macros empty otherwise
  some compiler may emit warning because of empty
  `;' semi-colon.
2020-08-02 16:33:20 +05:30
Anuj Verma f41ee8f0c3 [sdf] Added new renderer `bsdf'.
* src/sdf/ftsdfrend.* (*): Added new renderer
  named `bsdf' which basically convert bitmap
  to signed distance fields. This is a part of
  the `sdf' module and not a separate module on
  it's own.

* src/sdf/module.mk (FTMODULE_H_COMMANDS): Add
  the new renderer to the list of modules.

* include/freetype/config/ftmodule.h: Add the
  new renderer to default list of modules when
  not compiling with GNU Make.
2020-08-02 16:33:20 +05:30
Anuj Verma e78016b46d [sdf] Only track memory in debug mode.
* src/sdf/ftsdf.c (*): Disable total memory
  usage tracking if the program is not in
  debug mode.
2020-08-02 16:33:20 +05:30
Anuj Verma c09257f0dd [sdfb] Removed Module.
Remove sdfb module. Instead of a new module
simply create a new renderer in the `sdf'
module for converting bitmaps to SDF.
2020-08-02 16:33:20 +05:30
Anuj Verma 80ba40341c Revert "[sdfb] Added new module to generate SDF from bitmap."
This reverts commit 2136eddbccfa59b7478d87fe0947b35ca6a157f8.
2020-08-02 16:33:20 +05:30
Anuj Verma f4918e139c Revert "[sdfb] Fix GNU Make build."
This reverts commit 0d9179f4e8cdb02986f5d01f178364e3f2b8dc07.
2020-08-02 16:33:20 +05:30
Anuj Verma fca2ed969c [sdfb] Fix GNU Make build.
* src/sdfb/rules.mk (SDFB_DRV_H): Fix name of
  the module specific error file `ftsdfberrs.h'.

* src/sdf/ftsdf.h (Optimizations): Fix warning.
  `warning: comma at end of enumerator list [-Wpedantic]'

* src/sdf/ftsdf.c (sdf_generate_coarse_grid): Remove
  unused variable `cindex', causes warning.
  `warning: unused variable 'cindex' [-Wunused-variable]'
2020-08-02 16:33:20 +05:30
Anuj Verma 04f2a34a7d [sdfb] Added new module to generate SDF from bitmap.
* src/sdfb/sdfb.c, src/sdfb/ftsdfbrend.c,
  src/sdfb/ftsdfb.c, src/sdfb/ftsdfbrend.h,
  src/sdfb/ftsdfb.h, src/sdfb/ftsdfberrs.h:
  Added files required by the `sdfb' renderer module.

* src/sdfb/rules.mk, src/sdfb/module.mk: Added
  files required to build the `sdfb' module using
  the default build system.

* CMakeLists.txt (BASE_SRCS): Add `src/sdfb/sdfb.c'
  to the variable.

* include/freetype/config/ftmodule.h: Added `sdfb'
  module declaration so that the module can be compiled
  when not compiling with GNU make.

* modules.cfg (RASTER_MODULES): Include `sdfb' module
  to the default rasterizer module list.

* include/freetype/ftmoderr.h: sdfb module error define

* src/sdf/rules.mk: Add EOF.
2020-08-02 16:33:20 +05:30
Anuj Verma 968a2f6237 [sdf] Added memory tracker.
* src/sdf/ftsdf.c (SDF_MemoryUser): Added struct
  which is used in place of `FT_Memory::user'.

* src/sdf/ftsdf.c (SDF_ALLOC, SDF_FREE): Added macros
  for allocating and deallocating memory. These macros
  restore the old `FT_Memory::user' before calling the
  relevant allocation/deallocation functions so as to
  not cause errors while debugging memory. And later
  they add the allocated memory size in a variable.

* src/sdf/ftsdf.c (*): Use `SDF_ALLOC', `SDF_FREE'
  instead of the `FT_' variant.
2020-08-02 16:33:19 +05:30
Anuj Verma dfdbc34108 Revert "[sdf] Added total memory allocation log."
This reverts commit d97e060891af0cc59af6fefa84484bec0d1794a4.
2020-08-02 16:33:19 +05:30
Anuj Verma 531d51eb2a [sdf] Added total memory allocation log.
* src/sdf/ftsdf.c (*): Replaced `FT_QNEW' and `FT_ALLOC_MULT'
  to custom macros in order to track memory allocations
  throughout the process of generating SDF. It basically
  add the memory being allocated to a static global variable
  and at the end outputs it at the end.
2020-08-02 16:33:19 +05:30
Anuj Verma 08d5a325dc * src/sdf/ftsdfrend.c (sdf_property_set): Minor fix. 2020-08-02 16:33:19 +05:30
Anuj Verma d40fc55dad [sdf] Temporary change.
Added new property to dynamically change the
optimization to be used to generate the SDF.
This can be used to compare the performance of
different optimization techniques without going
and recompiling the program.
And will also be used in the demo to check the
performance.
2020-08-02 16:33:19 +05:30
Anuj Verma dd5276601c [sdf] Added more properties.
Added two properties:
- `flip_y': To flip the generated SDF along the y axis.
- `flip_sign': By default outside is treated to have
   negative sign, setting `flip_sign' to 1 the outside
   pixels will have positive sign.

* src/sdf/ftsdf.* (*): Use the newly added properties.

* src/sdf/ftsdfrend.* (*): Add the newly added properties,
  and add functionality to set them using `FT_Property_Set'.
2020-08-02 16:33:19 +05:30
Anuj Verma 6b03b1c57a [sdf] Check for left or right fill.
* src/sdf/ftsdf.c (SDF_Params): Added struct which
  contains some internal data required by the rater-
  izer (such as left/right fill).

* src/sdf/ftsdf.c (sdf_raster_render): Determine the
  fill side and pass it to the `sdf_generate_' funcs.

* src/sdf/ftsdf.c (sdf_generate_): Use the new `SDF_Params'
  to generate SDF accordingly.
2020-08-02 16:33:19 +05:30
Anuj Verma 548bd3cf62 [sdf] Optimize the coarse grid optimization.
* src/sdf/ftsdf.c (sdf_generate_coarse_grid): Merge
  the relevant edge finding loop and shortest dist-
  ance search loop. We can find the relevant edges
  of a coarse grid and immediately use them to find
  the shortest distance of the points in the coarse
  grid. This drastically reduce memory usage and 
  performance.
  Also, do the sign assignment of the edges which was
  missing.
2020-08-02 16:33:19 +05:30
Anuj Verma ad696c07d3 * src/sdf/ftsdf.c (*): Fixed warnings.
Fixed various warnings and other few errors.
2020-08-02 16:33:19 +05:30
Anuj Verma 2045c7d9b3 * src/sdf/ftsdf.c (sdf_generate_coarse_grid): Comments.
Add more comments explaining the step by step
process of using coarse grid to increase the
performance of nearest distance search.
2020-08-02 16:33:19 +05:30
Anuj Verma 2afa0cb369 * src/sdf/ftsdf.c (sdf_generate_coarse_grid): Memory leak.
Release the allocated lists for the coarse grid after
we are done using them.
2020-08-02 16:33:19 +05:30
Anuj Verma 80c5bed575 [sdf] Completed the coarse grid optimization.
* src/sdf/ftsdf.c (sdf_generate_coarse_grid): Fixed
  an issue with position calculation and upside down
  images.
2020-08-02 16:33:19 +05:30
Anuj Verma 992609a1db [sdf] Partially completed the coarse grid optimization.
* src/sdf/ftsdf.c (sdf_generate_coarse_grid): Added
  functionality to check distances of all edges from
  the coarse grid and add the relevant edges to the 
  list.
  [Note]: The function is not complete yet.
2020-08-02 16:33:19 +05:30
Anuj Verma 111b755128 [sdf] Added the coarse grid optimization function.
* src/sdf/ftsdf.c (sdf_generate_coarse_grid): The
  function uses coarse grid to optimize nearest edge
  search performance.
2020-08-02 16:33:19 +05:30
Anuj Verma d9eeac807e [sdf] Remove use of `FT_List'.
Simply use a `next' pointer inside `SDF_Edge' and
`SDF_Contour' to create a linked list. This reduces
the number of allocations due to `FT_ListNode', also
we don't need a doubly linked list.

* src/sdf/ftsdf.c (SDF_Edge, SDF_Contour): Remove the
  `FT_List' and use a `next' pointer to create the
  linked list.

* src/sdf/ftsdf.c(sdf_edge_destructor, sdf_contour_destructor):
  Removed, not needed any more.

* src/sdf/ftsdf.c (*): Remove the use of `FT_List_'
  functions wherever necessary and sync with the new
  list.
2020-08-02 16:33:19 +05:30
Anuj Verma 8bf9da21e0 [sdf] Added subdivision optimization.
* src/sdf/ftsdfrend.c (sdf_generate_subdivision): The
  function generate SDF just like the `sdf_generate'
  function, but subdivide the curve into a number of
  lines and then use the `sdf_generate_bounding_box'
  function to generate SDF.
2020-08-02 16:33:19 +05:30
Anuj Verma fa7251ba35 [sdf] Added functions to subdivide a cubic curve.
* src/sdf/ftsdf.c (split_cubic, split_sdf_cubic):
  These functions can be used to subdivide a
  cubic bezier curve into line segments which can
  then be used to generate the SDF.

* src/sdf/ftsdf.c (split_sdf_shape): Added function
  to split a cubic into a line segments.

* src/sdf/ftsdf.c (sdf_shape_done): No need to pass
  `FT_Memory' as a parameter, it can be accessed
  from the `shape' struct.
2020-08-02 16:33:19 +05:30
Anuj Verma 1ba3da86e1 * src/sdf/ftsdf.c (split_sdf_shape): Typo. 2020-08-02 16:33:18 +05:30
Anuj Verma 90abe41ead * src/sdf/ftsdf.c (split_sdf_shape): Memory leak.
* src/sdf/ftsdf.c (split_sdf_shape): Memory leak.
  After recursion the edges variable becomes `NULL'
  so reassign it to deallocate the list completely.
2020-08-02 16:33:18 +05:30
Anuj Verma 470d02aa60 [sdf] Added functions to subdivide a conic curve.
* src/sdf/ftsdf.c (split_conic, split_sdf_conic):
  These functions can be used to subdivide a
  conic bezier curve into line segments which can
  then be used to generate the SDF.

* src/sdf/ftsdf.c (split_sdf_shape): Added function
  to split a outline into a line segments.
2020-08-02 16:33:18 +05:30
Anuj Verma de86a14b32 *[GSoC]ChangeLog: Fix typos. 2020-08-02 16:33:18 +05:30
Anuj Verma c4f64fc0e1 * src/sdf/ftsdfrend.c (sdf_generate_bounding_box): Add buffer for signs. 2020-08-02 16:33:18 +05:30
Anuj Verma e6576cc0e7 [sdf] Precompute the orthogonality. 2020-08-02 16:33:18 +05:30
Anuj Verma 1e3c41d19e [sdf] Added bounding box optimization. 2020-08-02 16:33:18 +05:30
preversewharf45 1d5d8ff288 * src/sdf/ftsdfrend.c (sdf_shape_dump): Use `%ld' to printf `signed long'. 2020-08-02 16:33:18 +05:30
Anuj Verma 44e16a0be6 * src/sdf/ftsdfrend.c (ft_sdf_render): Don't negate unsigned integers. 2020-08-02 16:33:18 +05:30
Anuj Verma 4fcc1653ca * src/sdf/ftsdf.c: Use ASCII single quote ('). 2020-08-02 16:33:18 +05:30
Anuj Verma ddf631729e [sdf] Added function to find shortest distance from a point to a cubic. 2020-08-02 16:33:18 +05:30
Anuj Verma 5baa2cefc6 * src/sdf/ftsdf.c (sdf_contour_get_min_distance): Use epsilon. 2020-08-02 16:33:18 +05:30
Anuj Verma 76e67227ec * src/sdf/ftsdf.c (sdf_shape_dump): Add more info to the debug output. 2020-08-02 16:33:18 +05:30
Anuj Verma 3e52d1a7a8 * src/sdf/ftsdf.c (MAX_NEWTON_DIVISIONS): Renamed to avoid confusion. 2020-08-02 16:33:18 +05:30
Anuj Verma 363f1e8de1 [sdf] Added Newton's method for conic curve. 2020-08-02 16:33:17 +05:30
Anuj Verma be3b7d7945 * src/sdf/ftsdf.c: More comments and code style fix. 2020-08-02 16:33:17 +05:30
Anuj Verma d0e3074738 [sdf] Make squared distances toggleable. 2020-08-02 16:33:17 +05:30
Anuj Verma 97474a7072 * src/sdf/ftsdf.c (get_min_distance_conic): Use 0, 1 in case of 0 roots. 2020-08-02 16:33:17 +05:30
Anuj Verma f9b4f37433 [sdf] Added function to find shortest distance from a point to a conic. 2020-08-02 16:33:17 +05:30
Anuj Verma 5cbcab183a * src/sdf/ftsdf.c (get_min_distance_line): Minor bug 2020-08-02 16:33:17 +05:30
Anuj Verma c8e3c5a420 * src/sdf/ftsdf.c: Refactored the code. 2020-08-02 16:33:17 +05:30
Anuj Verma f1de833a9d [sdf] Added functions to solve polynomial equations. 2020-08-02 16:33:17 +05:30
Anuj Verma 92a5312036 * src/sdf/ftsdf.c: Use FT_16D16 instead of FT_Fixed to avoid confusion. 2020-08-02 16:33:17 +05:30
Anuj Verma 811b6a7177 * src/sdf/ftsdf.c (cube_root, arc_cos): Added a few math functions. 2020-08-02 16:33:17 +05:30
Anuj Verma 38df99a1b4 [sdf] Fixed compilation under gnumake. 2020-08-02 16:33:17 +05:30
Anuj Verma 96883decbb [sdf] Added function to resolve corners. 2020-08-02 16:33:17 +05:30
Anuj Verma 03e6debb80 [sdf] The module can now generate SDF for outline with only lines. 2020-08-02 16:33:17 +05:30
Anuj Verma 063b65d583 [sdf] Added function to find shortest distance from a point to a line. 2020-08-02 16:33:17 +05:30
Anuj Verma 186cc478ae * src/sdf/ftsdf.c: Manually iterate through the lists. 2020-08-02 16:33:17 +05:30
Anuj Verma e9fce03032 [sdf] Added basic outline of the functions required to generate sdf. 2020-08-02 16:33:17 +05:30
Anuj Verma 6d4e00ae37 [sdf] Added `SDF_Raster_Params'. 2020-08-02 16:33:17 +05:30
Anuj Verma 3ebcbd7066 * include/freetype/ftimage.h (FT_RASTER_FLAG_): Added a new raster flag. 2020-08-02 16:33:16 +05:30
Anuj Verma f02d1acb89 * src/sdf/ftsdf.c (sdf_shape_dump): Use `FT_TRACEX' instead of `printf'. 2020-08-02 16:33:16 +05:30
Anuj Verma 63c2ac5fae * src/sdf/ftsdf.c (sdf_shape_dump): Added debugging function. 2020-08-02 16:33:16 +05:30
Anuj Verma 2f0d349d8c [sdf] Added functions to de-allocate `SDF_' structs. 2020-08-02 16:33:16 +05:30
Anuj Verma 54ff90398a [sdf] Decompose outline and store it in a `SDF_Shape'. 2020-08-02 16:33:16 +05:30
Anuj Verma 38bc88ae6f [sdf] Added essential enums and structs required. 2020-08-02 16:33:16 +05:30
Anuj Verma d21ceef7b4 [sdf] Added functionality to set and get module properties. 2020-08-02 16:33:16 +05:30
Anuj Verma 29c92db771 [sdf] Implemented a few functions required by a renderer module. 2020-08-02 16:33:16 +05:30
Anuj Verma c9d1149923 * include/freetype/ftimage.h (FT_Render_Mode_): Added new pixel mode. 2020-08-02 16:33:16 +05:30
Anuj Verma 08ba8d1422 added new `FT_RENDER_MODE_SDF' 2020-08-02 16:33:16 +05:30
Anuj Verma e408bda4f9 author check 2020-08-02 16:33:16 +05:30
preversewharf45 185d07b0cd added the structure of new `sdf' module 2020-08-02 16:33:16 +05:30
19 changed files with 7406 additions and 11 deletions

View File

@ -347,6 +347,7 @@ set(BASE_SRCS
src/pshinter/pshinter.c
src/psnames/psnames.c
src/raster/raster.c
src/sdf/sdf.c
src/sfnt/sfnt.c
src/smooth/smooth.c
src/truetype/truetype.c

1171
[GSoC]ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,5 +26,7 @@ FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
/* EOF */

View File

@ -3208,10 +3208,14 @@ FT_BEGIN_HEADER
* in the @FT_GlyphSlotRec structure gives the format of the returned
* bitmap.
*
* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity,
* indicating pixel coverage. Use linear alpha blending and gamma
* correction to correctly render non-monochrome glyph bitmaps onto a
* surface; see @FT_Render_Glyph.
* All modes except @FT_RENDER_MODE_MONO and @FT_RENDER_MODE_SDF use
* 256 levels of opacity, indicating pixel coverage. Use linear alpha
* blending and gamma correction to correctly render non-monochrome glyph
* bitmaps onto a surface; see @FT_Render_Glyph.
*
* The @FT_RENDER_MODE_SDF is s special render mode which uses as much
* 65536 distance values, indicating the signed distance from the grid
* position to the nearest outline.
*
* @values:
* FT_RENDER_MODE_NORMAL ::
@ -3238,6 +3242,13 @@ FT_BEGIN_HEADER
* bitmaps that are 3~times the height of the original glyph outline in
* pixels and use the @FT_PIXEL_MODE_LCD_V mode.
*
* FT_RENDER_MODE_SDF ::
* This mode corresponds to 16-bit signed distance fields bitmap. Each
* pixel in a SDF bitmap contains information about the nearest edge of
* the glyph outline. The distances are calculated from the center of
* the pixel and are positive if they are filled by the outline (i.e.
* inside the outline) and negative otherwise.
*
* @note:
* The selected render mode only affects vector glyphs of a font.
* Embedded bitmaps often have a different pixel mode like
@ -3251,6 +3262,7 @@ FT_BEGIN_HEADER
FT_RENDER_MODE_MONO,
FT_RENDER_MODE_LCD,
FT_RENDER_MODE_LCD_V,
FT_RENDER_MODE_SDF,
FT_RENDER_MODE_MAX

View File

@ -157,6 +157,12 @@ FT_BEGIN_HEADER
* in font files according to the OpenType specification. We haven't
* found a single font using this format, however.
*
* FT_PIXEL_MODE_GRAY16 ::
* A 16-bit per pixel bitmap used to represent signed distances in a
* signed distance field bitmap. This is currently only used while
* rendering using @FT_RENDER_MODE_SDF. Note that this is a 2.14
* fixed-point fractional value.
*
* FT_PIXEL_MODE_LCD ::
* An 8-bit bitmap, representing RGB or BGR decimated glyph images used
* for display on LCD displays; the bitmap is three times wider than
@ -184,6 +190,7 @@ FT_BEGIN_HEADER
FT_PIXEL_MODE_GRAY,
FT_PIXEL_MODE_GRAY2,
FT_PIXEL_MODE_GRAY4,
FT_PIXEL_MODE_GRAY16,
FT_PIXEL_MODE_LCD,
FT_PIXEL_MODE_LCD_V,
FT_PIXEL_MODE_BGRA,
@ -962,11 +969,17 @@ FT_BEGIN_HEADER
* will be clipped to a box specified in the `clip_box` field of the
* @FT_Raster_Params structure. Otherwise, the `clip_box` is
* effectively set to the bounding box and all spans are generated.
*
* FT_RASTER_FLAG_SDF ::
* This flag is set to indicate that a signed distance field glyph
* image should be generated. This is only used while rendering with
* `FT_RENDER_MODE_SDF' render mode.
*/
#define FT_RASTER_FLAG_DEFAULT 0x0
#define FT_RASTER_FLAG_AA 0x1
#define FT_RASTER_FLAG_DIRECT 0x2
#define FT_RASTER_FLAG_CLIP 0x4
#define FT_RASTER_FLAG_SDF 0x8
/* these constants are deprecated; use the corresponding */
/* `FT_RASTER_FLAG_XXX` values instead */

View File

@ -171,6 +171,7 @@
FT_MODERRDEF( Type42, 0x1400, "Type 42 module" )
FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" )
FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" )
FT_MODERRDEF( Sdf, 0x1700, "signed distance field raster module" )
#ifdef FT_MODERR_END_LIST

View File

@ -40,6 +40,7 @@ FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */
FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */
FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */
FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
FT_TRACE_DEF( sdf ) /* signed distance raster (ftsdf.c) */
FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */
/* Cache sub-system */

View File

@ -99,6 +99,8 @@ RASTER_MODULES += raster
# Anti-aliasing rasterizer.
RASTER_MODULES += smooth
# Signed distance field rasterizer.
RASTER_MODULES += sdf
####
#### auxiliary modules

View File

@ -4393,8 +4393,7 @@
render->glyph_format = clazz->glyph_format;
/* allocate raster object if needed */
if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
clazz->raster_class->raster_new )
if ( clazz->raster_class->raster_new )
{
error = clazz->raster_class->raster_new( memory, &render->raster );
if ( error )
@ -4441,8 +4440,7 @@
/* release raster object, if any */
if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
render->raster )
if ( render->raster )
render->clazz->raster_class->raster_done( render->raster );
/* remove from list */
@ -4537,9 +4535,6 @@
switch ( slot->format )
{
case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
break;
default:
if ( slot->internal->load_flags & FT_LOAD_COLOR )
{

1293
src/sdf/ftbsdf.c Normal file

File diff suppressed because it is too large Load Diff

3941
src/sdf/ftsdf.c Normal file

File diff suppressed because it is too large Load Diff

77
src/sdf/ftsdf.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef FTSDF_H_
#define FTSDF_H_
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
#include <freetype/ftimage.h>
/* common properties and function */
#include "ftsdfcommon.h"
FT_BEGIN_HEADER
/**************************************************************************
*
* @struct:
* SDF_Raster_Params
*
* @description:
* This struct must be used for the raster render function
* `FT_Raster_Render_Func' instead of `FT_Raster_Params' because
* the rasterizer require some addition information to render properly.
* So, this struct is used to pass additional parameter to the
* rasterizer.
*
* @fields:
* root ::
* The native raster params struct.
*
* spread ::
* This is and essential parameter/property required by the
* rendere. `spread' defines the maximum unsigned value that
* will be present in the final SDF output. For default value
* check `ftsdfcommon.h'.
*
* flip_sign ::
* By default the position values are inside the contours i.e.
* filled by a contour. If this property is true then that output
* will be opposite from the default i.e. negative will be filled
* by a contour.
*
* flip_y ::
* Setting this parameter to true maked the output image flipped
* along the y-axis.
*
* overlaps ::
* Set this to true to generate SDF for glyphs having overlapping
* contours. The overlapping support is limited to glyph which do
* not have self intersecting contours. Also, removing overlaps
* require a considerable amount of extra memory and this is not
* valid while generating SDF from bitmap.
*
* @note:
* It is valid for both `sdf' and `bsdf' renderer.
*
*/
typedef struct SDF_Raster_Params_
{
FT_Raster_Params root;
FT_UInt spread;
FT_Bool flip_sign;
FT_Bool flip_y;
FT_Bool overlaps;
} SDF_Raster_Params;
/* rasterizer to convert outline to SDF */
FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_sdf_raster;
/* rasterizer to convert bitmap to SDF */
FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_bitmap_sdf_raster;
FT_END_HEADER
#endif /* FTSDF_H_ */
/* END */

137
src/sdf/ftsdfcommon.h Normal file
View File

@ -0,0 +1,137 @@
/****************************************************
*
* This file contain common function and properties
* for both `sdf' and `bsdf' renderer.
*
*/
#ifndef FTSDFCOMMON_H_
#define FTSDFCOMMON_H_
#include <ft2build.h>
#include FT_CONFIG_CONFIG_H
#include <freetype/freetype.h>
FT_BEGIN_HEADER
/**************************************************************************
*
* default values (cannot be set individually for each renderer)
*
*/
/* default spread value */
#define DEFAULT_SPREAD 8
/* minimum spread supported by the renderer. */
#define MIN_SPREAD 2
/* maximum spread supported by the renderer. */
#define MAX_SPREAD 32
/**************************************************************************
*
* common definitions (cannot be set individually for each renderer)
*
*/
/* If it is defined to 1 then the rasterizer will use squared distances */
/* for computation. It can greatly improve the performance but there is */
/* a chance of overflow and artifacts. You can safely use it upto a */
/* pixel size of 128. */
#ifndef USE_SQUARED_DISTANCES
# define USE_SQUARED_DISTANCES 0
#endif
/**************************************************************************
*
* common macros
*
*/
/* convert int to 26.6 fixed point */
#define FT_INT_26D6( x ) ( x * 64 )
/* convert int to 16.16 fixed point */
#define FT_INT_16D16( x ) ( x * 65536 )
/* convert 26.6 to 16.16 fixed point */
#define FT_26D6_16D16( x ) ( x * 1024 )
/* Convenient macro which calls the function */
/* and returns if any error occurs. */
#define FT_CALL( x ) do \
{ \
error = ( x ); \
if ( error != FT_Err_Ok ) \
goto Exit; \
} while ( 0 )
/* [IMPORTANT]: The macro `VECTOR_LENGTH_16D16' is not always the same */
/* and must not be used anywhere except a few places. This macro is */
/* controlled by the `USE_SQUARED_DISTANCES' macro. It compute squared */
/* distance or actual distance based on `USE_SQUARED_DISTANCES' value. */
/* By using squared distances the performance can be greatly improved */
/* but there is a risk of overflow. Use it wisely. */
#if USE_SQUARED_DISTANCES
# define VECTOR_LENGTH_16D16( v ) ( FT_MulFix( v.x, v.x ) + \
FT_MulFix( v.y, v.y ) )
#else
# define VECTOR_LENGTH_16D16( v ) FT_Vector_Length( &v )
#endif
/**************************************************************************
*
* common typedefs
*
*/
typedef FT_Vector FT_26D6_Vec; /* with 26.6 fixed point components */
typedef FT_Vector FT_16D16_Vec; /* with 16.16 fixed point components */
typedef FT_Fixed FT_16D16; /* 16.16 fixed point representation */
typedef FT_Fixed FT_26D6; /* 26.6 fixed point representation */
typedef FT_Short FT_6D10; /* 6.10 fixed point representation */
typedef FT_BBox FT_CBox; /* control box of a curve */
/**************************************************************************
*
* common functions
*
*/
/* Original Algorithm: https://github.com/chmike/fpsqrt */
/* Use this to compute the square root of a 16.16 fixed */
/* point number. */
static FT_16D16
square_root( FT_16D16 val )
{
FT_ULong t, q, b, r;
r = val;
b = 0x40000000;
q = 0;
while( b > 0x40 )
{
t = q + b;
if( r >= t )
{
r -= t;
q = t + b;
}
r <<= 1;
b >>= 1;
}
q >>= 8;
return q;
}
FT_END_HEADER
#endif /* FTSDFCOMMON_H_ */
/* END */

18
src/sdf/ftsdferrs.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef FTSDFERRS_H_
#define FTSDFERRS_H_
#include <freetype/ftmoderr.h>
#undef FTERRORS_H_
#undef FT_ERR_PREFIX
#define FT_ERR_PREFIX Sdf_Err_
#define FT_ERR_BASE FT_Mod_Err_Sdf
#include <freetype/fterrors.h>
#endif /* FTSDFERRS_H_ */
/* END */

542
src/sdf/ftsdfrend.c Normal file
View File

@ -0,0 +1,542 @@
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/services/svprop.h>
#include <freetype/ftoutln.h>
#include <freetype/ftbitmap.h>
#include "ftsdfrend.h"
#include "ftsdf.h"
#include "ftsdferrs.h"
/**************************************************************************
*
* The macro FT_COMPONENT is used in trace mode. It is an implicit
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
* messages during execution.
*/
#undef FT_COMPONENT
#define FT_COMPONENT sdf
/**************************************************************************
*
* macros and default property values
*
*/
#define SDF_RENDERER( rend ) ( (SDF_Renderer)rend )
/**************************************************************************
*
* for setting properties
*
*/
/* property setter function */
static FT_Error
sdf_property_set( FT_Module module,
const char* property_name,
const void* value,
FT_Bool value_is_string )
{
FT_Error error = FT_Err_Ok;
SDF_Renderer render = SDF_RENDERER( FT_RENDERER( module ) );
FT_UNUSED( value_is_string );
if ( ft_strcmp( property_name, "spread" ) == 0 )
{
FT_Int val = *(const FT_Int*)value;
if ( val > MAX_SPREAD || val < MIN_SPREAD )
{
FT_TRACE0(( "[sdf] sdf_property_set: "
"the `spread' property can have a "
"value within range [%d, %d] (value provided %d)\n",
MIN_SPREAD, MAX_SPREAD, val ));
error = FT_THROW( Invalid_Argument );
goto Exit;
}
render->spread = (FT_UInt)val;
FT_TRACE7(( "[sdf] sdf_property_set: "
"updated property `spread' to %d\n", val ));
}
else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
{
FT_Int val = *(const FT_Int*)value;
render->flip_sign = val ? 1 : 0;
FT_TRACE7(( "[sdf] sdf_property_set: "
"updated property `flip_sign' to %d\n", val ));
}
else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
{
FT_Int val = *(const FT_Int*)value;
render->flip_y = val ? 1 : 0;
FT_TRACE7(( "[sdf] sdf_property_set: "
"updated property `flip_y' to %d\n", val ));
}
else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
{
FT_Int val = *(const FT_Int*)value;
render->overlaps = val;
FT_TRACE7(( "[sdf] sdf_property_set: "
"updated property `overlaps' to %d\n", val ));
}
else
{
FT_TRACE0(( "[sdf] sdf_property_set: "
"missing property `%s'\n", property_name ));
error = FT_THROW( Missing_Property );
}
Exit:
return error;
}
/* property getter function */
static FT_Error
sdf_property_get( FT_Module module,
const char* property_name,
void* value )
{
FT_Error error = FT_Err_Ok;
SDF_Renderer render = SDF_RENDERER( FT_RENDERER( module ) );
if ( ft_strcmp( property_name, "spread" ) == 0 )
{
FT_Int* val = (FT_Int*)value;
*val = render->spread;
}
else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
{
FT_Int* val = (FT_Int*)value;
*val = render->flip_sign;
}
else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
{
FT_Int* val = (FT_Int*)value;
*val = render->flip_y;
}
else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
{
FT_Int* val = (FT_Int*)value;
*val = render->overlaps;
}
else
{
FT_TRACE0(( "[sdf] sdf_property_get: "
"missing property `%s'\n", property_name ));
error = FT_THROW( Missing_Property );
}
return error;
}
FT_DEFINE_SERVICE_PROPERTIESREC(
sdf_service_properties,
(FT_Properties_SetFunc)sdf_property_set, /* set_property */
(FT_Properties_GetFunc)sdf_property_get ) /* get_property */
FT_DEFINE_SERVICEDESCREC1(
sdf_services,
FT_SERVICE_ID_PROPERTIES, &sdf_service_properties )
static FT_Module_Interface
ft_sdf_requester( FT_Renderer render,
const char* module_interface )
{
FT_UNUSED( render );
return ft_service_list_lookup( sdf_services, module_interface );
}
/**************************************************************************
*
* interface functions
*
*/
static FT_Error
ft_sdf_init( FT_Renderer render )
{
SDF_Renderer sdf_render = SDF_RENDERER( render );
sdf_render->spread = DEFAULT_SPREAD;
sdf_render->flip_sign = 0;
sdf_render->flip_y = 0;
sdf_render->overlaps = 0;
return FT_Err_Ok;
}
static FT_Error
ft_sdf_done( FT_Renderer render )
{
FT_UNUSED( render );
return FT_Err_Ok;
}
/* generate signed distance field from a glyph's slot image */
static FT_Error
ft_sdf_render( FT_Renderer module,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{
FT_Error error = FT_Err_Ok;
FT_Outline* outline = &slot->outline;
FT_Bitmap* bitmap = &slot->bitmap;
FT_Memory memory = NULL;
FT_Renderer render = NULL;
FT_Pos x_shift = 0;
FT_Pos y_shift = 0;
FT_Pos x_pad = 0;
FT_Pos y_pad = 0;
SDF_Raster_Params params;
SDF_Renderer sdf_module = SDF_RENDERER( module );
render = &sdf_module->root;
memory = render->root.memory;
/* check if slot format is correct before rendering */
if ( slot->format != render->glyph_format )
{
error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
/* check if render mode is correct */
if ( mode != FT_RENDER_MODE_SDF )
{
FT_ERROR(( "[sdf] ft_sdf_render: "
"sdf module only render when "
"using `FT_RENDER_MODE_SDF'\n" ));
error = FT_THROW( Cannot_Render_Glyph );
goto Exit;
}
/* deallocate the previously allocated bitmap */
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
FT_FREE( bitmap->buffer );
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
/* preset the bitmap using the glyph's outline; */
/* the sdf bitmap is similar to an antialiased bitmap */
/* with a slightly bigger size and different pixel mode */
if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) )
{
error = FT_THROW( Raster_Overflow );
goto Exit;
}
if ( !bitmap->rows || !bitmap->pitch )
goto Exit;
/* the padding will simply be equal to the `spread' */
x_pad = sdf_module->spread;
y_pad = sdf_module->spread;
/* apply the padding, will be in all the directions */
bitmap->rows += y_pad * 2;
bitmap->width += x_pad * 2;
/* ignore the pitch, pixel mode and set custom */
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY16;
bitmap->pitch = bitmap->width * 2;
bitmap->num_grays = 65535;
/* allocate new buffer */
if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
goto Exit;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
x_shift = 64 * -( slot->bitmap_left - x_pad );
y_shift = 64 * -( slot->bitmap_top + y_pad );
y_shift += 64 * (FT_Int)bitmap->rows;
if ( origin )
{
x_shift += origin->x;
y_shift += origin->y;
}
/* translate outline to render it into the bitmap */
if ( x_shift || y_shift )
FT_Outline_Translate( outline, x_shift, y_shift );
/* set up parameters */
params.root.target = bitmap;
params.root.source = outline;
params.root.flags = FT_RASTER_FLAG_SDF;
params.spread = sdf_module->spread;
params.flip_sign = sdf_module->flip_sign;
params.flip_y = sdf_module->flip_y;
params.overlaps = sdf_module->overlaps;
/* render the outline */
error = render->raster_render( render->raster, (const FT_Raster_Params*)&params );
Exit:
if ( !error )
{
/* the glyph is successfully rendered to a bitmap */
slot->format = FT_GLYPH_FORMAT_BITMAP;
}
else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
FT_FREE( bitmap->buffer );
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
if ( x_shift || y_shift )
FT_Outline_Translate( outline, -x_shift, -y_shift );
return error;
}
/* transform the glyph using matrix and/or delta */
static FT_Error
ft_sdf_transform( FT_Renderer render,
FT_GlyphSlot slot,
const FT_Matrix* matrix,
const FT_Vector* delta )
{
FT_Error error = FT_Err_Ok;
if ( slot->format != render->glyph_format )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
if ( matrix )
FT_Outline_Transform( &slot->outline, matrix );
if ( delta )
FT_Outline_Translate( &slot->outline, delta->x, delta->y );
Exit:
return error;
}
/* returns the control box of glyph's outline */
static void
ft_sdf_get_cbox( FT_Renderer render,
FT_GlyphSlot slot,
FT_BBox* cbox )
{
FT_ZERO( cbox );
if ( slot->format == render->glyph_format )
FT_Outline_Get_CBox( &slot->outline, cbox );
}
/* set render specific modes or attributes */
static FT_Error
ft_sdf_set_mode( FT_Renderer render,
FT_ULong mode_tag,
FT_Pointer data )
{
/* pass it to the rasterizer */
return render->clazz->raster_class->raster_set_mode( render->raster,
mode_tag,
data );
}
FT_DEFINE_RENDERER(
ft_sdf_renderer_class,
FT_MODULE_RENDERER,
sizeof( SDF_Renderer_Module ),
"sdf",
0x10000L,
0x20000L,
NULL,
(FT_Module_Constructor) ft_sdf_init,
(FT_Module_Destructor) ft_sdf_done,
(FT_Module_Requester) ft_sdf_requester,
FT_GLYPH_FORMAT_OUTLINE,
(FT_Renderer_RenderFunc) ft_sdf_render, /* render_glyph */
(FT_Renderer_TransformFunc) ft_sdf_transform, /* transform_glyph */
(FT_Renderer_GetCBoxFunc) ft_sdf_get_cbox, /* get_glyph_cbox */
(FT_Renderer_SetModeFunc) ft_sdf_set_mode, /* set_mode */
(FT_Raster_Funcs*)&ft_sdf_raster /* raster_class */
)
/*************************************************************************/
/*************************************************************************/
/** **/
/** BITMAP TO SDF CONVERTER **/
/** **/
/*************************************************************************/
/*************************************************************************/
/* generate signed distance field from glyph's bitmap */
static FT_Error
ft_bsdf_render( FT_Renderer module,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{
FT_Error error = FT_Err_Ok;
FT_Bitmap* bitmap = &slot->bitmap;
FT_Memory memory = NULL;
FT_Renderer render = NULL;
FT_Bitmap target;
FT_Pos x_pad = 0;
FT_Pos y_pad = 0;
SDF_Raster_Params params;
SDF_Renderer sdf_module = SDF_RENDERER( module );
/* initialize the bitmap in case any error occurs */
FT_Bitmap_Init( &target );
render = &sdf_module->root;
memory = render->root.memory;
/* check if slot format is correct before rendering */
if ( slot->format != render->glyph_format )
{
FT_ERROR(( "[bsdf] ft_bsdf_render: "
"bsdf renderer require the slot "
"format to be a bitmap\n" ));
error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
/* check if render mode is correct */
if ( mode != FT_RENDER_MODE_SDF )
{
FT_ERROR(( "[bsdf] ft_bsdf_render: "
"sdf module only render when "
"using `FT_RENDER_MODE_SDF'\n" ));
error = FT_THROW( Cannot_Render_Glyph );
goto Exit;
}
if ( origin )
{
FT_ERROR(( "[bsdf] ft_bsdf_render: "
"bsdf renderer can't translate "
"the bitmap\n" ));
error = FT_THROW( Unimplemented_Feature );
goto Exit;
}
if ( !bitmap->rows || !bitmap->pitch )
goto Exit;
FT_Bitmap_New( &target );
/* the padding will simply be equal to the `spread' */
x_pad = sdf_module->spread;
y_pad = sdf_module->spread;
/* apply the padding, will be in all the directions */
target.rows = bitmap->rows + y_pad * 2;
target.width = bitmap->width + x_pad * 2;
/* setup the target bitmap */
target.pixel_mode = FT_PIXEL_MODE_GRAY16;
target.pitch = target.width * 2;
target.num_grays = 65535;
if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) )
goto Exit;
/* set up parameters */
params.root.target = &target;
params.root.source = bitmap;
params.root.flags = FT_RASTER_FLAG_SDF;
params.spread = sdf_module->spread;
params.flip_sign = sdf_module->flip_sign;
params.flip_y = sdf_module->flip_y;
error = render->raster_render( render->raster,
(const FT_Raster_Params*)&params );
Exit:
if ( !error )
{
/* the glyph is successfully converted to a SDF */
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
FT_FREE( bitmap->buffer );
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
slot->bitmap = target;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
}
else if ( target.buffer )
{
FT_FREE( target.buffer );
}
return error;
}
FT_DEFINE_RENDERER(
ft_bitmap_sdf_renderer_class,
FT_MODULE_RENDERER,
sizeof( SDF_Renderer_Module ),
"bsdf",
0x10000L,
0x20000L,
NULL,
(FT_Module_Constructor) ft_sdf_init,
(FT_Module_Destructor) ft_sdf_done,
(FT_Module_Requester) ft_sdf_requester,
FT_GLYPH_FORMAT_BITMAP,
(FT_Renderer_RenderFunc) ft_bsdf_render, /* render_glyph */
(FT_Renderer_TransformFunc) ft_sdf_transform, /* transform_glyph */
(FT_Renderer_GetCBoxFunc) ft_sdf_get_cbox, /* get_glyph_cbox */
(FT_Renderer_SetModeFunc) ft_sdf_set_mode, /* set_mode */
(FT_Raster_Funcs*)&ft_bitmap_sdf_raster /* raster_class */
)
/* END */

100
src/sdf/ftsdfrend.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef FTSDFREND_H_
#define FTSDFREND_H_
#include <freetype/ftrender.h>
#include <freetype/ftmodapi.h>
#include <freetype/internal/ftobjs.h>
FT_BEGIN_HEADER
/**************************************************************************
*
* @struct:
* SDF_Renderer_Module
*
* @description:
* This struct extends the native renderer struct `FT_RendererRec'.
* It is basically used to store various parameters required by the
* renderer and some additional parameters which can be used to
* tweak the output of the renderer.
*
* @fields:
* root ::
* The native rendere struct.
*
* spread ::
* This is and essential parameter/property required by the
* rendere. `spread' defines the maximum unsigned value that
* will be present in the final SDF output. For default value
* check `ftsdfcommon.h'.
*
* flip_sign ::
* By default the position values are inside the contours i.e.
* filled by a contour. If this property is true then that output
* will be opposite from the default i.e. negative will be filled
* by a contour.
*
* flip_y ::
* Setting this parameter to true maked the output image flipped
* along the y-axis.
*
* overlaps ::
* Set this to true to generate SDF for glyphs having overlapping
* contours. The overlapping support is limited to glyph which do
* not have self intersecting contours. Also, removing overlaps
* require a considerable amount of extra memory and this is not
* valid while generating SDF from bitmap.
*
* @note:
* All properties except `overlaps' is valid for both `sdf' and
* `bsdf' renderer.
*
*/
typedef struct SDF_Renderer_Module_
{
FT_RendererRec root;
FT_UInt spread;
FT_Bool flip_sign;
FT_Bool flip_y;
FT_Bool overlaps;
} SDF_Renderer_Module, *SDF_Renderer;
/**************************************************************************
*
* @renderer:
* ft_sdf_renderer_class
*
* @description:
* Renderer to convert `FT_Outline' to signed distance fields.
*
*/
FT_DECLARE_RENDERER( ft_sdf_renderer_class )
/**************************************************************************
*
* @renderer:
* ft_bitmap_sdf_renderer_class
*
* @description:
* This is not exactly a renderer, it's just a converter which
* convert bitmaps to signed distance fields.
*
* @note:
* This is not a separate module, it is a part of the `sdf' module.
*
*/
FT_DECLARE_RENDERER( ft_bitmap_sdf_renderer_class )
FT_END_HEADER
#endif /* FTSDFREND_H_ */
/* END */

16
src/sdf/module.mk Normal file
View File

@ -0,0 +1,16 @@
FTMODULE_H_COMMANDS += SDF_RENDERER
FTMODULE_H_COMMANDS += BSDF_RENDERER
define SDF_RENDERER
$(OPEN_DRIVER) FT_Renderer_Class, ft_sdf_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)sdf $(ECHO_DRIVER_DESC)signed distance field renderer$(ECHO_DRIVER_DONE)
endef
define BSDF_RENDERER
$(OPEN_DRIVER) FT_Renderer_Class, ft_bitmap_sdf_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)bsdf $(ECHO_DRIVER_DESC)bitmap to signed distance field converter$(ECHO_DRIVER_DONE)
endef
#EOF

63
src/sdf/rules.mk Normal file
View File

@ -0,0 +1,63 @@
# sdf driver directory
#
SDF_DIR := $(SRC_DIR)/sdf
# compilation flags for the driver
#
SDF_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(SDF_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# sdf driver sources (i.e., C files)
#
SDF_DRV_SRC := $(SDF_DIR)/ftsdfrend.c \
$(SDF_DIR)/ftsdf.c \
$(SDF_DIR)/ftbsdf.c
# sdf driver headers
#
SDF_DRV_H := $(SDF_DIR)/ftsdfrend.h \
$(SDF_DIR)/ftsdf.h \
$(SDF_DIR)/ftsdferrs.h \
$(SDF_DIR)/ftsdfcommon.h
# sdf driver object(s)
#
# SDF_DRV_OBJ_M is used during `multi' builds.
# SDF_DRV_OBJ_S is used during `single' builds.
#
SDF_DRV_OBJ_M := $(SDF_DRV_SRC:$(SDF_DIR)/%.c=$(OBJ_DIR)/%.$O)
SDF_DRV_OBJ_S := $(OBJ_DIR)/sdf.$O
# sdf driver source file for single build
#
SDF_DRV_SRC_S := $(SDF_DIR)/sdf.c
# sdf driver - single object
#
$(SDF_DRV_OBJ_S): $(SDF_DRV_SRC_S) $(SDF_DRV_SRC) \
$(FREETYPE_H) $(SDF_DRV_H)
$(SDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SDF_DRV_SRC_S))
# sdf driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(SDF_DIR)/%.c $(FREETYPE_H) $(SDF_DRV_H)
$(SDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver list
#
DRV_OBJS_S += $(SDF_DRV_OBJ_S)
DRV_OBJS_M += $(SDF_DRV_OBJ_M)
# EOF

10
src/sdf/sdf.c Normal file
View File

@ -0,0 +1,10 @@
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include "ftsdfrend.c"
#include "ftbsdf.c"
#include "ftsdf.c"
/* END */