/* TODO: this need a rework..., encoding to atari st doesn|t always work. ( gui_add_to_clipboard...) */ nserror utf8_to_local_encoding(const char *string, size_t len, char **result) { nserror r; r = utf8_to_enc(string, "ATARIST", len, result); if(r != NSERROR_OK) { r = utf8_to_enc(string, "UTF-8", len, result); assert( r == NSERROR_OK ); } return r; }
utf8_convert_ret utf8_to_font_encoding(const struct font_desc* font, const char *string, size_t len, char **result) { return utf8_to_enc(string, font->encoding, len, result); }
static int str_width( FONT_PLOTTER self,const plot_font_style_t *fstyle, const char * str, size_t length, int * width ) { short cw, ch, cellw, cellh; short pxsize; short fx=0; lstr = (char*)str; utf8_to_enc(str, "ATARIST", length, &lstr ); assert( lstr != NULL ); int slen = strlen(lstr); if( fstyle->flags & FONTF_ITALIC ) fx |= 4; if( fstyle->flags & FONTF_OBLIQUE ) fx |= 16; if( fstyle->weight > 450 ) fx |= 1; vst_effects( self->vdi_handle, fx ); /* TODO: replace 90 with global dpi setting */ pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 ); vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh); *width = slen * cellw; free( (void*)lstr ); lstr = NULL; return( 0 ); }
utf8_convert_ret utf8_to_local_encoding(const char *string, size_t len, char **result) { return utf8_to_enc(string, "CP1252", len, result); }
nserror utf8_to_local_encoding(const char *string, size_t len, char **result) { const char *encname = "ISO-8859-1"; #ifdef __amigaos4__ LONG charset; charset = GetDiskFontCtrl(DFCTRL_CHARSET); encname = (const char *) ObtainCharsetInfo(DFCS_NUMBER, charset, DFCS_MIMENAME); #endif return utf8_to_enc(string,encname,len,result); }
static int str_split( FONT_PLOTTER self, const plot_font_style_t * fstyle, const char *string, size_t length,int x, size_t *char_offset, int *actual_x ) { short cw, ch, cellw, cellh; short pxsize; short fx=0; int i; lstr = (char*)string; int slen = 0; int last_space_x = 0; int last_space_idx = 0; utf8_to_enc(string, "ATARIST", length, &lstr ); assert( lstr != NULL ); slen = strlen(lstr); if( fstyle->flags & FONTF_ITALIC ) fx |= 4; if( fstyle->flags & FONTF_OBLIQUE ) fx |= 16; if( fstyle->weight > 450 ) fx |= 1; vst_effects( self->vdi_handle, fx ); pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 ); vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh); *actual_x = 0; *char_offset = 0; int cpos=0; for( i=0; i<slen; i++) { if( lstr[i] == ' ' ) { last_space_x = *actual_x; last_space_idx = cpos; } if( *actual_x > x ) { *actual_x = last_space_x; *char_offset = last_space_idx; return true; } *actual_x += cellw; cpos++; } *char_offset = cpos; free( (void*)lstr ); lstr = NULL; return( 0 ); }
static int text( FONT_PLOTTER self, int x, int y, const char *text, size_t length, const plot_font_style_t *fstyle ) { /* todo: either limit the string to max 80 chars, or use v_ftext instead of v_gtext */ short cw, ch, cellw, cellh; short pxsize=8; short fx=0; lstr = (char*)text; utf8_to_enc(text, "ATARIST", length, &lstr ); assert( lstr != NULL ); int slen = strlen(lstr); size_t mylen = MIN(511, slen ); char textcpy[mylen+1]; textcpy[mylen] = 0; strncpy((char*)&textcpy, lstr, mylen+1 ); if( fstyle != NULL){ if( fstyle->flags & FONTF_ITALIC ) fx |= 4; if( fstyle->flags & FONTF_OBLIQUE ) fx |= 4; if( fstyle->weight > 450 ) fx |= 1; /* TODO: netsurf uses 90 as default dpi ( somewhere defined in libcss), use that value or pass it as arg, to reduce netsurf dependency */ pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 ); } x += CURFB(self->plotter).x; y += CURFB(self->plotter).y; vst_effects( self->vdi_handle, fx ); vst_alignment(vdih, 0, 4, &cw, &ch ); vst_height( self->vdi_handle, pxsize, &cw, &ch, &cellw, &cellh); vswr_mode( self->vdi_handle, MD_TRANS ); vst_rgbcolor(self->vdi_handle, fstyle->foreground ); if( atari_sysinfo.gdos_FSMC ){ v_ftext( self->vdi_handle, x, y, (char*)&textcpy ); } else { v_gtext( self->vdi_handle, x, y, (char*)&textcpy ); } free( lstr ); return( 0 ); }
static int pixel_pos( FONT_PLOTTER self, const plot_font_style_t * fstyle,const char *string, size_t length,int x, size_t *char_offset, int *actual_x ) { short cw, ch, cellw, cellh; short pxsize=0; short fx=0; lstr = (char*)string; int i=0; int curpx=0; utf8_to_enc(string, "ATRIST", length, &lstr ); assert( lstr != NULL ); int slen = strlen(lstr); if( fstyle->flags & FONTF_ITALIC ) fx |= 4; if( fstyle->flags & FONTF_OBLIQUE ) fx |= 16; if( fstyle->weight > 450 ) fx |= 1; vst_effects( self->vdi_handle, fx ); pxsize = ceil( (fstyle->size/FONT_SIZE_SCALE) * 90 / 72 ); vst_height( self->vdi_handle, pxsize ,&cw, &ch, &cellw, &cellh); *actual_x = 0; *char_offset = 0; for( i=0; i<slen; i++) { *actual_x += cellw; if( *actual_x > x) { *actual_x -= cellw; *char_offset = i; break; } } free( (void*)lstr ); lstr = NULL; return( 0 ); }
/** * Convert a UTF-8 encoded string into the system local encoding * * \param string The string to convert * \param len The length (in bytes) of the string, or 0 * \param result Pointer to location in which to store result * \return An nserror code */ nserror utf8_to_local_encoding(const char *string, size_t len, char **result) { os_error *error; int alphabet, i; size_t off, prev_off; char *temp, *cur_pos; const char *enc; nserror err; assert(string); assert(result); /* get length, if necessary */ if (len == 0) len = strlen(string); /* read system alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) alphabet = territory_ALPHABET_LATIN1; /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { *result = strndup(string, len); return NSERROR_OK; } /* get encoding name */ enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] : (alphabet == 120 ? localencodings[CONT_ENC_END - 100 + 1] : localencodings[0])); /* create output buffer */ *(result) = malloc(len + 1); if (!(*result)) return NSERROR_NOMEM; *(*result) = '\0'; prev_off = 0; cur_pos = (*result); /* Iterate over string, converting input between unconvertable * characters and inserting appropriate output for characters * that iconv can't handle. */ for (off = 0; off < len; off = utf8_next(string, len, off)) { if (string[off] != 0xE2 && string[off] != 0xC5 && string[off] != 0xEF) continue; for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { if (strncmp(string + off, special_chars[i].utf, special_chars[i].len) != 0) continue; /* 0 length has a special meaning to utf8_to_enc */ if (off - prev_off > 0) { err = utf8_to_enc(string + prev_off, enc, off - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); cur_pos += strlen(temp); free(temp); } *cur_pos = special_chars[i].local; *(++cur_pos) = '\0'; prev_off = off + special_chars[i].len; } } /* handle last chunk * NB. 0 length has a special meaning to utf8_to_enc */ if (prev_off < len) { err = utf8_to_enc(string + prev_off, enc, len - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); free(temp); } return NSERROR_OK; }
ULONG ami_unicode_text(struct RastPort *rp,const char *string,ULONG length,const plot_font_style_t *fstyle,ULONG dx, ULONG dy) { uint16 *utf16 = NULL, *outf16 = NULL; uint16 utf16charsc = 0, utf16nextsc = 0; uint16 utf16next = 0; int utf16charlen; struct OutlineFont *ofont, *ufont = NULL; ULONG i,gx,gy; UWORD posn; uint32 x=0; uint8 co = 0; int32 tempx = 0; ULONG emwidth = (ULONG)NSA_FONT_EMWIDTH(fstyle->size); if(!string || string[0]=='\0') return 0; if(!length) return 0; if(utf8_to_enc(string,"UTF-16",length,(char **)&utf16) != UTF8_CONVERT_OK) return 0; outf16 = utf16; if(!(ofont = ami_open_outline_font(fstyle, FALSE))) return 0; if(rp) SetRPAttrs(rp,RPTAG_APenColor,p96EncodeColor(RGBFB_A8B8G8R8,fstyle->foreground),TAG_DONE); while(*utf16 != 0) { if (*utf16 < 0xD800 || 0xDFFF < *utf16) utf16charlen = 1; else utf16charlen = 2; utf16next = utf16[utf16charlen]; if(fstyle->flags & FONTF_SMALLCAPS) { utf16charsc = ami_font_translate_smallcaps(*utf16); utf16nextsc = ami_font_translate_smallcaps(utf16next); tempx = ami_font_plot_glyph(ofont, rp, utf16charsc, utf16nextsc, dx + x, dy, emwidth); } else tempx = 0; if(tempx == 0) tempx = ami_font_plot_glyph(ofont, rp, *utf16, utf16next, dx + x, dy, emwidth); if(tempx == 0) { if(ufont == NULL) { ufont = ami_open_outline_font(fstyle, TRUE); } if(ufont) { tempx = ami_font_plot_glyph(ufont, rp, *utf16, utf16next, dx + x, dy, emwidth); } /* if(tempx == 0) { tempx = ami_font_plot_glyph(ofont, rp, 0xfffd, utf16next, dx + x, dy, emwidth); } */ } x += tempx; utf16 += utf16charlen; } free(outf16); return x; }
bool nsfont_split(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { struct TextExtent extent; ULONG co; char *ostr = (char *)string; struct TextFont *tfont; uint16 *utf16 = NULL,*outf16 = NULL; uint16 utf16next = 0; FIXED kern = 0; int utf16charlen = 0; struct OutlineFont *ofont, *ufont = NULL; struct GlyphMap *glyph; uint32 tx=0,i=0; size_t len; int utf8len, utf8clen = 0; int32 tempx = 0; ULONG emwidth = (ULONG)NSA_FONT_EMWIDTH(fstyle->size); len = utf8_bounded_length(string, length); if(utf8_to_enc((char *)string,"UTF-16",length,(char **)&utf16) != UTF8_CONVERT_OK) return false; outf16 = utf16; if(!(ofont = ami_open_outline_font(fstyle, FALSE))) return false; *char_offset = 0; *actual_x = 0; for(i=0;i<len;i++) { utf8len = utf8_char_byte_length(string+utf8clen); if (*utf16 < 0xD800 || 0xDFFF < *utf16) utf16charlen = 1; else utf16charlen = 2; utf16next = utf16[utf16charlen]; if(x < tx) { i = length+1; } else { if(string[utf8clen] == ' ') //*utf16 == 0x0020) { *actual_x = tx; *char_offset = utf8clen; } } tempx = ami_font_plot_glyph(ofont, NULL, *utf16, utf16next, 0, 0, emwidth); if(tempx == 0) { if(ufont == NULL) { ufont = ami_open_outline_font(fstyle, TRUE); } if(ufont) { tempx = ami_font_plot_glyph(ufont, NULL, *utf16, utf16next, 0, 0, emwidth); } /* if(tempx == 0) { tempx = ami_font_plot_glyph(ofont, NULL, 0xfffd, utf16next, 0, 0, emwidth); } */ } tx += tempx; utf16 += utf16charlen; utf8clen += utf8len; } free(outf16); return true; }
bool nsfont_position_in_string(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x) { struct TextExtent extent; struct TextFont *tfont; uint16 *utf16 = NULL, *outf16 = NULL; uint16 utf16next = 0; FIXED kern = 0; struct OutlineFont *ofont, *ufont = NULL; struct GlyphMap *glyph; uint32 tx=0,i=0; size_t len, utf8len = 0; uint8 *utf8; uint32 co = 0; int utf16charlen; ULONG emwidth = (ULONG)NSA_FONT_EMWIDTH(fstyle->size); int32 tempx; len = utf8_bounded_length(string, length); if(utf8_to_enc(string,"UTF-16",length,(char **)&utf16) != UTF8_CONVERT_OK) return false; outf16 = utf16; if(!(ofont = ami_open_outline_font(fstyle, FALSE))) return false; *char_offset = length; for(i=0;i<len;i++) { if (*utf16 < 0xD800 || 0xDFFF < *utf16) utf16charlen = 1; else utf16charlen = 2; utf8len = utf8_char_byte_length(string); utf16next = utf16[utf16charlen]; tempx = ami_font_plot_glyph(ofont, NULL, *utf16, utf16next, 0, 0, emwidth); if(tempx == 0) { if(ufont == NULL) { ufont = ami_open_outline_font(fstyle, TRUE); } if(ufont) { tempx = ami_font_plot_glyph(ufont, NULL, *utf16, utf16next, 0, 0, emwidth); } /* if(tempx == 0) { tempx = ami_font_plot_glyph(ofont, NULL, 0xfffd, utf16next, 0, 0, emwidth); } */ } if(x < (tx + tempx)) { *actual_x = tx; i = len+1; } else { co += utf8len; } tx += tempx; string += utf8len; utf16 += utf16charlen; } if(co >= (length)) { *actual_x = tx; co = length; } *char_offset = co; free(outf16); return true; }