// Given two edges, place fragment node.ident into this unitig using the thickest edge to decide on // the placement. At least one of the edges must be from the node to a fragment in the target // unitig. // // Returns true if placement was successful. // bool Unitig::addAndPlaceFrag(int32 fid, BestEdgeOverlap *bestedge5, BestEdgeOverlap *bestedge3, bool report) { int32 bidx5 = -1, bidx3 = -1; int32 blen5 = 0, blen3 = 0; ufNode frag; frag.ident = fid; frag.contained = 0; frag.parent = 0; frag.ahang = 0; frag.bhang = 0; frag.position.bgn = 0; frag.position.end = 0; frag.containment_depth = 0; // The length of the overlap depends only on the length of the a frag and the hangs. We don't // actually care about the real length (except for logging), only which is thicker. if ((bestedge5) && (bestedge5->fragId() == 0)) bestedge5 = NULL; if ((bestedge3) && (bestedge3->fragId() == 0)) bestedge3 = NULL; if ((bestedge5) && (fragIn(bestedge5->fragId()) == id())) { bidx5 = pathPosition(bestedge5->fragId()); blen5 = FI->fragmentLength(fid) + ((bestedge5->ahang() < 0) ? bestedge5->bhang() : -bestedge5->ahang()); #ifdef DEBUG_PLACEMENT writeLog("addAndPlaceFrag()-- bestedge5: %d,%d,%d,%d len %d\n", bestedge5->fragId(), bestedge5->frag3p, bestedge5->ahang(), bestedge5->bhang(), blen5); #endif assert(bestedge5->fragId() == ufpath[bidx5].ident); } if ((bestedge3) && (fragIn(bestedge3->fragId()) == id())) { bidx3 = pathPosition(bestedge3->fragId());; blen3 = FI->fragmentLength(fid) + ((bestedge3->ahang() < 0) ? bestedge3->bhang() : -bestedge3->ahang()); #ifdef DEBUG_PLACEMENT writeLog("addAndPlaceFrag()-- bestedge3: %d,%d,%d,%d len %d\n", bestedge3->fragId(), bestedge3->frag3p, bestedge3->ahang(), bestedge3->bhang(), blen3); #endif assert(bestedge3->fragId() == ufpath[bidx3].ident); } // Use the longest that exists -- an alternative would be to take the average position, but that // could get messy if the placements are different. Picking one or the other has a better chance // of working, though it'll fail if the fragment is chimeric or spans something it shouldn't, // etc. if ((blen5 == 0) && (blen3 == 0)) { writeLog("Unitig::addAndPlaceFrag()-- WARNING: Failed to place frag %d into unitig %d; no edges to the unitig.\n", fid, id()); return(false); } if (blen5 < blen3) bestedge5 = NULL; else bestedge3 = NULL; // Compute the placement -- a little scary, as we stuff both placements into the same frag, but // we guarantee only one placement is computed. if (placeFrag(frag, bidx5, bestedge5, frag, bidx3, bestedge3) == false) return(false); // If we just computed a placement before the start of the unitig, we need to shift the unitig to // make space. int32 frgBgn = MIN(frag.position.bgn, frag.position.end); if (frgBgn < 0) { frgBgn = -frgBgn; frag.position.bgn += frgBgn; frag.position.end += frgBgn; _length += frgBgn; for (uint32 fi=0; fi<ufpath.size(); fi++) { ufNode *tfrg = &ufpath[fi]; tfrg->position.bgn += frgBgn; tfrg->position.end += frgBgn; } } // Finally, add the fragment. addFrag(frag, 0, report); return(true); }
//----------------------------------------------------------------- // format the textbox contents. void mgTextScan::scan( unsigned int &posn) // starting position { // parse buffer and format text m_clipped = false; // set state to default m_page->getDefaultFormat(m_justify, m_leftMargin, m_rightMargin, m_indent, m_wrap); m_page->getDefaultFont(m_fontFace, m_fontSize, m_fontItalic, m_fontBold, m_color); m_baseFontSize = m_fontSize; newFont(); // temporaries for when we return values to defaults mgString face; short left, right, indent, size; BOOL wrap, italic, bold; DWORD color; mgTextAlign justify; unsigned int count = 0; BOOL endBuffer = false; while (!m_clipped && !endBuffer) { mgFormatCmd cmd = m_buffer->readCommand(posn); switch (cmd) { case mgJustifyCmd: { m_justify = m_buffer->readJustify(posn); if (m_justify == mgTextAlignHDefault) m_page->getDefaultFormat(m_justify, left, right, indent, wrap); break; } case mgLeftMarginCmd: { short value = m_buffer->readLeftMargin(posn); if (value == MGDEFAULTSHORT) m_page->getDefaultFormat(justify, m_leftMargin, right, indent, wrap); else m_leftMargin = (m_page->getUnits()*value)/100; newMargins(); break; } case mgRightMarginCmd: { short value = m_buffer->readRightMargin(posn); if (value == MGDEFAULTSHORT) m_page->getDefaultFormat(justify, left, m_rightMargin, indent, wrap); else m_rightMargin = (m_page->getUnits()*value)/100; newMargins(); break; } case mgIndentCmd: { short value = m_buffer->readIndent(posn); if (value == MGDEFAULTSHORT) m_page->getDefaultFormat(justify, left, right, m_indent, wrap); else m_indent = (m_page->getUnits() * value)/100; newMargins(); break; } case mgWrapCmd: { mgBooleanAttr value = m_buffer->readWrap(posn); if (value == mgDefaultBoolean) m_page->getDefaultFormat(justify, left, right, indent, m_wrap); else m_wrap = value == mgTrue; break; } case mgFontFaceCmd: m_buffer->readFontFace(posn, m_fontFace); if (m_fontFace.equals("default")) m_page->getDefaultFont(m_fontFace, size, italic, bold, color); newFont(); break; case mgFontSizeCmd: { short value = m_buffer->readFontSize(posn); if (value == MGDEFAULTSHORT) m_page->getDefaultFont(face, m_fontSize, italic, bold, color); else m_fontSize = (m_baseFontSize * value)/100; newFont(); break; } case mgFontItalicCmd: { mgBooleanAttr value = m_buffer->readFontItalic(posn); if (value == mgDefaultBoolean) m_page->getDefaultFont(face, size, m_fontItalic, bold, color); else m_fontItalic = value == mgTrue; newFont(); break; } case mgFontBoldCmd: { mgBooleanAttr value = m_buffer->readFontBold(posn); if (value == mgDefaultBoolean) m_page->getDefaultFont(face, size, italic, m_fontBold, color); else m_fontBold = value == mgTrue; newFont(); break; } case mgColorCmd: m_color = m_buffer->readColor(posn); if (m_color == MGDEFAULTCOLOR) m_page->getDefaultFont(face, size, italic, bold, m_color); break; case mgAnchorCmd: // m_anchor = (mgAnchorDesc*) m_buffer->readPtr(posn); break; case mgSpaceCmd: newWord(); addSpace(m_buffer->readSpace(posn)); break; case mgTabCmd: { newWord(); short value = m_buffer->readTab(posn); value = (m_page->getUnits() * value)/100; addTab(value); break; } case mgTextCmd: { int textLen; const char* text; m_buffer->readText(posn, textLen, text); if (!m_wrap) addFrag(false, text, textLen); else { // writeText has converted whitespace to blanks and removed // duplicate blanks. However, a single word may be broken into // multiple fragments due to tags within the word. // ex: <b>T</b>est while (textLen > 0) { int c = 0xFF & text[0]; BOOL isBlank = isspace(c) != 0; if (isBlank) { newWord(); text++; textLen--; } // count characters of next word int len = 0; while (len < textLen) { c = 0xFF & text[len]; if (!isspace(c)) len++; else break; } addFrag(isBlank, text, len); text += len; textLen -= len; } } break; } case mgChildCmd: { // read child info const void* child; mgTextAlign halign; mgTextAlign valign; m_buffer->readChild(posn, child, halign, valign); newWord(); // breaks the current word addChild(child, halign, valign); break; } case mgBreakCmd: { int height = m_buffer->readBreak(posn); newWord(); // breaks the current word newLine(height); break; } case mgClearCmd: { mgTextAlign clear = m_buffer->readClear(posn); clearMargins(clear); break; } case mgTargetCmd: addTarget((int*) m_buffer->readTarget(posn)); break; case mgDoneCmd: newWord(); // breaks the current word done(); // end of input endBuffer = true; break; } } }