ImageFont::ImageFont(const std::string &image, const std::string &glyphs) : m_texel(0) { /* * replace these with shamirs texture loading Image *img = ImageLoader::load(image); m_texel = Textures::generateTexelOfImage(img); delete img; */ int i = 0; float x, y; for (std::string::const_iterator it = glyphs.begin(); it != glyphs.end(); ++it, ++i ) { x = (i%12)/12.8f; y = (i/12)/8.0f; Glyph glyph( x, y, x + 0.078125f, y, x, y + 0.125f, x + 0.078125f, y + 0.125f ); m_glyphs.insert(std::pair<char, Glyph>(*it, glyph)); } }
glyph Monster::get_glyph() { if (type) { return type->sym; } return glyph(); }
glyph Worldmap_tile::top_glyph() { if (!terrain) { return glyph(); } return terrain->sym; }
void PrintableWindow::default_geometry() { WindowRep& w = *Window::rep(); const Display& d = *w.display_; w.glyph_->request(w.shape_); Coord width = w.shape_.requirement(Dimension_X).natural(); Coord height = w.shape_.requirement(Dimension_Y).natural(); ((OcGlyph*)glyph())->def_size(width, height); w.canvas_->size(width, height); if (xplace_) { w.placed_ = true; w.left_ = d.to_coord(xleft_); w.bottom_ = d.to_coord(d.pheight() - xtop_ - w.canvas_->pheight()); } w.xpos_ = d.to_pixels(w.left_); w.ypos_ = d.pheight() - d.to_pixels(w.bottom_) - w.canvas_->pheight(); if (w.aligned_) { w.xpos_ -= d.to_pixels(w.xalign_ * width); w.ypos_ += d.to_pixels(w.yalign_ * height); } if (w.placed_) { Display& d = *w.display_; PixelCoord l = w.xpos_, b = w.ypos_; PixelCoord pw = d.to_pixels(width), ph = d.to_pixels(height); l = (l < d.pwidth() - pw) ? l : d.pwidth() - pw; b = (b < d.pheight() - ph) ? b : d.pheight() - ph; l = (l > 0) ? l : 0; b = (b > 0) ? b : 0; w.xpos_ = l; w.ypos_ = b; } }
glyph poor_smallcaps_font_rep::get_glyph (string s) { int i=0, n= N(s), nr; if (n == 0) return subfn[0]->get_glyph (s); string r= s; advance (s, i, r, nr); if (nr<0) return glyph (); return subfn[nr]->get_glyph (r); }
glyph smart_font_rep::get_glyph (string s) { int i=0, n= N(s), nr; if (n == 0) return fn[0]->get_glyph (s); string r= s; advance (s, i, r, nr); if (nr<0) return glyph (); return fn[nr]->get_glyph (r); }
Font::Font(const String& filename) : Image(filename, 16, 16) { int widthImage = 0; int heightImage = 0; int nComponents = 4; unsigned int nFrames = 16 * 16; uint16 widthFrame = GetWidth(); uint16 heightFrame = GetHeight(); uint16 nLine = -1; unsigned char* pixels = stbi_load( filename.ToCString(), &widthImage, &heightImage, &nComponents, nComponents); for(unsigned int n = 0; n < (unsigned int)nFrames; n++) { Glyph glyph(0, 0, widthFrame, heightFrame); uint16 row = n / 16; uint16 column = n % 16; for(unsigned int posY = (unsigned int) (row * heightFrame); posY < (unsigned int) ((row + 1) * heightFrame) ; posY++ ) { for(unsigned int posX = (unsigned int)( column * widthFrame ); posX < (unsigned int)( (column + 1) * widthFrame ); posX++) { unsigned char pixelR = pixels[(posY * widthImage + posX) * 4 + 0]; unsigned char pixelG = pixels[(posY * widthImage + posX) * 4 + 1]; unsigned char pixelB = pixels[(posY * widthImage + posX) * 4 + 2]; unsigned char* pixelA = &pixels[(posY * widthImage + posX) * 4 + 3]; if( Glyph::IsYellow( pixelR, pixelG, pixelB)) { glyph.SetInitialCoordinates(posX, posY); *pixelA = 0; } else if( Glyph::IsRed( pixelR, pixelG, pixelB)) { glyph.SetFinalCoordinates(posX, posY); *pixelA = 0; } else if( Glyph::IsBlack( pixelR, pixelG, pixelB)) { *pixelA = 0; } } } glyphs.Add(glyph); } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, widthImage, heightImage, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); stbi_image_free(pixels); }
glyph poor_bbb_font_rep::get_glyph (string s) { glyph gl= base->get_glyph (s); if (is_nil (gl)) return gl; font_metric fnm; font_glyphs fng; int c= base->index_glyph (s, fnm, fng); if (c < 0) return glyph (); return make_bbb (gl, c, wpen, hpen, fat); }
static void show(void) { int i, j; for (i = 1; i <= N; i++) { for(j = 1; j <= N; j++) printf("%s", glyph(grid[i][j])); newline(); } printf("\n"); }
int LRun::setGlyphs(lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); this->glyphs.clear(); for(int i=1;i<=lua_objlen(L, 2); ++i) { lua_rawgeti(L, 2, i); TextLayout::Glyph glyph( LUCE::luce_toglyph(-1) ); this->glyphs.add( glyph ); } lua_remove(L, 2); return 0; }
////////////////////////////////////////////////////////////////////////// // calculate text width float Font::text_width(const char *text) const { float W = 0.0f; for (const char *p = text; *p; ++p) { const Font::Glyph &gm = glyph(*p); W += gm.gmfCellIncX; } return W; }
Size Font::size_of(const std::string s) const { Size size; for(const auto c : s) { const auto glyph_data = glyph(c); size = { size.width() + glyph_data.w(), std::max(size.height(), glyph_data.h()) }; } return size; }
////////////////////////////////////////////////////////////////////////// // calculate text height float Font::text_height(const char *text) const { float H = 0.0f; for (const char *p = text; *p; ++p) { const Glyph &gm = glyph(*p); if (H < gm.gmfBlackBoxY) H = gm.gmfBlackBoxY; } return H; }
////////////////////////////////////////////////////////////////////////// // calculate text height float Font::text_descent(const char *text) const { float D = 0.0f; for (const char *p = text; *p; ++p) { const Glyph &gm = glyph(*p); if (D < gm.gmfptGlyphOrigin.y - gm.gmfBlackBoxY) D = gm.gmfptGlyphOrigin.y - gm.gmfBlackBoxY; } return D; }
int main(void) { u8g_t u8g; u8g_Init(&u8g, &u8g_dev_sdl_1bit_h); u8g_FirstPage(&u8g); do { u8g_SetColorIndex(&u8g, 1); u8g_DrawPixel(&u8g,0,0); u8g_DrawPixel(&u8g,0,1); u8g_SetFont(&u8g, u8g_font_unifont); //u8g_SetFont(&u8g, u8g_font_10x20); //u8g_SetFont(&u8g, u8g_font_gdb17); u8g_SetFontRefHeightText(&u8g); //u8g_SetRefHeightAll(&u8g); //u8g_SetFontPosBaseline(&u8g); //u8g_SetFontPosCenter(&u8g); u8g_SetFontPosTop(&u8g); glyph(&u8g, 5,25, 'g'); u8g_SetFontPosCenter(&u8g); glyph(&u8g, 5+25,25, 'g'); u8g_SetFontPosBaseline(&u8g); glyph(&u8g, 5+2*25,25, 'g'); u8g_SetFontPosBottom(&u8g); glyph(&u8g, 5+3*25,25, 'g'); }while( u8g_NextPage(&u8g) ); while( u8g_sdl_get_key() < 0 ) ; return 0; }
////////////////////////////////////////////////////////////////////////// // calculate text height float Font::text_ascent(const char *text) const { float A = 0.0f; for (const char *p = text; *p; ++p) { const Glyph &gm = glyph(*p); if (A < gm.gmfptGlyphOrigin.y) A = gm.gmfptGlyphOrigin.y; } return A; }
int agg2RenderBitmapGlyphs(imageObj *img, double x, double y, labelStyleObj *style, char *text) { typedef mapserver::glyph_raster_bin<color_type> glyph_gen; int size = MS_NINT(style->size); if(size<0 || size>4) { msSetError(MS_RENDERERERR,"invalid bitmap font size", "agg2RenderBitmapGlyphs()"); return MS_FAILURE; } AGG2Renderer *r = AGG_RENDERER(img); glyph_gen glyph(0); mapserver::renderer_raster_htext_solid<renderer_base, glyph_gen> rt(r->m_renderer_base, glyph); glyph.font(rasterfonts[size]); int numlines=0; char **lines; /*masking out the out-of-range character codes*/ int len; int cc_start = rasterfonts[size][2]; int cc_end = cc_start + rasterfonts[size][3]; if(msCountChars(text,'\n')) { if((lines = msStringSplit((const char*)text, '\n', &(numlines))) == NULL) return(-1); } else { lines = &text; numlines = 1; } y -= glyph.base_line(); for(int n=0; n<numlines; n++) { len = strlen(lines[n]); for (int i = 0; i < len; i++) if (lines[n][i] < cc_start || lines[n][i] > cc_end) lines[n][i] = '.'; if(style->outlinewidth > 0) { rt.color(aggColor(style->outlinecolor)); for(int i=-1; i<=1; i++) { for(int j=-1; j<=1; j++) { if(i||j) { rt.render_text(x+i, y+j, lines[n], true); } } } } assert(style->color); rt.color(aggColor(style->color)); rt.render_text(x, y, lines[n], true); y += glyph.height(); } if(*lines != text) msFreeCharArray(lines, numlines); return MS_SUCCESS; return MS_SUCCESS; }
bool ParagraphLayout::_AppendGlyphInfo(uint32 charCode, float width, const CharacterStyle& style) { if (style.Width() >= 0.0f) { // Use the metrics provided by the CharacterStyle and override // the font provided metrics passed in "width" width = style.Width(); } width += style.GlyphSpacing(); GlyphInfo glyph(charCode, 0.0f, width, width, 0, style); return fGlyphInfos.Add(glyph); }
int agg2RenderBitmapGlyphs2(imageObj *img, textPathObj *tp, colorObj *c, colorObj *oc, int ow) { int size = tp->glyph_size; size = MS_MAX(0,size); size = MS_MIN(4,size); AGG2Renderer *r = AGG_RENDERER(img); glyph_gen glyph(0); mapserver::renderer_raster_htext_solid<renderer_base, glyph_gen> rt(r->m_renderer_base, glyph); glyph.font(rasterfonts[size]); unsigned int cc_start = rasterfonts[size][2]; unsigned int cc_end = cc_start + rasterfonts[size][3]; unsigned int glyph_idx; if(oc) { rt.color(aggColor(oc)); for(int n=0; n<tp->numglyphs; n++) { glyphObj *g = &tp->glyphs[n]; /* do some unicode mapping, for now we just replace unsupported characters with "." */ if(g->glyph->key.codepoint < cc_start || g->glyph->key.codepoint > cc_end) { glyph_idx = '.'; } else { glyph_idx = g->glyph->key.codepoint; } for(int i=-1; i<=1; i++) { for(int j=-1; j<=1; j++) { if(i||j) { rt.render_glyph(g->pnt.x+i , g->pnt.y+j, glyph_idx, true); } } } } } if(c) { rt.color(aggColor(c)); for(int n=0; n<tp->numglyphs; n++) { glyphObj *g = &tp->glyphs[n]; /* do some unicode mapping, for now we just replace unsupported characters with "." */ if(g->glyph->key.codepoint < cc_start || g->glyph->key.codepoint > cc_end) { glyph_idx = '.'; } else { glyph_idx = g->glyph->key.codepoint; } rt.render_glyph(g->pnt.x , g->pnt.y, glyph_idx, true); } } return MS_SUCCESS; }
void DataSet::addGlyphs() { if (!_context) M_throw() << "Cannot add glyphs before the Dataset is initialised"; std::shared_ptr<Glyphs> glyph(new Glyphs(_comboPointSet->get_active_text(), *this)); _children.push_back(glyph); _children.back()->init(_systemQueue); if (_iter) { Gtk::TreeModel::iterator child_iter = _view->_store->append(_iter->children()); _children.back()->addViewRows(*_view, child_iter); _view->_view->expand_to_path(_view->_store->get_path(child_iter)); } }
std::vector<Point> Game::path_selector(int startx, int starty) { std::vector<Point> ret; if (!player) { return ret; } if (startx == -1 || starty == -1) { startx = player->pos.x; starty = player->pos.y; } Tripoint target(startx, starty, player->pos.z); map->draw(w_map, &entities, player->pos); w_map->refresh(); while (true) { long ch = input(); if (ch == KEY_ESC || ch == 'q' || ch == 'Q') { std::vector<Point> empty; return empty; } else if (ch == '\n') { return ret; } else { Point p = input_direction(ch); if (p.x == 0 && p.y == 0) { return ret; // Return out path on hitting "pause" } else if (p.x != -2 && p.y != -2) { target += p; ret = map->line_of_sight(player->pos, target); map->draw(w_map, &entities, player->pos); for (int i = 0; i < ret.size(); i++) { map->draw_tile(w_map, &entities, ret[i].x, ret[i].y, player->pos.x, player->pos.y, true); // true==inverted } // TODO: No no no remove this w_map->putglyph(w_map->sizex() / 2 - player->pos.x + target.x, w_map->sizey() / 2 - player->pos.y + target.y, glyph('*', c_red, c_black)); w_map->refresh(); } } } }
void DataSet::addPointSetWorker(std::string name, std::vector<GLuint> data, int datatype) { _pointSets[name].init(data, 1); _pointSets[name].glyphType = datatype; _comboPointSet->get_model().clear(); for (const auto& pointset: _pointSets) _comboPointSet->insert(-1, pointset.first); _comboPointSet->set_active(0); std::shared_ptr<Glyphs> glyph(new Glyphs(name, *this)); _children.push_back(glyph); _children.back()->init(_systemQueue); if (_iter) { Gtk::TreeModel::iterator child_iter = _view->_store->append(_iter->children()); _children.back()->addViewRows(*_view, child_iter); _view->_view->expand_to_path(_view->_store->get_path(child_iter)); } }
XtGeometryResult WidgetWindow::xt_query_geometry( XtWidgetGeometry* intended, XtWidgetGeometry* preferred ) { WindowRep& wr = *((Window*)this)->rep(); Display& d = *wr.display_; Glyph* g = glyph(); if (!g) { *preferred = *intended; return XtGeometryYes; } Requisition req; // GlyphImpl::default_requisition(req); g->request(req); Coord w = req.requirement(Dimension_X).natural(); Coord h = req.requirement(Dimension_Y).natural(); // ### look into how the following works XtGeometryMask mode = CWWidth | CWHeight; preferred->request_mode = mode; preferred->width = XCoord(d.to_pixels(w)); preferred->height = XCoord(d.to_pixels(h)); if ((intended->request_mode & mode) == mode && intended->width == preferred->width && intended->height == preferred->height ) { return XtGeometryYes; } else if (preferred->width == widget_->core.width && preferred->height == widget_->core.height ) { return XtGeometryNo; } return XtGeometryAlmost; }
bool Resources::InitTextFont() { // For the text font, we load the bounding boxes only pugi::xml_document doc; // For now, we have only Times bounding boxes for ASCII chars // For any other char, we currently use 'o' bounding box std::string filename = Resources::GetPath() + "/text/Times.xml"; pugi::xml_parse_result result = doc.load_file(filename.c_str()); if (!result) { // File not found, default bounding boxes will be used LogMessage("Cannot load bounding boxes for text font '%s'", filename.c_str()); return false; } pugi::xml_node root = doc.first_child(); if (!root.attribute("units-per-em")) { LogWarning("No units-per-em attribute in bouding box file"); return false; } int unitsPerEm = atoi(root.attribute("units-per-em").value()); pugi::xml_node current; for (current = root.child("g"); current; current = current.next_sibling("g")) { if (current.attribute("c")) { wchar_t code = (wchar_t)strtol(current.attribute("c").value(), NULL, 16); // We create a glyph with only the units per em which is the only info we need for // the bounding boxes; path and codeStr will remain [unset] Glyph glyph(unitsPerEm); double x = 0.0, y = 0.0, width = 0.0, height = 0.0; // Not check for missing values... if (current.attribute("x")) x = atof(current.attribute("x").value()); if (current.attribute("y")) y = atof(current.attribute("y").value()); if (current.attribute("w")) width = atof(current.attribute("w").value()); if (current.attribute("h")) height = atof(current.attribute("h").value()); glyph.SetBoundingBox(x, y, width, height); m_textFont[code] = glyph; } } return true; }
int getBitmapGlyphMetrics(int size, unsigned int unicode, glyph_metrics *bounds) { size = MS_MAX(0,size); size = MS_MIN(4,size); unsigned int glyph_idx; /* do some unicode mapping, for now we just replace unsupported characters with "." */ unsigned int cc_start = rasterfonts[size][2]; unsigned int cc_end = cc_start + rasterfonts[size][3]; if(unicode < cc_start || unicode > cc_end) { glyph_idx = '.'; } else { glyph_idx = unicode; } glyph_gen glyph(0); glyph.font(rasterfonts[size]); bounds->minx = 0; bounds->miny = -glyph.base_line(); bounds->maxx = glyph.glyph_width(glyph_idx); bounds->maxy = glyph.height() + bounds->miny; bounds->advance = bounds->maxx; return MS_SUCCESS; }
// // Encodes position as FEN string. // func (p *Position) fen() (fen string) { // fancy = engine.fancy // engine.fancy = false; defer func() { engine.fancy = fancy }() // // // Board: start from A8->H8 going down to A1->H1. // empty = 0 // for row = A8H8; row >= A1H1; row-- { // for col = A1A8; col <= H1H8; col++ { // square = square(row, col) // piece = p.pieces[square] // // if piece != 0 { // if empty != 0 { // fen += fmt.Sprintf("%d", empty) // empty = 0 // } // fen += piece.String() // } else { // empty++ // } // // if col == 7 { // if empty != 0 { // fen += fmt.Sprintf("%d", empty) // empty = 0 // } // if row != 0 { // fen += "/" // } // } // } // } // // // Side to move. // if p.color == White { // fen += " w" // } else { // fen += " b" // } // // // Castle rights for both sides, if any. // if p.castles & 0x0F != 0 { // fen += " " // if p.castles & castleKingside[White] != 0 { // fen += "K" // } // if p.castles & castleQueenside[White] != 0 { // fen += "Q" // } // if p.castles & castleKingside[Black] != 0 { // fen += "k" // } // if p.castles & castleQueenside[Black] != 0 { // fen += "q" // } // } else { // fen += " -" // } // // // En-passant square, if any. // if p.enpassant != 0 { // row, col = coordinate(int(p.enpassant)) // fen += fmt.Sprintf(" %c%d", col + 'a', row + 1) // } else { // fen += " -" // } // // // TODO: Number of half-moves and number of full moves. // fen += " 0 1" // // return // } // // // Encodes position as DCF string (Donna Chess Format). // func (p *Position) dcf() string { // fancy = engine.fancy // engine.fancy = false; defer func() { engine.fancy = fancy }() // // encode = func (square int) string { // var buffer bytes.Buffer // // buffer.WriteByte(byte(col(square)) + 'a') // buffer.WriteByte(byte(row(square)) + '1') // // return buffer.String() // } // // var pieces [2][]string // // for color = uint8(White); color <= uint8(Black); color++ { // // Right to move and (TODO) move number. // if color == p.color && color == Black { // pieces[color] = append(pieces[color], "M") // } // // // King. // pieces[color] = append(pieces[color], "K" + encode(int(p.king[color]))) // // // Queens, Rooks, Bishops, and Knights. // outposts = p.outposts[queen(color)] // for outposts != 0 { // pieces[color] = append(pieces[color], "Q" + encode(outposts.pop())) // } // outposts = p.outposts[rook(color)] // for outposts != 0 { // pieces[color] = append(pieces[color], "R" + encode(outposts.pop())) // } // outposts = p.outposts[bishop(color)] // for outposts != 0 { // pieces[color] = append(pieces[color], "B" + encode(outposts.pop())) // } // outposts = p.outposts[knight(color)] // for outposts != 0 { // pieces[color] = append(pieces[color], "N" + encode(outposts.pop())) // } // // // Castle rights. // if p.castles & castleQueenside[color] == 0 || p.castles & castleKingside[color] == 0 { // if p.castles & castleQueenside[color] != 0 { // pieces[color] = append(pieces[color], "C" + encode(C1 + 56 * int(color))) // } // if p.castles & castleKingside[color] != 0 { // pieces[color] = append(pieces[color], "C" + encode(G1 + 56 * int(color))) // } // } // // // En-passant square if any. Note that this gets assigned to the // // current side to move. // if p.enpassant != 0 && color == p.color { // pieces[color] = append(pieces[color], "E" + encode(int(p.enpassant))) // } // // // Pawns. // outposts = p.outposts[pawn(color)] // for outposts != 0 { // pieces[color] = append(pieces[color], encode(outposts.pop())) // } // } // // return strings.Join(pieces[White], ",") + " : " + strings.Join(pieces[Black], ",") // } // char *position_string(Position *p, char *buffer) { strcpy(buffer, " a b c d e f g h"); if (!is_in_check(p, p->color)) { strcat(buffer, "\n"); } else { sprintf(buffer + strlen(buffer), " Check to %s\n", p->color ? "black" : "white"); } for (int row = 7; row >= 0; row--) { int last = strlen(buffer); buffer[last] = '1' + row; buffer[last + 1] = '\0'; for (int col = 0; col <= 7; col++) { strcat(buffer, " "); Piece piece = p->pieces[square(row, col)]; if (piece) { strcat(buffer, glyph(piece)); // Set } else { strcat(buffer, "\xE2\x8B\x85"); // Clear } } strcat(buffer, "\n"); } return buffer; }
Loops get_ttt_loops(int char_index=0) { SEG_Writer my_writer; // this Writer writes G-code my_writer.set_scale( 1e-4 ); std::string all_glyphs = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char c = all_glyphs.at(char_index); std::string glyph(&c,1); //all_glyphs.at(char_index); std::cout << " ttt glyph is " << glyph << "\n"; Ttt t( &my_writer, glyph, false , TTFONT ); // ( Writer*, text, unicode?, path-to-font ) Loops all_loops = my_writer.get_loops(); extents ext = my_writer.get_extents(); std::cout << " x-range : " << ext.minx << " - " << ext.maxx << "\n"; std::cout << " y-range : " << ext.miny << " - " << ext.maxy << "\n"; Loops mod_loops; // ttt returns loops with duplicate start/endpoints // to avoid duplicates, remove the first point from each loop BOOST_FOREACH(Loop l, all_loops) { l.erase(l.begin()); // remove first element of loop mod_loops.push_back(l); }
size graphics_context::multiline_text_extent(const string& aText, const font& aFont, dimension aMaxWidth, bool aUseCache) const { const auto& glyphText = aUseCache && !iGlyphTextCache->empty() ? *iGlyphTextCache : to_glyph_text(aText.begin(), aText.end(), aFont); if (aUseCache && iGlyphTextCache->empty()) *iGlyphTextCache = glyphText; typedef std::pair<glyph_text::const_iterator, glyph_text::const_iterator> line_t; typedef std::vector<line_t> lines_t; lines_t lines; std::array<glyph, 2> delimeters = { glyph(text_direction::Whitespace, '\r'), glyph(text_direction::Whitespace, '\n') }; neolib::tokens(glyphText.cbegin(), glyphText.cend(), delimeters.begin(), delimeters.end(), lines, 0, false); size result; for (lines_t::const_iterator i = lines.begin(); i != lines.end(); ++i) { if (aMaxWidth == 0) { size lineExtent = from_device_units(glyph_text::extents(aFont, i->first, i->second)); result.cx = std::max(result.cx, lineExtent.cx); result.cy += lineExtent.cy; } else { glyph_text::const_iterator next = i->first; glyph_text::const_iterator lineStart = next; glyph_text::const_iterator lineEnd = i->second; dimension maxWidth = to_device_units(size(aMaxWidth, 0)).cx; dimension lineWidth = 0; bool gotLine = false; while(next != i->second) { if (lineWidth + next->advance().cx > maxWidth) { std::pair<glyph_text::const_iterator, glyph_text::const_iterator> wordBreak = glyphText.word_break(lineStart, next); lineWidth -= glyph_text::extents(aFont, wordBreak.first, next).cx; lineEnd = wordBreak.first; next = wordBreak.second; if (lineEnd == next) { while(lineEnd != i->second && (lineEnd + 1)->source() == wordBreak.first->source()) ++lineEnd; next = lineEnd; } gotLine = true; } else { lineWidth += next->advance().cx; ++next; } if (gotLine || next == i->second) { result.cx = std::max(result.cx, from_device_units(size(lineWidth, 0)).cx); result.cy += from_device_units(glyph_text::extents(aFont, i->first, i->second)).cy; lineStart = next; lineEnd = i->second; lineWidth = 0; gotLine = false; } } } } if (result.cy == 0) result.cy = from_device_units(size(0, aFont.height())).cy; return result; }
void graphics_context::draw_multiline_text(const point& aPoint, const string& aText, const font& aFont, dimension aMaxWidth, const colour& aColour, alignment aAlignment, bool aUseCache) const { const auto& glyphText = aUseCache && !iGlyphTextCache->empty() ? *iGlyphTextCache : to_glyph_text(aText.begin(), aText.end(), aFont); if (aUseCache && iGlyphTextCache->empty()) *iGlyphTextCache = glyphText; typedef std::pair<glyph_text::const_iterator, glyph_text::const_iterator> line_t; typedef std::vector<line_t> lines_t; lines_t lines; std::array<glyph, 2> delimeters = { glyph(text_direction::Whitespace, '\r'), glyph(text_direction::Whitespace, '\n') }; neolib::tokens(glyphText.cbegin(), glyphText.cend(), delimeters.begin(), delimeters.end(), lines, 0, false); size textExtent = multiline_text_extent(aText, aFont, aMaxWidth, aUseCache); point pos = aPoint; for (lines_t::const_iterator i = lines.begin(); i != lines.end(); ++i) { const auto& line = (logical_coordinates()[1] > logical_coordinates()[3] ? *i : *(lines.rbegin() + (i - lines.begin()))); if (aMaxWidth == 0) { point linePos = pos; size lineExtent = from_device_units(glyph_text::extents(aFont, line.first, line.second)); if (glyph_text_direction(line.first, line.second) == text_direction::RTL) linePos.x += textExtent.cx - lineExtent.cx; draw_glyph_text(linePos, line.first, line.second, aFont, aColour); pos.y += lineExtent.cy; } else { glyph_text::const_iterator next = line.first; glyph_text::const_iterator lineStart = next; glyph_text::const_iterator lineEnd = line.second; dimension maxWidth = to_device_units(size(aMaxWidth, 0)).cx; dimension lineWidth = 0; while(next != line.second) { bool gotLine = false; if (lineWidth + next->advance().cx > maxWidth) { std::pair<glyph_text::const_iterator, glyph_text::const_iterator> wordBreak = glyphText.word_break(lineStart, next); lineWidth -= glyph_text::extents(aFont, wordBreak.first, next).cx; lineEnd = wordBreak.first; next = wordBreak.second; if (lineEnd == next) { while(lineEnd != line.second && (lineEnd + 1)->source() == wordBreak.first->source()) ++lineEnd; next = lineEnd; } gotLine = true; } else { lineWidth += next->advance().cx; ++next; } if (gotLine || next == line.second) { point linePos = pos; if (aAlignment == alignment::Left && glyph_text_direction(lineStart, next) == text_direction::RTL || aAlignment == alignment::Right && glyph_text_direction(lineStart, next) == text_direction::LTR) linePos.x += textExtent.cx - from_device_units(size(lineWidth, 0)).cx; else if (aAlignment == alignment::Centre) linePos.x += std::ceil((textExtent.cx - from_device_units(size(lineWidth, 0)).cx) / 2); draw_glyph_text(linePos, lineStart, lineEnd, aFont, aColour); pos.y += glyph_text::extents(aFont, lineStart, lineEnd).cy; lineStart = next; lineEnd = line.second; lineWidth = 0; } } if (line.first == line.second) pos.y += font().height(); } } }
virtual void on_draw() { struct font_type { const agg::int8u* font; const char* name; } fonts[] = { { agg::gse4x6, "gse4x6" }, { agg::gse4x8, "gse4x8" }, { agg::gse5x7, "gse5x7" }, { agg::gse5x9, "gse5x9" }, { agg::gse6x9, "gse6x9" }, { agg::gse6x12, "gse6x12" }, { agg::gse7x11, "gse7x11" }, { agg::gse7x11_bold, "gse7x11_bold" }, { agg::gse7x15, "gse7x15" }, { agg::gse7x15_bold, "gse7x15_bold" }, { agg::gse8x16, "gse8x16" }, { agg::gse8x16_bold, "gse8x16_bold" }, { agg::mcs11_prop, "mcs11_prop" }, { agg::mcs11_prop_condensed, "mcs11_prop_condensed" }, { agg::mcs12_prop, "mcs12_prop" }, { agg::mcs13_prop, "mcs13_prop" }, { agg::mcs5x10_mono, "mcs5x10_mono" }, { agg::mcs5x11_mono, "mcs5x11_mono" }, { agg::mcs6x10_mono, "mcs6x10_mono" }, { agg::mcs6x11_mono, "mcs6x11_mono" }, { agg::mcs7x12_mono_high, "mcs7x12_mono_high" }, { agg::mcs7x12_mono_low, "mcs7x12_mono_low" }, { agg::verdana12, "verdana12" }, { agg::verdana12_bold, "verdana12_bold" }, { agg::verdana13, "verdana13" }, { agg::verdana13_bold, "verdana13_bold" }, { agg::verdana14, "verdana14" }, { agg::verdana14_bold, "verdana14_bold" }, { agg::verdana16, "verdana16" }, { agg::verdana16_bold, "verdana16_bold" }, { agg::verdana17, "verdana17" }, { agg::verdana17_bold, "verdana17_bold" }, { agg::verdana18, "verdana18" }, { agg::verdana18_bold, "verdana18_bold" }, 0, 0 }; glyph_gen glyph(0); pixfmt pixf(rbuf_window()); ren_base rb(pixf); rb.clear(agg::rgba(1,1,1)); agg::renderer_raster_htext_solid<ren_base, glyph_gen> rt(rb, glyph); int i; double y = 5; rt.color(agg::rgba(0,0,0)); for(i = 0; fonts[i].font; i++) { char buf[100]; strcpy(buf, "A quick brown fox jumps over the lazy dog 0123456789: "); strcat(buf, fonts[i].name); // Testing "wide-char" unsigned wbuf[100]; unsigned* wp = wbuf; const char* p = buf; while(*p) *wp++ = *(unsigned char*)p++; *wp++ = 0; glyph.font(fonts[i].font); rt.render_text(5, y, wbuf, !flip_y()); y += glyph.height() + 1; } // Rendering raster text with a custom span generator, gradient typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_allocator<agg::rgba8> span_alloc_type; typedef agg::span_gradient<agg::rgba8, interpolator_type, gradient_sine_repeat_adaptor<agg::gradient_circle>, agg::gradient_linear_color<agg::rgba8> > span_gen_type; typedef agg::renderer_scanline_aa<ren_base, span_alloc_type, span_gen_type> ren_type; agg::trans_affine mtx; gradient_sine_repeat_adaptor<agg::gradient_circle> grad_func; grad_func.periods(5); agg::gradient_linear_color<agg::rgba8> color_func; color_func.colors(agg::rgba(1.0,0,0), agg::rgba(0,0.5,0)); interpolator_type inter(mtx); span_alloc_type sa; span_gen_type sg(inter, grad_func, color_func, 0, 150.0); ren_type ren(rb, sa, sg); agg::renderer_raster_htext<ren_type, glyph_gen> rt2(ren, glyph); rt2.render_text(5, 465, (unsigned char*)"RADIAL REPEATING GRADIENT: A quick brown fox jumps over the lazy dog", !flip_y()); }