bittermelon 2.3.1
CRAN release: 2026-03-27
Breaking changes
-
write_hex()andwrite_yaff()now throw an error instead of automatically clamping when given multi-colored glyphs.- Now explicitly use
bm_lapply(font, as_bm_bitmap)and/orbm_clamp(font)to cast to an appropriatefontobject before writing.
- Now explicitly use
New features
-
as_bm_pixmap()gains acharactermethod analogous toas_bm_bitmap.character()for rendering strings from abm_font()font. -
read_yaff()now supports the experimentallevelsproperty for greyscale fonts returning abm_font()withbm_pixmap()glyphs. Uninked pixels are encoded as"#FFFFFF00"(transparent).read_yaff()gains afgargument (default"#000000FF") to control the foreground color; its RGB values are used for inked pixels and its alpha is multiplied by the level fraction to set pixel transparency. -
bm_bytepad()pads bitmap widths to the nearest multiple of 8 (i.e. nearest byte) by adding pixels on the right (e.g. as required by the BDF font format) (#43). -
bm_extend()gains amodeargument. The defaultmode = "constant"fills new pixels withvalue(existing behavior). Usemode = "edge"to fill new pixels by replicating the nearest edge pixel (#81). -
bm_extend()gainswidth_multiples_ofandheight_multiples_ofarguments that pad the bitmap’s width or height to the nearest multiple of a given integer (#43). -
bm_rotate()gainsin_placeandvaluearguments to rotate the glyph in place without changing the background padding (#70). -
bm_shift()gains anoverflowargument. The defaultoverflow = "clip"silently clips content that would be pushed off the bitmap (matching the previous behavior). Useoverflow = "error"to throw an error if non-padding content would be clipped, oroverflow = "wrap"to wrap content around to the other side (#74). -
summary.bm_font()summarizes abm_font()object, showing the font name (if available), the bitmap class, the number of characters, and coverage of Unicode blocks (#35).
Bug fixes and minor improvements
-
is_bm_list()gains aclassargument to optionally check that all elements inherit from at least one of the specified classes. -
read_monobit()gains a...argument that is passed on toread_yaff(), allowing use of arguments such asfg. -
read_yaff()now correctly reads multi-line property values; they are stored as a length-one character string with embedded newlines. Previously, a bug caused incorrect indices to be used when computing value ranges, and the values were stored as a character vector. -
read_yaff()now correctly captures global comments from files where every line is a comment (no blank lines). Previously, line indices were returned instead of the comment strings. - Slicing a
bm_font()orbm_list()with[now preserves the class and attributes (includingcommentsandproperties) of the original object.
bittermelon 2.2.1
CRAN release: 2026-01-29
New features
-
bm_extract()can extract parts of a bitmap (#89). -
is_supported_bitmap()tests whether the object is one of the bitmap formats supported by the functions in this package (i.e.bm_bitmap,bm_pixmap,magick-image,nativeRaster, orraster).
bittermelon 2.1.1
CRAN release: 2025-01-16
New features
New
as.data.frame.bm_bitmap()andas.data.frame.bm_pixmap()which returns a data frame with (x,y) coordinates for the bitmap pixels (#78). Thanks @coolbutuseless for suggestion.bm_pixel_picker()lets you use an interactive graphics device to click on a bitmap’s pixels and learn the column/row coordinates for the clicked pixel and its integer/color value (#85).-
New
as_bm_bitmap()/as_bm_pixmap()class methods:-
as_bm_bitmap.lofi-matrix()/as_bm_pixmap.lofi-matrix()(from lofifonts)
-
Bug fixes and minor improvements
- The
bgandfgarguments offormat.bm_bitmap()andprint.bm_bitmap()now accept a (single) cli ANSI style function in addition to lists of cli ANSI style functions and character vectors of R color strings. -
bm_downscale()no longer returns invisibly. -
as_bm_bitmap.array()/as_bm_pixmap.array()can now handle “raw” arrays as returned bypdftools::pdf_render_page(numeric = FALSE)andwebp::read_webp(numeric = FALSE)(#83). -
col2int()now uses colorfast to make the conversion if available. If colorfast is unavailable will fall back to farver if available. If neither are available will throw an error (#66).
bittermelon 2.0.2
CRAN release: 2024-06-25
Breaking changes
-
We no longer embed an increasingly outdated version of monobit.
-
monobithas now grown too large to embed within bittermelon and stay within CRAN package size limits. - Users interested in reading/writing bitmap fonts formats other than
.hexand.yafffiles will need to manually install their own version ofmonobitusingpip3 install monobit. - The interpretation of the argument
monobit_pathinread_monobit()andwrite_monobit()and the global optionbittermelon.monobit_pathhas been changed and now means the path to pass tobase::Sys.which()(if the new default name"monobit-convert"is not good enough). - Any previously installed versions of
monobittorappdirs::site_config_dir("bittermelon", "monobit")orrappdirs::user_config_dir("bittermelon", "monobit")will now be ignored. Please consider deleting them or update thebittermelon.monobit_pathoption to point to them. - The function
update_monobit()has been removed.
-
The default
colargument toas.raster.bm_bitmap()andplot.bm_bitmap()is nowgetOption("bittermelon.col", col_bitmap)where the newly exportedcol_bitmap = c("transparent", "black", "grey50", "grey25"). In particular by default0Lvalues will now be cast to “transparent” instead of “grey80”. To get the old behaviour setoptions("bittermelon.col" = c("grey80", "black", "grey40")).We no longer export a generic S3
which()method which by default callsbase::which()and remove the specialwhich.bm_bitmap()method that first cast to a logical. Instead now usewhich(as.logical(x))forbm_bitmap()objects.Many functions were upgraded to S3 generics that support more bitmap objects. The first argument of these functions are now usually
xinstead ofbm_object. If specifying the first argument by name instead of positionally you’ll now need to usexinstead.bm_distort()is now a wrapper aroundmagick::image_resize().x,width, andheightare now the only supported positional arguments and theinterpolate,vp, andpng_devicearguments are no longer supported. It now requires the suggested package magick.The default for
heightinbm_expand()is now the value ofwidthi.e.bm_expand(x, 2L)will now double the size ofxin both directions. To get the previous behaviour you may now need to explicitly setheight = 1L.
New features
-
bm_pixmap()creates a S3 object representing raster image pixmaps (#60). Intended to represent pixel art / sprites but can be used to represent more complicated raster images. It supports the following S3 methods:-
as_bm_pixmap()is a S3 method that coerces objects tobm_pixmap()objects-
as_bm_pixmap.array()(e.g. from png, jpeg, and webp) as_bm_pixmap.bm_bitmap()as_bm_pixmap.default()-
as_bm_pixmap.glyph_bitmap()(from{fontr}) as_bm_pixmap.grob()-
as_bm_pixmap.magick-image()(from magick) as_bm_pixmap.matrix()-
as_bm_pixmap.maze()(from{mazing}) as_bm_pixmap.nativeRaster()-
as_bm_pixmap.pattern_square()(from gridpattern) -
as_bm_pixmap.pattern_weave()(from gridpattern) -
as_bm_pixmap.pixeltrix()(from pixeltrix) -
as_bm_pixmap.pixmapGrey()(from{pixmap}) -
as_bm_pixmap.pixmapIndexed()(from{pixmap}) -
as_bm_pixmap.pixmapRGB()(from{pixmap}) as_bm_pixmap.raster()
-
is_bm_pixmap()returnsTRUEforbm_pixmap()objects (or subclasses) andFALSEfor all other objects.Some of the “Ops” group generic operators such as
==and!=.
-
The following functions are now S3 generics that have methods that support (at least)
bm_bitmap()/bm_pixmap(),bm_font()/bm_list(), “magick-image”, and “raster” / “nativeRaster” objects: -
New bitmap/pixmap manipulation function:
bm_downscale()-
bm_gray()with aliasbm_grey() bm_invert()bm_replace()
-
Other new functions:
-
bm_print()andbm_format()can be used to pretty print bitmap objects to the terminal. -
farming_crops_16x16()returns a named list of lists of twenty farming crops in five stages of growth plus a portrait asbm_pixmap()objects. -
bm_options()returns a list of (current or default)bittermelonoptions values. -
px_auto()determines which character vector to use for “pixels” based on whethercli::is_utf8_output()isTRUEor not.
-
-
New
as_bm_bitmap()class methods:-
as_bm_bitmap.array()(e.g. from png, jpeg, and webp) as_bm_bitmap.bm_pixmap()-
as_bm_pixmap.glyph_bitmap()(from{fontr}) -
as_bm_bitmap.magick-image()(from magick) -
as_bm_bitmap.maze()coerces (from{mazing}) as_bm_bitmap.nativeRaster()-
as_bm_bitmap.pattern_square()(from gridpattern) -
as_bm_bitmap.pattern_weave()(from gridpattern) -
as_bm_bitmap.pixeltrix()(from pixeltrix) -
as_bm_bitmap.pixmapGrey()(from{pixmap}) -
as_bm_bitmap.pixmapIndexed()(from{pixmap}) -
as_bm_bitmap.pixmapRGB()(from{pixmap}) as_bm_bitmap.raster()
-
-
New
"bm_bitmap"class S3 generics features:-
format.bm_bitmap()andprint.bm_bitmap()gain adownscaleargument to downscale the image togetOption("width")(if necessary to fit in terminal). -
as.raster.bm_bitmap()now has anativeargument to cast to “nativeRaster” objects. -
as.matrix.bm_bitmap()now has afirst_row_is_topargument to flip the rows so that the first row represents the top of the bitmap instead of the bottom. - New
as.array.bm_bitmap()function for writing bitmaps withpng::writePNG()and friends.
-
-
New color utilities:
-
Following
bm_list()upgrades (#69):- Can now contain
bm_bitmap(),bm_pixmap(), “magick-image”, “nativeRaster”, or “raster” bitmaps. -
as_bm_list.list()now supportsFUNfor a function which can be applied to each element of the list such asidentity(),as_bm_bitmap(), andas_bm_pixmap().
- Can now contain
-
New package options:
- The
bittermelon.downscaleoption can be used to change the default for thedownscaleargument informat.bm_bitmap(),print.bm_bitmap(),format.bm_pixmap(), andprint.bm_pixmap().
- The
Bug fixes and minor improvements
- The
bgandfgarguments offormat.bm_bitmap()andprint.bm_bitmap()now accept lists of cli ANSI style functions in addition to color strings. -
print.bm_bitmap()no longer silently ignores itscompressargument. - The default value of the option
bittermelon.pxis nowpx_auto(). This means ifcli::is_utf8_output()isFALSEwe now default topx_asciiinstead ofpx_unicode. - Fixes bugs in
write_monobit(),write_yaff(), and the unit tests if any of the optionsbittermelon.fg,bittermelon.bg, orbittermelon.compressare set away from their defaults. -
read_yaff()now correctly handles octal codepoint and (single) character labels. -
write_yaff()now encloses “tag” labels with double quotes. -
hex2ucp()now also callsbase::toupper()on the input value. -
bm_bitmap()objects now also have the class"bm_matrix"(as does the newbm_pixmap()objects). -
format.bm_bitmap(x)no longer throws an error whenxhas zero columns (#68). -
bm_flip()now has avalueargument to set the background padding value to use ifin_placeisTRUE.
bittermelon 1.1.2
CRAN release: 2023-12-15
Bug fixes and minor improvements
- Updates
is_combining_character()so it will continue to work after a breaking change inUnicode::u_char_property()’s behavior introduced in{Unicode}v15.1.0-1 (#55).
bittermelon 1.1.1
CRAN release: 2023-02-12
New features
-
read_hex()has new argumentucp. Character vector of Unicode Code Points: glyphs not in this vector won’t be read in. IfNULL(default) read every glyph in the font (#52).
Bug fixes and minor improvements
-
block2ucp()andstr2ucp()are now vectorized in their first argument.
bittermelon 1.0.0
CRAN release: 2022-08-15
This update has no user-facing changes (at the request of CRAN we re-built our package man pages with an updated version of the roxygen2 package to avoid a deprecated html image alignment warning).
bittermelon 0.2.1
CRAN release: 2021-11-01
New features
- New function
bm_compose()simplifiesbm_list()object by applying combining marks to preceding glpyhs (composing new graphemes) (#42). -
as_bm_bitmap.character()has new argumentscomposeandpua_combiningto compose graphemes using combining characters. -
as_bm_bitmap.character()direction argument now supports combining in combinations of horizontal/vertical directions such asleft-to-right, top-to-bottom(#47). -
is_combining_character()has new argumentpua_combiningwhich is character vector of additional Unicode code points to be considered “combining” characters (such as those in the Private Use Area of a font). Defaults tocharacter(0). - We now include the 5x8 Fixed font (in addition to the 4x6 and 6x13 Fixed fonts already included in earlier version).
-
read_monobit()andwrite_monobit()take new argumentmonobit_pathindicating the directory path containingmonobitto use. Default will be to look infile.path(rappdirs::user_config_dir("bittermelon"), "monobit"),file.path(rappdirs::site_config_dir("bittermelon"), "monobit"), andsystem.file("monobit", package = "bittermelon")(in that order). New package optionbittermelon.monobit_pathcan be used to set a new default. (#48) - New function
update_monobit()which downloads the most up to date (upstream) version of monobit. Although we continue to embed an older, more compact version ofmonobitin this package the newest versions ofmonobitare too large to embed within this package and must be downloaded separately.
Bug fixes and minor improvements
- Updates the embedded version of monobit. In particular
monobitshould now better handle Amiga, AngelCode BMFont, X11/Adobe BDF, and C/C++ source code bitmap fonts and be able to natively read/write bzip2, gzip, or lzma compressed fonts. - Fixes bug in
is_combining_character(). Now “combining enclosing” characters are correctly classified as combining characters. - Fixes bug in
bm_expand()for bitmaps with zero columns/rows.
bittermelon 0.1.3
CRAN release: 2021-09-09
-
bm_bitmap()creates a S3 object representing bitmaps (#1). Intended to represent bitmap font glyphs but can be used to represent more complicated bitmaps. Non-binary bitmaps are allowed (but we are unlikely to ever support exporting color bitmap fonts). It supports the following S3 methods:[.bm_bitmap()and[<-.bm_bitmap()(#38)as.raster.bm_bitmap()(#3) andplot.bm_bitmap()(#4)which.bm_bitmap()(withwhich()redefined as a S3 generic that defaults tobase::which())-
as_bm_bitmap()is a S3 method that coerces objects tobm_bitmap()objects is_bm_bitmap()returnsTRUEforbm_bitmap()objects (or subclasses) andFALSEfor all other objects.
-
bm_list()creates a S3 object representing a list ofbm_bitmap()objects. It supports the following S3 methods:The “min()”, “max()”, and “range()” functions from the “Summary” group generic methods
as.list.bm_list()“slicing” with
[]returnsbm_list()objects.-
as_bm_list()is a S3 method that coerces objects tobm_list()objects is_bm_list()returnsTRUEforbm_list()objects (or subclasses) andFALSEfor all other objects.
-
bm_font()creates a S3 object representing bitmap fonts (#5). it is a subclass of thebm_list()class.-
as_bm_font()is a S3 method that coerces objects tobm_font()objects is_bm_font()returnsTRUEforbm_font()objects (or subclasses) andFALSEfor all other objects.
-
-
The following functions can modify
bm_bitmap()objects as well as all the bitmaps inbm_list()objects (includingbm_font()):- All the “Ops” group generic operators such as
!. -
bm_bold()creates a basic “bold” effect (#16) -
bm_clamp()clamps integer values between a lower and upper value. By default coerces the bitmap to binary values. -
bm_compress()shrinks bitmaps by a factor of two using a “block elements” scheme (#31). -
bm_distort()resizes bitmaps via distortion. -
bm_expand()expands bitmap(s) by repeating each row and/or column (#19). -
bm_extend()extends the bitmap by a specified value in specified directions (#11). -
bm_flip()flips (reflects) bitmaps (or just their glyphs in place) vertically, horizontally, or both. -
bm_glow()adds a basic “glow” effect (#17) -
bm_mask()uses amaskbitmap to set certain pixels in abasebitmap to zero (#21). -
bm_outline()computes a “outline” bitmap from a bitmap. -
bm_overlay()merges bitmaps by overlaying one over another (#18). -
bm_pad()adjusts bitmap padding lengths (#40). -
bm_resize()resizes the bitmap to a desired width and/or height via extending/trimming (#34). -
bm_rotate()losslessly rotates bitmaps 0, 90, 180, or 270 degrees (#15). -
bm_shadow()adds a “shadow effect” (#17) -
bm_shift()shifts elements within a bitmap in a specified direction while preserving original width and height (#13). -
bm_trim()trims the bitmap in specified directions (#12).
- All the “Ops” group generic operators such as
-
Support for reading and writing bitmap fonts
-
read_hex()reads in a “hex” font as abm_font()object (#8) -
write_hex()writes out a “hex” font of abm_font()object (#9) -
read_yaff()reads in a “yaff” font as abm_font()object (#6) -
write_yaff()writes out a “yaff” font of abm_font()object (#7) -
read_monobit()reads in a bitmap font as abm_font()object usingmonobit. Supports multiple bitmap font formats. Requires Python to be available. (#26) -
write_monobit()writes out a bitmap font of abm_font()object usingmonobit. Supports multiple bitmap font formats. Requires Python to be available. (#27)
-
-
Other utility functions
-
c()S3 methods combine bitmap objects. In particular when using it to combine fonts the later fonts “update” the glyphs in the earlier fonts. -
bm_call()executes a function on bitmap objects. It places the bitmap object as the first argument so it is a bit friendlier to use in pipes thanbase::do.call()and allows specifying additional arguments to the function. -
bm_edit()allows editing abm_bitmap()object via text editor indicating zeroes with a.and ones with a@(as inyafffont format). -
bm_lapply()applies a function to each element in abm_list()orbm_font()object. It returns anotherbm_list()orbm_font()object with the same metadata as the original object. -
bm_widths()andbm_heights()calculates the widths and heights of the bitmaps inbm_list()orbm_font()objects. -
bm_padding_lengths()computes the padding lengths of a target value for the top, right, bottom, and left sides of the bitmap. -
block2ucp(),hex2ucp(),int2ucp(),name2ucp(),range2ucp(), andstr2ucp()return Unicode code points as character vectors. -
ucp2label()returns Unicode code labels as character vectors. -
is_combining_character()returnsTRUEorFALSEif Unicode code point refers to a combining character. -
ucp_sort()sorts Unicode code points
-