//-------------------------------------------------------------- void ofxFileDialog::drawFilenames(int offset, int bottomOffset, bool highlight) { int x = 0; float center = (m_height-s_charHeight*offset)*0.5; int top = -center+(s_charHeight*2); int bottom = center-(s_charHeight*bottomOffset); int displayRange = m_visibleLines-offset; // center vertically ofPushMatrix(); ofTranslate(0, m_visibleLines*0.5*s_charHeight); // start drawing based on current file location in file list so selection remains centered float y = (m_currentFile/(float)m_filenames.size()) * -s_charHeight * (float)m_filenames.size() + s_charHeight; unsigned int count = 0; for(vector<u32string>::iterator i = m_filenames.begin(); i != m_filenames.end(); i++) { m_numLines = 0; bool isDir = m_directories.find(count) != m_directories.end(); // don't draw on top of path if(y < top) { y += s_charHeight; count++; continue; } // only show numbers in the display range if(((int)count > ((int)m_currentFile - (int)displayRange)) && ((int)count < ((int)m_currentFile + (int)displayRange))) { for(int c = 0; c < i->size(); ++c) { // current file background if(highlight && count == m_currentFile) { ofSetColor(m_settings->getCursorColor().r, m_settings->getCursorColor().g, m_settings->getCursorColor().b, m_settings->getCursorColor().a * m_settings->getAlpha()); ofRectMode rectMode = ofGetRectMode(); ofSetRectMode(OF_RECTMODE_CORNER); ofDrawRectangle(x, y-s_charHeight, characterWidth((*i)[c]), s_charHeight); ofSetRectMode(rectMode); } // file or dir name x = s_font->drawCharacter((*i)[c], x, y, s_textShadow); } x = 0; } y += s_charHeight; count++; // don't draw beyond bottom if(y > bottom) { break; } } ofPopMatrix(); }
unsigned SimpleShaper::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer) { bool hasExtraSpacing = (m_font->fontDescription().letterSpacing() || m_font->fontDescription().wordSpacing() || m_expansion) && !m_run.spacingDisabled(); const SimpleFontData* primaryFont = m_font->primaryFont(); const SimpleFontData* lastFontData = primaryFont; bool normalizeSpace = m_run.normalizeSpace(); CharacterData charData; while (textIterator.consume(charData.character, charData.clusterLength)) { charData.characterOffset = textIterator.currentCharacter(); GlyphData glyphData = glyphDataForCharacter(charData, normalizeSpace); // Some fonts do not have a glyph for zero-width-space, // in that case use the space character and override the width. float width; if (!glyphData.glyph && Character::treatAsZeroWidthSpaceInComplexScript(charData.character)) { charData.character = space; glyphData = glyphDataForCharacter(charData); width = 0; } else { width = characterWidth(charData.character, glyphData); } Glyph glyph = glyphData.glyph; const SimpleFontData* fontData = glyphData.fontData; ASSERT(fontData); if (m_fallbackFonts && lastFontData != fontData && width) { lastFontData = fontData; cacheFallbackFont(fontData, primaryFont); } if (hasExtraSpacing) width = adjustSpacing(width, charData, *fontData, glyphBuffer); if (m_bounds) updateGlyphBounds(glyphData, width, !charData.characterOffset); if (m_forTextEmphasis && !Character::canReceiveTextEmphasis(charData.character)) glyph = 0; // Advance past the character we just dealt with. textIterator.advance(charData.clusterLength); m_runWidthSoFar += width; if (glyphBuffer) glyphBuffer->add(glyph, fontData, width); } unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter; m_currentCharacter = textIterator.currentCharacter(); return consumedCharacters; }
unsigned SimpleShaper::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer) { bool hasExtraSpacing = (m_font->getFontDescription().letterSpacing() || m_font->getFontDescription().wordSpacing() || m_expansion) && !m_textRun.spacingDisabled(); const SimpleFontData* lastFontData = m_font->primaryFont(); bool normalizeSpace = m_textRun.normalizeSpace(); const float initialRunWidth = m_runWidthSoFar; CharacterData charData; while (textIterator.consume(charData.character)) { charData.characterOffset = textIterator.offset(); charData.clusterLength = textIterator.glyphLength(); GlyphData glyphData = glyphDataForCharacter(charData, normalizeSpace); // Some fonts do not have a glyph for zero-width-space, // in that case use the space character and override the width. float width; bool spaceUsedAsZeroWidthSpace = false; if (!glyphData.glyph && Character::treatAsZeroWidthSpace(charData.character)) { charData.character = spaceCharacter; glyphData = glyphDataForCharacter(charData); width = 0; spaceUsedAsZeroWidthSpace = true; } else { width = characterWidth(charData.character, glyphData); } Glyph glyph = glyphData.glyph; const SimpleFontData* fontData = glyphData.fontData; ASSERT(fontData); if (m_fallbackFonts && lastFontData != fontData && width) { lastFontData = fontData; trackNonPrimaryFallbackFont(fontData); } if (hasExtraSpacing && !spaceUsedAsZeroWidthSpace) width = adjustSpacing(width, charData); if (m_glyphBoundingBox) { ASSERT(glyphData.fontData); FloatRect glyphBounds = glyphData.fontData->boundsForGlyph(glyphData.glyph); // We are handling simple text run here, so Y-Offset will be zero. // FIXME: Computing bounds relative to the initial advance seems odd. Are we adjusting // these someplace else? If not, we'll end up with different bounds depending on how // we segment our advance() calls. glyphBounds.move(m_runWidthSoFar - initialRunWidth, 0); m_glyphBoundingBox->unite(glyphBounds); } if (glyphBuffer) { if (!forTextEmphasis()) { glyphBuffer->add(glyph, fontData, m_runWidthSoFar); } else if (Character::canReceiveTextEmphasis(charData.character)) { addEmphasisMark(glyphBuffer, m_runWidthSoFar + width / 2); } } // Advance past the character we just dealt with. textIterator.advance(); m_runWidthSoFar += width; } unsigned consumedCharacters = textIterator.offset() - m_currentCharacter; m_currentCharacter = textIterator.offset(); return consumedCharacters; }