static TT_Error Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph) { TT_UShort index; TT_Glyph_Metrics metrics; TT_Outline outline; int x_offset; int y_offset; TT_Error error; /* Load the glyph */ index = TT_Char_Index(font->map, UNICODE(ch)); error = TT_Load_Glyph(font->inst, font->glyph, index, TTLOAD_DEFAULT); if ( error ) return error; /* Get the bounding box */ TT_Get_Glyph_Metrics(font->glyph, &metrics); glyph->minx = (metrics.bbox.xMin & -64) / 64; glyph->maxx = ((metrics.bbox.xMax + 63) & -64) / 64; glyph->miny = (metrics.bbox.yMin & -64) / 64; glyph->maxy = ((metrics.bbox.yMax + 63) & -64) / 64; glyph->advance = (metrics.advance & -64) / 64; /* Adjust for bold and italic text */ if ( font->style & TTF_STYLE_BOLD ) { glyph->maxx += font->glyph_overhang; } if ( font->style & TTF_STYLE_ITALIC ) { glyph->maxx += round(font->glyph_italics); } /* Get the bitmap memory */ glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7; glyph->bitmap.rows = font->height; glyph->bitmap.cols = glyph->bitmap.width/8; glyph->bitmap.flow = TT_Flow_Down; glyph->bitmap.size = (glyph->bitmap.rows * glyph->bitmap.cols); if ( glyph->bitmap.size ) { glyph->bitmap.bitmap = malloc(glyph->bitmap.size); if ( ! glyph->bitmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->bitmap.bitmap, 0, glyph->bitmap.size); } else { glyph->bitmap.bitmap = 0; } /* Get the pixmap memory */ glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3; glyph->pixmap.rows = font->height; glyph->pixmap.cols = glyph->pixmap.width; glyph->pixmap.flow = TT_Flow_Down; glyph->pixmap.size = (glyph->pixmap.rows * glyph->pixmap.cols); if ( glyph->pixmap.size ) { glyph->pixmap.bitmap = malloc(glyph->pixmap.size); if ( ! glyph->pixmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->pixmap.bitmap, 0, glyph->pixmap.size); } else { glyph->pixmap.bitmap = 0; } /* Render the glyph into the bitmap and pixmap */ error = TT_Get_Glyph_Outline(font->glyph, &outline); /* Handle the italic style */ if ( font->style & TTF_STYLE_ITALIC ) { TT_Matrix shear; shear.xx = 1<<16; shear.xy = (int)(font->glyph_italics*(1<<16))/font->height; shear.yx = 0; shear.yy = 1<<16; TT_Transform_Outline(&outline, &shear); } x_offset = -glyph->minx * 64; y_offset = -round(font->descent) * 64; TT_Translate_Outline(&outline, x_offset, y_offset); error += TT_Get_Outline_Bitmap(engine, &outline, &glyph->bitmap); error += TT_Get_Outline_Pixmap(engine, &outline, &glyph->pixmap); /* Handle the bold style */ if ( font->style & TTF_STYLE_BOLD ) { int row, col; int offset; int pixel; Uint8 *pixmap; /* The bitmap is easy, just render another copy */ for ( offset=0; offset < font->glyph_overhang; ++offset ) { TT_Translate_Outline(&outline, 64, 0); error += TT_Get_Outline_Bitmap(engine, &outline,&glyph->bitmap); } x_offset += font->glyph_overhang*64; /* The pixmap is a little harder, we have to add and clamp */ for ( row=glyph->pixmap.rows-1; row >= 0; --row ) { pixmap = (Uint8 *)glyph->pixmap.bitmap + row*glyph->pixmap.cols; for (offset=1; offset<=font->glyph_overhang; ++offset) { for (col=glyph->pixmap.cols-1; col > 0; --col) { pixel=(pixmap[col]+pixmap[col-1]); if ( pixel > 4 ) { pixel = 4; } pixmap[col] = (Uint8)pixel; } } } } TT_Translate_Outline(&outline, -x_offset, -y_offset); was_error: if ( error ) { if ( glyph->bitmap.bitmap ) { free(glyph->bitmap.bitmap); glyph->bitmap.bitmap = 0; } if ( glyph->pixmap.bitmap ) { free(glyph->pixmap.bitmap); glyph->pixmap.bitmap = 0; } return error; } /* We're done, mark this glyph cached */ glyph->cached = ch; return TT_Err_Ok; }
.EndpointSize = VENDOR_OUT_EPSIZE, .PollingIntervalMS = 0x01 } }; /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate * via the language ID table available at USB.org what languages the device supports for its string descriptors. */ const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); /** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * Descriptor. */ const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(UNICODE(USB_SETTINGS_VENDOR_NAME)); /** Product descriptor string. This is a Unicode string containing the product's details in human readable form, * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device * Descriptor. */ const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(UNICODE(USB_SETTINGS_DEVICE_NAME)); /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" * documentation) by the application code so that the address and size of a requested descriptor can be given * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the * USB host. */ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex,