void TextLayout::draw (Graphics& g, const Rectangle<float>& area) const { const Point<float> origin (justification.appliedToRectangle (Rectangle<float> (width, getHeight()), area).getPosition()); LowLevelGraphicsContext& context = g.getInternalContext(); for (int i = 0; i < getNumLines(); ++i) { const Line& line = getLine (i); const Point<float> lineOrigin (origin + line.lineOrigin); for (int j = 0; j < line.runs.size(); ++j) { const Run& run = *line.runs.getUnchecked (j); context.setFont (run.font); context.setFill (run.colour); for (int k = 0; k < run.glyphs.size(); ++k) { const Glyph& glyph = run.glyphs.getReference (k); context.drawGlyph (glyph.glyphCode, AffineTransform::translation (lineOrigin.x + glyph.anchor.x, lineOrigin.y + glyph.anchor.y)); } } } }
void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth, float maxHeight) { const float minimumWidth = maxWidth / 2.0f; float bestWidth = maxWidth; float bestLineProportion = 0.0f; while (maxWidth > minimumWidth) { createLayout (text, maxWidth, maxHeight); if (getNumLines() < 2) return; const float line1 = lines.getUnchecked (lines.size() - 1)->getLineBoundsX().getLength(); const float line2 = lines.getUnchecked (lines.size() - 2)->getLineBoundsX().getLength(); const float shortestLine = jmin (line1, line2); const float prop = (shortestLine > 0) ? jmax (line1, line2) / shortestLine : 1.0f; if (prop > 0.9f) return; if (prop > bestLineProportion) { bestLineProportion = prop; bestWidth = maxWidth; } maxWidth -= 10.0f; } if (bestWidth != maxWidth) createLayout (text, bestWidth, maxHeight); }
//-------------------------------------------------------------- string ofxMuiTextBlock::getDisplayTextLine(int lineNumber) const { if(lineNumber > getNumLines() - 1) { ofLogError("ofxMuiTextBlock::getDisplayText() requested a display text line that doesn't exist."); } return displayLines[lineNumber]; }
Vector2I GUIInputCaret::getCaretPosition(const Vector2I& offset) const { if(mNumChars > 0 && isDescValid()) { UINT32 curPos = 0; UINT32 numLines = getNumLines(); for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& lineDesc = getLineDesc(i); if(mCaretPos == curPos) { // Caret is on line start return Vector2I(offset.x, lineDesc.getLineYStart() + getTextOffset().y); } curPos += lineDesc.getEndChar(false) - lineDesc.getStartChar() + 1; // + 1 for special line start position } UINT32 charIdx = getCharIdxAtCaretPos(); if(charIdx > 0) charIdx -= 1; charIdx = std::min((UINT32)(mNumChars - 1), charIdx); Rect2I charRect = getCharRect(charIdx); UINT32 lineIdx = getLineForChar(charIdx); UINT32 yOffset = getLineDesc(lineIdx).getLineYStart() + getTextOffset().y; return Vector2I(charRect.x + charRect.width, yOffset); } return offset; }
UINT32 GUIInputTool::getCharIdxAtInputIdx(UINT32 inputIdx) const { if(mNumChars == 0) return 0; UINT32 numLines = getNumLines(); UINT32 curPos = 0; UINT32 curCharIdx = 0; for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& lineDesc = getLineDesc(i); if(curPos == inputIdx) return lineDesc.getStartChar(); curPos++; // Move past line start position UINT32 numChars = lineDesc.getEndChar() - lineDesc.getStartChar(); UINT32 numCaretPositions = lineDesc.getEndChar(false) - lineDesc.getStartChar(); if(inputIdx >= (curPos + numCaretPositions)) { curCharIdx += numChars; curPos += numCaretPositions; continue; } UINT32 diff = inputIdx - curPos; curCharIdx += diff + 1; // Character after the caret return curCharIdx; } return 0; }
/*--2--freeGrade */ void freeGrade(Rio **grade) { int i; for (i = getNumLines()-1; i >= 0; i--) free(grade[i]); free(grade); }
const TextObjectLineInfo& TextObject::findLineInfoForIndex(int index) const { const TextObjectLineInfo* line_info = getLineInfo(0); for (int line = 1; line < getNumLines(); ++line) { const TextObjectLineInfo* next_line_info = getLineInfo(line); if (index < next_line_info->start_index) break; line_info = next_line_info; } return *line_info; }
int TextObject::findLineForIndex(int index) const { int line_num = 0; for (int line = 1; line < getNumLines(); ++line) { const TextObjectLineInfo* line_info = getLineInfo(line); if (index < line_info->start_index) break; line_num = line; } return line_num; }
void GUIInputCaret::moveCaretToPos(const Vector2I& pos) { INT32 charIdx = getCharIdxAtPos(pos); if(charIdx != -1) { Rect2I charRect = getCharRect(charIdx); float xCenter = charRect.x + charRect.width * 0.5f; if(pos.x <= xCenter) moveCaretToChar(charIdx, CARET_BEFORE); else moveCaretToChar(charIdx, CARET_AFTER); } else { UINT32 numLines = getNumLines(); if(numLines == 0) { mCaretPos = 0; return; } UINT32 curPos = 0; for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& line = getLineDesc(i); INT32 lineStart = line.getLineYStart() + getTextOffset().y; if(pos.y >= lineStart && pos.y < (lineStart + (INT32)line.getLineHeight())) { mCaretPos = curPos; return; } UINT32 numChars = line.getEndChar(false) - line.getStartChar() + 1; // +1 For extra line start position curPos += numChars; } { const GUIInputLineDesc& firstLine = getLineDesc(0); INT32 lineStart = firstLine.getLineYStart() + getTextOffset().y; if(pos.y < lineStart) // Before first line mCaretPos = 0; else // After last line mCaretPos = curPos - 1; } } }
void InventoryRenderer::showInventory() { if (!_inv) error("InventoryRenderer not bound to inventory"); uint16 lines = getNumLines(); Common::Point p; _vm->_input->getCursorPos(p); _pos.x = CLIP((int)(p.x - (_props->_width / 2)), 0, (int)(_vm->_screenWidth - _props->_width)); _pos.y = CLIP((int)(p.y - 2 - (lines * _props->_itemHeight)), 0, (int)(_vm->_screenHeight - lines * _props->_itemHeight)); refresh(); }
UINT32 GUIInputCaret::getMaxCaretPos() const { if(mNumChars == 0) return 0; UINT32 numLines = getNumLines(); UINT32 maxPos = 0; for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& lineDesc = getLineDesc(i); UINT32 numChars = lineDesc.getEndChar(false) - lineDesc.getStartChar() + 1; // + 1 for special line start position maxPos += numChars; } return maxPos - 1; }
CExtent TextStruct::getTextBox(double spaceRatio, double penWidth) const { const double characterSpacing = .1; const double textLeading = 1.25; double boxWidth = getMaxLineLength(spaceRatio,penWidth); int numLines = getNumLines(); double boxHeight = m_height + ((numLines - 1) * textLeading * m_height); CPoint2d upperLeft(0.,0.); switch (getVerticalPosition()) { case verticalPositionBaseline: upperLeft.y = m_height; break; case verticalPositionCenter: upperLeft.y = boxHeight/2.; break; case verticalPositionBottom: upperLeft.y = boxHeight; break; case verticalPositionTop: upperLeft.y = 0.; break; } switch (getHorizontalPosition()) { case horizontalPositionLeft: upperLeft.x = 0.; break; case horizontalPositionCenter: upperLeft.x = -boxWidth/2.; break; case horizontalPositionRight: upperLeft.x = -boxWidth; break; } CPoint2d lowerRight = upperLeft + CPoint2d(boxWidth,-boxHeight); if (m_oblique != 0) { double offset = m_height * cos(degreesToRadians(m_oblique)); if (offset < 0.) upperLeft.x -= offset; else lowerRight.x += offset; } CExtent textBox; textBox.update(upperLeft); textBox.update(lowerRight); return textBox; }
bool GUIInputTool::isNewline(UINT32 inputIdx) const { if(mNumChars == 0) return true; UINT32 numLines = getNumLines(); UINT32 curPos = 0; for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& lineDesc = getLineDesc(i); if(curPos == inputIdx) return true; UINT32 numChars = lineDesc.getEndChar(false) - lineDesc.getStartChar(); curPos += numChars; } return false; }
/*--3--printGrade */ void printGrade(Rio **grade, int primeiraLinha, float tempoDecorrido) { int i, j; i = primeiraLinha; printf("\033[2J\033[;H"); if (getReportData()) printInfoTopo(tempoDecorrido); do { i--; if (i < 0) i = getNumLines()-1; for (j = 0; j < getNumColumns(); j++) printf ("%c", grade[i][j].terreno); if (getReportData()) printInfoLinha(grade[i]); printf("\n"); } while ( i != primeiraLinha ); printf ("\n\n"); }
/** function to get the corresponding line according to section and key */ long FileIO::FileIni::getline(char * cSection, char * cKey, std::string * strline, int * iIndexLine) { bool bFoundSection = false; bool bFoundKey = false; char cTempSection[STR_LONG]; memset(cTempSection, 0x00, STR_LONG); sprintf(cTempSection,"[%s]\n",cSection); std::string strSection = cTempSection; std::string strKey = cKey; int iNumberLines = getNumLines(); for(int i = 0; i < iNumberLines; i++) { std::string line = getItem(i); if(line.compare(strSection) == 0) { // section found bFoundSection = true; } size_t npos = line.find(strKey); if(npos == 0) { bFoundKey = true; } // found key and section if(bFoundKey && bFoundSection) { *strline = line; *iIndexLine = 0; return FILE_SUCCESS; } // reinit for loop: for a better detection, reinit bFoundSection if another section detected bFoundKey = false; } return FILE_KEY_NOT_FOUND; }
// FIXME actually this is two functions, selected by parameter find_line_only; make two functions or return TextObjectLineInfo reference int TextObject::calcTextPositionAt(QPointF point, bool find_line_only) const { float click_tolerance = Settings::getInstance().getMapEditorClickTolerancePx(); for (int line = 0; line < getNumLines(); ++line) { const TextObjectLineInfo* line_info = getLineInfo(line); if (line_info->line_y - line_info->ascent > point.y()) return -1; // NOTE: Only true as long as every line has a bigger or equal y value than the line before if (point.x() < line_info->line_x - click_tolerance) continue; if (point.y() > line_info->line_y + line_info->descent) continue; if (point.x() > line_info->line_x + line_info->width + click_tolerance) continue; // Position in the line rect. if (find_line_only) return line; else return line_info->getIndex(point.x()); } return -1; }
int main() { FILE *tmpFile; FILE *inputFile; int lines; char spacer[readsize]; inputFile = fopen("unformattedBasic.txt","r"); tmpFile = fopen("tmp.txt", "w"); lines = getNumLines(inputFile); getSpacer(inputFile, spacer); removeLeadingSpace(inputFile, tmpFile); //move tmpfile to input //clear tmpfile fixSpacing(inputFile, spacer); //move tmpfile to inputfile fclose(inputFile); return 0; }
void GUIInputCaret::moveCaretToChar(UINT32 charIdx, CaretPos caretPos) { if(charIdx >= mNumChars) { mCaretPos = 0; return; } UINT32 numLines = getNumLines(); UINT32 curPos = 0; UINT32 curCharIdx = 0; for(UINT32 i = 0; i < numLines; i++) { const GUIInputLineDesc& lineDesc = getLineDesc(i); curPos++; // Move past line start position UINT32 numChars = lineDesc.getEndChar() - lineDesc.getStartChar(); UINT32 numCaretPositions = lineDesc.getEndChar(false) - lineDesc.getStartChar(); if(charIdx >= (curCharIdx + numChars)) { curCharIdx += numChars; curPos += numCaretPositions; continue; } UINT32 diff = charIdx - curCharIdx; if(caretPos == CARET_BEFORE) curPos += diff - 1; else curPos += diff; break; } mCaretPos = curPos; }
void DmxPrintOutput::appendPageBreak () { char * buf; char *contents = "\n"; int nlines, missing; nlines = getNumLines(); missing = ((nlines % _lines_per_page) > 0) ? (_lines_per_page - (nlines % _lines_per_page)) : 0; if (! missing) return; #ifdef PRINT_TO_VIDEO for (int i=0; i<missing; i++) { char buffer[128]; sprintf(buffer, "Page Break Line: %d\n", i); appendContents((XtPointer) this, buffer); } fprintf( stdout, "Total Lines: %d; Lines Per Page: %d; Missing Lines: %d\n", nlines, _lines_per_page, missing); #else buf = (char *) malloc((missing * 2) + 1); for (int i=0; i<missing; i++) strcat(buf, contents); appendContents(this, contents); free(buf); #endif }
void GlyphLayout::draw (const Graphics& g) const { LowLevelGraphicsContext* const context = g.getInternalContext(); for (int i = 0; i < getNumLines(); ++i) { Line& line = getLine (i); for (int j = 0; j < line.getNumRuns(); ++j) { const Run& run = line.getRun (j); context->setFont (run.getFont()); context->setFill (run.getColour()); for (int k = 0; k < run.getNumGlyphs(); ++k) { const Glyph& glyph = run.getGlyph (k); context->drawGlyph (glyph.glyphCode, AffineTransform::translation ((float) glyph.anchor.x, (float) glyph.anchor.y)); } } } }
void GUIInputCaret::moveCaretDown() { UINT32 charIdx = getCharIdxAtCaretPos(); if(charIdx > 0) charIdx -= 1; UINT32 lineIdx = getLineForChar(charIdx); const GUIInputLineDesc& desc = getLineDesc(lineIdx); // If char is a newline, I want that to count as being on the next line because that's // how user sees it if(desc.isNewline(charIdx)) lineIdx++; if(lineIdx == (getNumLines() - 1)) { moveCaretToEnd(); return; } Vector2I caretCoords = getCaretPosition(mElement->_getTextInputOffset()); caretCoords.y += getCaretHeight(); moveCaretToPos(caretCoords); }
int initTitle(){ char fbuf[255]; FILE* fp; sprintf(fbuf,"%s/titles.txt", dynPath.dir_usb_loader); fp = fopen(fbuf, "r"); //fp = fopen(USBLOADER_PATH "/titles.txt", "r"); if(fp == NULL) return -1; int numLines = getNumLines(fp); //rewind(fp); if(numLines <= 0){ fclose(fp); return -2; } fclose(fp); return numLines; }
void TextObject::prepareLineInfos() const { const TextSymbol* text_symbol = reinterpret_cast<const TextSymbol*>(symbol); double scaling = text_symbol->calculateInternalScaling(); QFontMetricsF metrics = text_symbol->getFontMetrics(); double line_spacing = text_symbol->getLineSpacing() * metrics.lineSpacing(); double paragraph_spacing = scaling * text_symbol->getParagraphSpacing() + (text_symbol->hasLineBelow() ? (scaling * (text_symbol->getLineBelowDistance() + text_symbol->getLineBelowWidth())) : 0); double ascent = metrics.ascent(); bool word_wrap = ! hasSingleAnchor(); double box_width = word_wrap ? (scaling * getBoxWidth()) : 0.0; double box_height = word_wrap ? (scaling * getBoxHeight()) : 0.0; int text_end = text.length(); const QLatin1Char line_break('\n'); const QLatin1Char part_break('\t'); const QLatin1Char word_break(' '); line_infos.clear(); // Initialize offsets double line_x = 0.0; if (h_align == TextObject::AlignLeft) line_x -= 0.5 * box_width; else if (h_align == TextObject::AlignRight) line_x += 0.5 * box_width; double line_y = 0.0; if (v_align == TextObject::AlignTop || v_align == TextObject::AlignBaseline) line_y += -0.5 * box_height; if (v_align != TextObject::AlignBaseline) line_y += ascent; // Determine lines and parts //double next_line_x_offset = 0; // to keep indentation after word wrap in a line with tabs int num_paragraphs = 0; int line_num = 0; int line_start = 0; while (line_start <= text_end) { // Initialize input line double line_width = 0.0; int line_end = text.indexOf(line_break, line_start); if (line_end == -1) line_end = text_end; bool paragraph_end = true; std::vector<TextObjectPartInfo> part_infos; int part_start = line_start; double part_x = line_x; while (part_start <= line_end) { // Initialize part (sequence of letters terminated by tab or line break) int part_end = text.indexOf(part_break, part_start); if (part_end == -1) part_end = line_end; else if (part_end > line_end) part_end = line_end; if (part_start > 0 && text[part_start - 1] == part_break) part_x = line_x + text_symbol->getNextTab(part_x - line_x); QString part = text.mid(part_start, part_end - part_start); double part_width = metrics.boundingRect(part).width(); if (word_wrap) { // shrink overflowing part to maximum possible size while (part_x + part_width - line_x > box_width) { // find latest possible break int new_part_end = text.lastIndexOf(word_break, part_end - 1); if (new_part_end <= part_start) { // part won't fit if (part_start > line_start) { // don't put another part on this line part_end = part_start - 1; paragraph_end = false; } break; } paragraph_end = false; // Shrink the part and the line part_end = new_part_end; part = text.mid(part_start, part_end - part_start); part_width = metrics.width(part); line_end = part_end; } } if (part_end < part_start) break; // Add the current part part_infos.push_back( { part, part_start, part_end, part_x, metrics.width(part), metrics } ); // Advance to next part position part_start = part_end + 1; part_x += part_width; } TextObjectPartInfo& last_part_info = part_infos.back(); line_end = last_part_info.end_index; line_width = last_part_info.part_x + last_part_info.width - line_x; // Jump over whitespace after the end of the line and check if it contains a newline character to determine if it is a paragraph end int next_line_start = line_end + 1; /*while (next_line_start < text.size() && (text[next_line_start] == line_break || text[next_line_start] == part_break || text[next_line_start] == word_break)) { if (text[next_line_start - 1] == line_break) { paragraph_end = true; break; } ++next_line_start; }*/ line_infos.push_back( { line_start, line_end, paragraph_end, line_x, line_y, line_width, metrics.ascent(), metrics.descent(), part_infos } ); // Advance to next line line_y += line_spacing; if (paragraph_end) { line_y += paragraph_spacing; num_paragraphs++; } line_num++; line_start = next_line_start; } // Update the line and part offset for every other alignment than top-left or baseline-left double delta_y = 0.0; if (v_align == TextObject::AlignBottom || v_align == TextObject::AlignVCenter) { int num_lines = getNumLines(); double height = ascent + (num_lines - 1) * line_spacing + (num_paragraphs - 1) * paragraph_spacing; if (v_align == TextObject::AlignVCenter) delta_y = -0.5 * height; else if (v_align == TextObject::AlignBottom) delta_y = -height + 0.5 * box_height; } if (delta_y != 0.0 || h_align != TextObject::AlignLeft) { int num_lines = getNumLines(); for (int i = 0; i < num_lines; i++) { TextObjectLineInfo* line_info = &line_infos[i]; double delta_x = 0.0; if (h_align == TextObject::AlignHCenter) delta_x = -0.5 * line_info->width; else if (h_align == TextObject::AlignRight) delta_x -= line_info->width; line_info->line_x += delta_x; line_info->line_y += delta_y; int num_parts = line_info->part_infos.size(); for (int j = 0; j < num_parts; j++) { line_info->part_infos.at(j).part_x += delta_x; } } } }
int main(int argc, char *argv[]) { //initPersonList(database); int i; for(i = 0; i < MAX; i++) // initialize the shared buffer to null sample[i] = NULL; char *dbFile; char *orderFile; char *categoryFile; dbFile = argv[1]; orderFile = argv[2]; categoryFile = argv[3]; FILE *catFile = fopen(categoryFile,"r"); if(catFile == NULL) printf("Error opening the file\n"); int catNumber; catNumber = getNumLines(catFile); printf("catNumber is: %d\n",catNumber); int maxCatSize; maxCatSize = getMaxLineCount(catFile); // printf("maxCatSize: %d\n",maxCatSize); char *categoryList[catNumber]; for(i = 0; i < catNumber; i++) { categoryList[i] = (char *)malloc(catNumber*sizeof(char)); fgets(categoryList[i],maxCatSize,catFile); printf("Temp is: %s\n",categoryList[i]); } strcat(categoryList[catNumber-1],"\n"); printf("categoryList[catNumber-1]: %s\n",categoryList[catNumber-1]); fclose(catFile); /* NEED TO FIGURE OUT WHY THE CREDIT ISN'T GETTING RETURNED!!!!!*/ char *name; char *IDTemp; char *creditTemp; char *address; char *state; char *zip; double credit; int ID; int peopleCount; int maxLineSize; FILE *db = fopen(dbFile,"r"); // peopleCount = getNumLines(db); char d; while(d != EOF) { d = fgetc(db); if(d == '\n') peopleCount++; } rewind(db); d = 'a'; FILE *myOrders = fopen(orderFile,"r"); while(d != EOF) { d = fgetc(myOrders); if(d == '\n') ordersLeft++; } rewind(db); maxLineSize = getMaxLineCount(db); char line[maxLineSize]; database = (Person *)realloc(database,peopleCount*sizeof(Person)); int x; for(x = 0; x < peopleCount; x++) { fgets(line,maxLineSize,db); PersonPtr newPerson = (PersonPtr)malloc(sizeof(Person)); name = strdup(strtok(line,"|")); IDTemp = strdup(strtok(NULL,"|")); creditTemp = strdup(strtok(NULL,"|")); address = strdup(strtok(NULL,"|")); state = strdup(strtok(NULL,"|")); zip = strdup(strtok(NULL,"|")); credit = atof(creditTemp); ID = atoi(IDTemp); initPerson(newPerson,name,ID,credit,address,state,zip); database[x] = newPerson; // insertPerson(database,newPerson); } for(x = 0; x < peopleCount; x++) { //printPerson(database[x]); printf("\n"); } printf("%s\n",categoryList[2]); pthread_t thread; // pthread_t consumers[catNumber]; pthread_t *consumers = malloc(catNumber*sizeof(pthread_t)); struct package args; struct package *argPtr = &args; argPtr->consumers = consumers; argPtr->orderFile = orderFile; pthread_create(&thread,0,producer,(void *)argPtr); pthread_create(&consumers[0],0,consumer,categoryList[0]); pthread_create(&consumers[1],0,consumer,categoryList[1]); pthread_create(&consumers[2],0,consumer,categoryList[2]); printf("About to join the producer...\n"); pthread_join(thread,NULL); printf("We're going to join the two threads now\n"); // pthread_join(thread,NULL); pthread_cond_signal(&exitVar); // pthread_cond_signal(&dataAvailable); // pthread_cond_signal(&dataAvailable); /* pthread_join(consumers[0],NULL); pthread_join(consumers[1],NULL); pthread_join(consumers[2],NULL); */ printf("And we're back!\n"); sleep(10); pthread_exit(0); return 0; }
void SimpleTypeLayout::getGlyphLayout (const AttributedString& text, GlyphLayout& glyphLayout) { clear(); int stringLength = text.getText().length(); int numCharacterAttributes = text.getCharAttributesSize(); int rangeStart = 0; // Character attributes are applied as a series of ranges. These ranges may overlap or there may // be multiple attributes for the same range. We need to come up with a single set of unique and // non overlapping ranges. // The approach below iterates through every character, looks through all the attributes and their // ranges and stores the last font or color that was applied. It think constructs a set of unique // and non overlapping ranges by comparing each character's attributes to the previous characters // attributes. // A more efficient approach may be to split and combine the individual ranges to construct the // set of unique and non overlapping ranges. This more efficient approach, if possible, would only // need to iterate through all the attributes once. This would be much faster than the current // approach which loops through all the attributes for every character. Font defaultFont; Colour defaultColour (Colours::black); Array<RunAttribute> runAttributes; Array<CharAttribute> charAttributes; charAttributes.ensureStorageAllocated (stringLength); // Iterate through every character in the string for (int i = 0; i < stringLength; ++i) { CharAttribute attribute; attribute.font = &defaultFont; attribute.colour = &defaultColour; // Iterate through every character attribute for (int j = 0; j < numCharacterAttributes; ++j) { Attr* attr = text.getCharAttribute (j); // Check if the current character falls within the range of a font attribute if (attr->attribute == Attr::font && (i >= attr->range.getStart()) && (i < attr->range.getEnd())) { AttrFont* attrFont = static_cast<AttrFont*>(attr); attribute.font = &(attrFont->font); } // Check if the current character falls within the range of a foreground colour attribute if (attr->attribute == Attr::foregroundColour && (i >= attr->range.getStart()) && (i < attr->range.getEnd())) { AttrColour* attrColour = static_cast<AttrColour*>(attr); attribute.colour = &(attrColour->colour); } } charAttributes.add(attribute); // Skip the first character since we are comparing to previous characters if (i == 0) continue; if ((charAttributes[i-1].font != charAttributes[i].font) || (charAttributes[i-1].colour != charAttributes[i].colour) || (*(charAttributes[i-1].font) != *(charAttributes[i].font)) || (*(charAttributes[i-1].colour) != *(charAttributes[i].colour)) || (i + 1 == stringLength)) { // The current character has a new font or new color or there is no next character RunAttribute attribute; attribute.range.setStart (rangeStart); attribute.range.setEnd (i); if (i + 1 == stringLength) attribute.range.setEnd (i+1); attribute.font = charAttributes[i-1].font; attribute.colour = charAttributes[i-1].colour; runAttributes.add (attribute); rangeStart = i; } } charAttributes.clear(); for (int i = 0; i < runAttributes.size(); ++i) { appendText (text, runAttributes[i].range, *(runAttributes[i].font), *(runAttributes[i].colour)); } runAttributes.clear(); // Run layout to break strings into words and create lines from words layout ((int) glyphLayout.getWidth()); // Use tokens to create Glyph Structures glyphLayout.setNumLines (getNumLines()); // Set Starting Positions to 0 int charPosition = 0; int lineStartPosition = 0; int runStartPosition = 0; // Create first GlyphLine and GlyphRun GlyphLine* glyphLine = new GlyphLine(); GlyphRun* glyphRun = new GlyphRun(); for (int i = 0; i < tokens.size(); ++i) { const Token* const t = tokens.getUnchecked (i); // See TextLayout::draw const float xOffset = (float) t->x; const float yOffset = (float) t->y; // See GlyphArrangement::addCurtailedLineOfText Array <int> newGlyphs; Array <float> xOffsets; t->font.getGlyphPositions (t->text.trimEnd(), newGlyphs, xOffsets); // Resize glyph run array glyphRun->setNumGlyphs (glyphRun->getNumGlyphs() + newGlyphs.size()); // Add each glyph in the token to the current GlyphRun for (int j = 0; j < newGlyphs.size(); ++j) { const float thisX = xOffsets.getUnchecked (j); // Check if this is the first character in the line if (charPosition == lineStartPosition) { // Save line offset data Point<float> origin (xOffset, yOffset + t->font.getAscent()); glyphLine->setLineOrigin (origin); } float xPos = glyphLayout.getX() + glyphLine->getLineOrigin().getX() + xOffset + thisX; float yPos = glyphLayout.getY() + glyphLine->getLineOrigin().getY(); Glyph* glyph = new Glyph (newGlyphs.getUnchecked(j), xPos, yPos); glyphRun->addGlyph (glyph); charPosition++; } if (t->isWhitespace || t->isNewLine) ++charPosition; // We have reached the end of a token, we may need to create a new run or line if (i + 1 == tokens.size()) { // We have reached the last token // Close GlyphRun Range<int> runRange (runStartPosition, charPosition); glyphRun->setStringRange (runRange); glyphRun->setFont (t->font); glyphRun->setColour (t->colour); // Check if run descent is the largest in the line if (t->font.getDescent() > glyphLine->getDescent()) glyphLine->setDescent (t->font.getDescent()); glyphLine->addGlyphRun (glyphRun); // Close GlyphLine Range<int> lineRange (lineStartPosition, charPosition); glyphLine->setStringRange (lineRange); glyphLayout.addGlyphLine (glyphLine); } else { // We have not yet reached the last token const Token* const nextt = tokens.getUnchecked (i+1); if (t->font != nextt->font || t->colour != nextt->colour) { //The next token has a new font or new colour // Close GlyphRun Range<int> runRange (runStartPosition, charPosition); glyphRun->setStringRange (runRange); glyphRun->setFont (t->font); glyphRun->setColour (t->colour); // Check if run descent is the largest in the line if (t->font.getDescent() > glyphLine->getDescent()) glyphLine->setDescent (t->font.getDescent()); glyphLine->addGlyphRun (glyphRun); // Create the next GlyphRun runStartPosition = charPosition; glyphRun = new GlyphRun(); } if (t->line != nextt->line) { // The next token is in a new line // Close GlyphRun Range<int> runRange (runStartPosition, charPosition); glyphRun->setStringRange (runRange); glyphRun->setFont (t->font); glyphRun->setColour (t->colour); // Check if run descent is the largest in the line if (t->font.getDescent() > glyphLine->getDescent()) glyphLine->setDescent (t->font.getDescent()); glyphLine->addGlyphRun (glyphRun); // Close GlyphLine Range<int> lineRange (lineStartPosition, charPosition); glyphLine->setStringRange (lineRange); glyphLayout.addGlyphLine (glyphLine); // Create the next GlyphLine and GlyphRun runStartPosition = charPosition; lineStartPosition = charPosition; glyphLine = new GlyphLine(); glyphRun = new GlyphRun(); } } } // Apply Layout Text Alignment if (text.getTextAlignment() == AttributedString::right || text.getTextAlignment() == AttributedString::center) { int totalW = (int) glyphLayout.getWidth(); for (int i = 0; i < getNumLines(); ++i) { const int lineW = getLineWidth (i); int dx = 0; if (text.getTextAlignment() == AttributedString::right) { dx = totalW - lineW; } else if (text.getTextAlignment() == AttributedString::center) { dx = (totalW - lineW) / 2; } GlyphLine& glyphLine = glyphLayout.getGlyphLine (i); Point<float> lineOrigin = glyphLine.getLineOrigin(); lineOrigin.setX (lineOrigin.getX() + dx); glyphLine.setLineOrigin (lineOrigin); } } }
void InventoryRenderer::getRect(Common::Rect& r) const { r.setWidth(_props->_width); r.setHeight(_props->_itemHeight * getNumLines()); r.moveTo(_pos); }