int TextLayout::screenToPosition(FPoint coord) const { qreal maxx = coord.x() - 1.0; for (unsigned int i=0; i < lines(); ++i) { LineSpec ls = line(i); // qDebug() << QString("screenToPosition: (%1,%2) -> y %3 - %4 + %5").arg(coord.x()).arg(coord.y()).arg(ls.y).arg(ls.ascent).arg(ls.descent); if (ls.y + ls.descent < coord.y()) continue; qreal xpos = ls.x; for (int j = ls.firstItem; j <= ls.lastItem; ++j) { // qDebug() << QString("screenToPosition: (%1,%2) -> x %3 + %4").arg(coord.x()).arg(coord.y()).arg(xpos).arg(item(j)->glyph.wide()); qreal width = story()->getGlyphs(j)->wide(); xpos += width; if (xpos >= coord.x()) { if (story()->hasObject(j)) return j; else return xpos - width/2 > coord.x() ? j : j+1; } } if (xpos > maxx) maxx = xpos; if (xpos + 1.0 > coord.x()) // allow 1pt after end of line return ls.lastItem + 1; else if (coord.x() <= ls.x + ls.width) // last line of paragraph? return ((ls.lastItem == m_lastInFrame) ? (ls.lastItem + 1) : ls.lastItem); else if (xpos < ls.x + 0.01 && maxx >= coord.x()) // check for empty line return ls.firstItem; } return qMax(m_lastInFrame+1, m_firstInFrame); }
int TextLayout::nextLine(int pos) const { for (int i=0; i < m_lines.count(); ++i) { // find line for pos const LineSpec & ls(m_lines.at(i)); if (ls.firstItem <= pos && pos <= ls.lastItem) { if (i+1 == m_lines.count()) return endOfLine(pos); // find current xpos qreal xpos = 0.0; for (int j = ls.firstItem; j < pos; ++j) xpos += story()->getGlyphs(j)->wide(); if (pos != m_lastMagicPos || xpos > m_magicX) m_magicX = xpos; const LineSpec & ls2(m_lines.at(i+1)); // find new cpos xpos = 0.0; for (int j = ls2.firstItem; j <= ls2.lastItem; ++j) { xpos += story()->getGlyphs(j)->wide(); if (xpos > m_magicX) { m_lastMagicPos = j; return j; } } m_lastMagicPos = ls2.lastItem + 1; return ls2.lastItem + 1; } } return m_lastInFrame; }
int TextLayout::endOfLine(int pos) const { for (int i=0; i < m_lines.count(); ++i) { const LineSpec & ls(m_lines.at(i)); if (ls.firstItem <= pos && pos <= ls.lastItem) return story()->text(ls.lastItem) == SpecialChars::PARSEP ? ls.lastItem : story()->text(ls.lastItem) == ' ' ? ls.lastItem : ls.lastItem + 1; } return story()->length(); }
// Runs the Game... void Ultra1::App::Run( ) { // All of the game states we could be in... Intro intro( this ); MainMenu menu( this ); Game game( this ); MapState map_state( this ); WonState won( this ); LostState lost( this ); HelpState help( this ); StoryState story( this ); OptionsState options( this ); // Must be entered into array in same order as the const values... GameState* states[] = { &intro, &menu, &game, &map_state, &won, &lost, &help, &story, &options }; // We start in the intro... StateNumber current_state = INTRO_STATE; while( current_state != QUIT_STATE ) { // Run the current state and assign the next state to it... current_state = states[current_state]->Run( ); } }
void TextLayout::appendLine(const LineSpec& ls) { assert( ls.firstItem >= 0 ); assert( ls.firstItem < story()->length() ); assert( ls.lastItem >= 0 && ls.firstItem - ls.lastItem < 1 ); assert( ls.lastItem < story()->length() ); m_lines.append(ls); if (m_lastInFrame < m_firstInFrame) { m_firstInFrame = ls.firstItem; m_lastInFrame = ls.lastItem; } else { m_firstInFrame = qMin(m_firstInFrame, ls.firstItem); m_lastInFrame = qMax(m_lastInFrame, ls.lastItem); } }
void TextLayout::clear() { m_lines.clear(); m_path.clear(); m_firstInFrame = 0; m_lastInFrame = -1; if (m_frame->asPathText() != NULL) m_path.resize(story()->length()); }
static void emitStory(const char* m) { Story st; memset(&st, 0, sizeof(st)); st.sub[0] = crewTable; st.subSize[0] = 100; // plenty st.sub[1] = opTable; st.subSize[1] = DIM(opTable); // emit on the message line lastLine(); story(m, &st); }
PathData& TextLayout::point(int pos) { if (pos >= story()->length()) m_path.resize(story()->length()); return m_path[pos]; }
FRect TextLayout::boundingBox(int pos, uint len) const { FRect result; LineSpec ls; for (uint i=0; i < lines(); ++i) { ls = line(i); if (ls.lastItem < pos) continue; if (ls.firstItem <= pos) { /* //if (ls.lastItem == pos && (item(pos)->effects() & ScLayout_SuppressSpace) ) { if (i+1 < lines()) { ls = line(i+1); result.setRect(ls.x, ls.y - ls.ascent, 1, ls.ascent + ls.descent); } else { ls = line(lines()-1); const ParagraphStyle& pstyle(paragraphStyle(pos)); result.setRect(ls.x, ls.y + pstyle.lineSpacing() - ls.ascent, 1, ls.ascent + ls.descent); } } else */ { qreal xpos = ls.x; for (int j = ls.firstItem; j < pos; ++j) { if (story()->hasObject(j)) xpos += (story()->object(j)->width() + story()->object(j)->lineWidth()) * story()->getGlyphs(j)->scaleH; else xpos += story()->getGlyphs(j)->wide(); } qreal finalw = 1; if (story()->hasObject(pos)) finalw = (story()->object(pos)->width() + story()->object(pos)->lineWidth()) * story()->getGlyphs(pos)->scaleH; else finalw = story()->getGlyphs(pos)->wide(); const CharStyle& cs(story()->charStyle(pos)); qreal desc = -cs.font().descent(cs.fontSize() / 10.0); qreal asce = cs.font().ascent(cs.fontSize() / 10.0); result.setRect(xpos, ls.y - asce, pos < story()->length()? finalw : 1, desc+asce); } return result; } } const ParagraphStyle& pstyle(story()->paragraphStyle(qMin(pos, story()->length()))); // rather the trailing style than a segfault. if (lines() > 0) { ls = line(lines()-1); result.setRect(ls.x, ls.y + pstyle.lineSpacing() - ls.ascent, 1, ls.ascent + ls.descent); } else { result.setRect(1, 1, 1, pstyle.lineSpacing()); } return result; }