/**************************************************************************** * libs/libnx/nxfonts/nxfonts_convert.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include "nxfonts.h" /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ /* Make sure the bits-per-pixel value has been set */ #ifndef NXFONTS_BITSPERPIXEL # error "NXFONTS_BITSPERPIXEL must be defined on the command line" #endif /* Set up bit blit macros for this BPP */ #if NXFONTS_BITSPERPIXEL == 1 # define NXF_PIXELMASK 0x01 # define NXF_SCALEX(x) ((x) >> 3) # define NXF_PIXEL_T uint8_t # define NXF_MULTIPIXEL(p) ((p) ? 0xff : 0x00) #elif NXFONTS_BITSPERPIXEL == 2 # define NXF_PIXELMASK 0x03 # define NXF_SCALEX(x) ((x) >> 2) # define NXF_PIXEL_T uint8_t # define NXF_MULTIPIXEL(p) ((uint8_t)(p) << 6 | (uint8_t)(p) << 4 | (uint8_t)(p) << 2 | (p)) #elif NXFONTS_BITSPERPIXEL == 4 # define NXF_PIXELMASK 0x0f # define NXF_SCALEX(x) ((x) >> 1) # define NXF_PIXEL_T uint8_t # define NXF_MULTIPIXEL(p) ((uint8_t)(p) << 4 | (p)) #elif NXFONTS_BITSPERPIXEL == 8 # define NXF_SCALEX(x) (x) # define NXF_PIXEL_T uint8_t #elif NXFONTS_BITSPERPIXEL == 16 # define NXF_SCALEX(x) ((x) << 1) # define NXF_PIXEL_T uint16_t #elif NXFONTS_BITSPERPIXEL == 24 # define NXF_SCALEX(x) (((x) << 1) + (x)) # define NXF_PIXEL_T uint32_t #elif NXFONTS_BITSPERPIXEL == 32 # define NXF_SCALEX(x) ((x) << 2) # define NXF_PIXEL_T uint32_t #endif #if NXFONTS_BITSPERPIXEL < 8 # ifdef CONFIG_NXFONTS_PACKEDMSFIRST # define NXF_INITMASK (NXF_PIXELMASK << (8 - NXFONTS_BITSPERPIXEL)) # else # define NXF_INITMASK NXF_PIXELMASK # endif #endif /* Form a function name by concatenating two strings */ #define _NXF_FUNCNAME(a,b) a ## b #define NXF_FUNCNAME(a,b) _NXF_FUNCNAME(a,b) /**************************************************************************** * Private Data ****************************************************************************/ /**************************************************************************** * Public Data ****************************************************************************/ /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: nxf_convert_*bpp * * Description: * Convert the 1BPP font to a new pixel depth * * Input Parameters: * dest - The destination buffer provided by the caller. * height - The max height of the returned char in rows * width - The max width of the returned char in pixels * stride - The width of the destination buffer in bytes * bm - Describes the character glyph to convert * color - The color to use for '1' bits in the font bitmap * (0 bits are transparent) * * Returned Value: * OK on Success, ERROR: on failure with errno set appropriately. * (never fails) * ****************************************************************************/ int NXF_FUNCNAME(nxf_convert, NXFONTS_SUFFIX) (FAR NXF_PIXEL_T *dest, uint16_t height, uint16_t width, uint16_t stride, FAR const struct nx_fontbitmap_s *bm, nxgl_mxpixel_t color) { FAR uint8_t *line; FAR NXF_PIXEL_T *dptr; FAR const uint8_t *sptr; uint8_t bmbyte; int bmbit; int row; int col; int bmndx; #if NXFONTS_BITSPERPIXEL < 8 NXF_PIXEL_T mpixel; NXF_PIXEL_T mask; NXF_PIXEL_T pixel; int nbits; #endif /* Get the starting position */ line = (uint8_t *)dest + bm->metric.yoffset * stride + NXF_SCALEX(bm->metric.xoffset); /* Then copy the font */ height = ngl_min(bm->metric.height, height - bm->metric.yoffset); width = ngl_min(bm->metric.width, width - bm->metric.xoffset); /* Render each row of the glyph */ sptr = bm->bitmap; #if NXFONTS_BITSPERPIXEL < 8 mpixel = NXF_MULTIPIXEL(color); /* Handle each row in both the input and output */ for (row = 0; row < height; row++) { /* Process each byte in the glyph row */ col = 0; dptr = (FAR NXF_PIXEL_T *)line; pixel = *dptr; mask = NXF_INITMASK; nbits = 0; for (bmndx = 0; bmndx < bm->metric.stride && col < width; bmndx++) { bmbyte = *sptr++; /* Process each bit in one byte */ for (bmbit = 7; bmbit >= 0 && col < width; bmbit--, col++) { /* Is the bit set? */ if (bmbyte & (1 << bmbit)) { /* Yes.. set the bit to 'color' in the output */ pixel = ((pixel & ~mask) | (mpixel & mask)); } #ifdef CONFIG_NXFONTS_PACKEDMSFIRST mask >>= NXFONTS_BITSPERPIXEL; #else mask <<= NXFONTS_BITSPERPIXEL; #endif nbits += NXFONTS_BITSPERPIXEL; if (nbits >= 8) { *dptr++ = pixel; pixel = *dptr; mask = NXF_INITMASK; nbits = 0; } } } /* The entire glyph row has been rendered. * Handle any fractional bytes at the end of the row */ if (nbits > 0) { *dptr = pixel; } /* Point to the beginning of the next row */ line += stride; } #else /* Handle each row in both the input and output */ for (row = 0; row < height; row++) { /* Process each byte in the glyph */ col = 0; dptr = (FAR NXF_PIXEL_T *)line; for (bmndx = 0; bmndx < bm->metric.stride && col < width; bmndx++) { bmbyte = *sptr++; /* Process each bit in the byte */ for (bmbit = 7; bmbit >= 0 && col < width; bmbit--, col++) { /* Is the bit set? */ if (bmbyte & (1 << bmbit)) { /* Yes.. set the bit to 'color' in the output */ *dptr++ = color; } else { /* No... keep the background color in the output */ dptr++; } } } /* Advance to the beginning of the next line in the destination */ line += stride; } #endif return OK; }