void TextLinker::FindLinks() { m_links.clear(); const std::vector<GG::Font::LineData>& line_data = GetLineData(); GG::Y y_posn(0); // y-coordinate of the top of the current line Link link; for (std::vector<GG::Font::LineData>::const_iterator it = line_data.begin(); it != line_data.end(); ++it) { const GG::Font::LineData& curr_line = *it; for (unsigned int i = 0; i < curr_line.char_data.size(); ++i) { for (unsigned int j = 0; j < curr_line.char_data[i].tags.size(); ++j) { const boost::shared_ptr<GG::Font::FormattingTag>& tag = curr_line.char_data[i].tags[j]; if (tag->tag_name == VarText::PLANET_ID_TAG || tag->tag_name == VarText::SYSTEM_ID_TAG || tag->tag_name == VarText::SHIP_ID_TAG || tag->tag_name == VarText::FLEET_ID_TAG || tag->tag_name == VarText::BUILDING_ID_TAG || tag->tag_name == VarText::FIELD_ID_TAG || tag->tag_name == VarText::COMBAT_ID_TAG || tag->tag_name == VarText::EMPIRE_ID_TAG || tag->tag_name == VarText::DESIGN_ID_TAG || tag->tag_name == VarText::PREDEFINED_DESIGN_TAG || tag->tag_name == VarText::TECH_TAG || tag->tag_name == VarText::BUILDING_TYPE_TAG || tag->tag_name == VarText::SPECIAL_TAG || tag->tag_name == VarText::SHIP_HULL_TAG || tag->tag_name == VarText::SHIP_PART_TAG || tag->tag_name == VarText::SPECIES_TAG || tag->tag_name == VarText::FIELD_TYPE_TAG || tag->tag_name == VarText::METER_TYPE_TAG || tag->tag_name == TextLinker::ENCYCLOPEDIA_TAG || tag->tag_name == TextLinker::GRAPH_TAG) { link.type = tag->tag_name; if (tag->close_tag) { link.text_posn.second = Value(curr_line.char_data[i].string_index); m_links.push_back(link); link = Link(); } else { link.data = tag->params[0]; link.text_posn.first = Value(curr_line.char_data[i].string_index); for (unsigned int k = 0; k < curr_line.char_data[i].tags.size(); ++k) { link.text_posn.first -= Value(curr_line.char_data[i].tags[k]->StringSize()); } } // Before decoration, the real positions are the same as the raw ones link.real_text_posn = link.text_posn; } } } } LocateLinks(); }
void CLogManager::GetLineData( LPTSTR lpszData, int nSize ) { if (lpszData == NULL) { return; } char* pCh = lpszData; std::string strLine = GetLineData(); for (int idx = 0; idx < nSize; idx++) { *pCh++ = strLine[idx]; } }
// Generates training data for training a line recognizer, eg LSTM. // Breaks the boxes into lines, normalizes them, converts to ImageData and // appends them to the given training_data. void Tesseract::TrainFromBoxes(const GenericVector<TBOX>& boxes, const GenericVector<STRING>& texts, BLOCK_LIST *block_list, DocumentData* training_data) { int box_count = boxes.size(); // Process all the text lines in this page, as defined by the boxes. int end_box = 0; // Don't let \t, which marks newlines in the box file, get into the line // content, as that makes the line unusable in training. while (end_box < texts.size() && texts[end_box] == "\t") ++end_box; for (int start_box = end_box; start_box < box_count; start_box = end_box) { // Find the textline of boxes starting at start and their bounding box. TBOX line_box = boxes[start_box]; STRING line_str = texts[start_box]; for (end_box = start_box + 1; end_box < box_count && texts[end_box] != "\t"; ++end_box) { line_box += boxes[end_box]; line_str += texts[end_box]; } // Find the most overlapping block. BLOCK* best_block = NULL; int best_overlap = 0; BLOCK_IT b_it(block_list); for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) { BLOCK* block = b_it.data(); if (block->poly_block() != NULL && !block->poly_block()->IsText()) continue; // Not a text block. TBOX block_box = block->bounding_box(); block_box.rotate(block->re_rotation()); if (block_box.major_overlap(line_box)) { TBOX overlap_box = line_box.intersection(block_box); if (overlap_box.area() > best_overlap) { best_overlap = overlap_box.area(); best_block = block; } } } ImageData* imagedata = NULL; if (best_block == NULL) { tprintf("No block overlapping textline: %s\n", line_str.string()); } else { imagedata = GetLineData(line_box, boxes, texts, start_box, end_box, *best_block); } if (imagedata != NULL) training_data->AddPageToDocument(imagedata); // Don't let \t, which marks newlines in the box file, get into the line // content, as that makes the line unusable in training. while (end_box < texts.size() && texts[end_box] == "\t") ++end_box; } }
void TextLinker::LocateLinks() { const std::vector<GG::Font::LineData>& line_data = GetLineData(); const boost::shared_ptr<GG::Font>& font = GetFont(); if (m_links.empty()) return; GG::Y y_posn(0); // y-coordinate of the top of the current line // We assume that links are stored in m_links in the order they appear in the text. // We shall iterate through the text, updating the rectangles of a link whenever we know we are inside it std::vector<Link>::iterator current_link = m_links.begin(); bool inside_link = false; for (std::vector<GG::Font::LineData>::const_iterator it = line_data.begin(); it != line_data.end(); ++it, y_posn += font->Lineskip()) { const GG::Font::LineData& curr_line = *it; // if the last line ended without the current tag ending if (inside_link) current_link->rects.push_back(GG::Rect(GG::X0, y_posn, GG::X0, y_posn + font->Height())); for (unsigned int i = 0; i < curr_line.char_data.size(); ++i) { // The link text_posn is at the beginning of the tag, whereas // char_data jumps over tags. That is why we cannot test for precise equality if (!inside_link && curr_line.char_data[i].string_index >= current_link->real_text_posn.first && curr_line.char_data[i].string_index < current_link->real_text_posn.second) { inside_link = true; // Clear out the old rectangles current_link->rects.clear(); current_link->rects.push_back(GG::Rect(i ? curr_line.char_data[i - 1].extent : GG::X0, y_posn, GG::X0, y_posn + font->Height())); } else if (inside_link && curr_line.char_data[i].string_index >= current_link->real_text_posn.second) { inside_link = false; current_link->rects.back().lr.x = i ? curr_line.char_data[i - 1].extent : GG::X0; ++current_link; if (current_link == m_links.end()) return; } } // if a line is ending without the current tag ending if (inside_link) current_link->rects.back().lr.x = curr_line.char_data.empty() ? GG::X0 : curr_line.char_data.back().extent; } }
INDEX CPROC CheckSectorInRect( INDEX sector, PSECTORSELECTINFO psi ) { PORTHOAREA rect = psi->rect; INDEX pStart, pCur; int priorend = TRUE; _POINT p; //GETWORLD( psi->iWorld ); pCur = pStart = GetFirstWall( psi->iWorld, sector, &priorend ); do { PFLATLAND_MYLINESEG line; GetLineData( psi->iWorld, GetWallLine( psi->iWorld, pCur ), &line ); if( priorend ) { addscaled( p, line->r.o, line->r.n, line->dTo ); } else { addscaled( p, line->r.o, line->r.n, line->dFrom ); } //Log7( "Checking (%g,%g) vs (%g,%g)-(%g,%g)", if( p[0] < (rect->x) || p[0] > (rect->x + rect->w) || p[1] < (rect->y) || p[1] > (rect->y + rect->h) ) { pCur = INVALID_INDEX; break; } pCur = GetNextWall( psi->iWorld , pCur, &priorend ); }while( pCur != pStart ); if( pCur == pStart ) { if( psi->ppsectors ) psi->ppsectors[psi->nsectors++] = sector; else psi->nsectors++; } return 0; }
/** * @brief 強調表示文字列の検索 * @param pBeforeBetween 前の行の持ち越し色分け * @param plsWords 強調表示文字列リスト * @return 変更に変化があった場合trueが返る */ bool CFootyLine::SearchEmphasis(TakeOver *pBeforeBetween, LsWords *plsWords) { if (!plsWords)return false; // 宣言 WordPt pNowWord; //!< 現在走査中の強調表示文字列 TakeOver::iterator pNowBefore; //!< 前データセット用 const wchar_t *pNowChar = GetLineData(); //!< 現在走査中の文字列 size_t nStringLen = GetLineLength(); //!< 文字列の長さ CStaticStack<WordPt,sizeof(int)*8> cEmpStack; //!< 現在色つけしているスタック EmpPos stInsert; //!< 挿入する構造体 // 初期化 TakeOver vecBetweenBackup; vecBetweenBackup = m_vecLineBetweenAfter; m_vecColorInfo.clear(); m_vecLineBetweenAfter.clear(); // 前からのデータをセットする if (pBeforeBetween){ // データが存在するときのみ stInsert.m_nPosition = 0; stInsert.m_bIsStart = true; for (pNowBefore=pBeforeBetween->begin();pNowBefore!=pBeforeBetween->end();pNowBefore++){ (*pNowBefore)->m_bDuplix = true; // 重複チェック stInsert.m_Color = (*pNowBefore)->GetColor(); // コマンドをリストへ m_vecColorInfo.push_back(stInsert); cEmpStack.push(*pNowBefore); } } // 小文字化 std::wstring strLower = GetLineData(); const wchar_t *pNowLower = strLower.c_str(); CEmphasisWord::SetLower(&strLower[0], nStringLen); // 検索していく for (size_t i=0;i<nStringLen;i++,pNowChar++,pNowLower++) { bool bWordSkipped = false; // 文字列を走査していく for (pNowWord=plsWords->begin();pNowWord!=plsWords->end();pNowWord++) { // この文字が無効であるかチェックする if (pNowWord->m_bDuplix)continue; // 重複チェック if (i != 0) { if (pNowWord->IsOnlyHead())continue; // 先頭に限る if (!pNowWord->CheckIndependence(pNowChar-1,false)) // 独立性チェック(前) continue; } if (cEmpStack.size() == 0) { if (!pNowWord->IsPermitted(0))continue; } else { if (!pNowWord->IsPermitted(cEmpStack.top()->GetLevel()))continue; } if (nStringLen - i < pNowWord->GetLen1()) // 文字の長さは十分か? { continue; } if (nStringLen - i != pNowWord->GetLen1()) { if (!pNowWord->CheckIndependence (pNowChar+pNowWord->GetLen1(),true)) // 独立性チェック(後) continue; } // 文字が一致するかチェック if (!MATCH_STR(pNowWord->GetString1(),pNowWord->GetLen1())) continue; // 開始コマンドを挿入する stInsert.m_nPosition = i; stInsert.m_Color = pNowWord->GetColor(); stInsert.m_bIsStart = true; m_vecColorInfo.push_back(stInsert); // インデックス番号を先へ移動させる i += pNowWord->GetLen1() - 1; pNowChar += pNowWord->GetLen1() - 1; pNowLower+= pNowWord->GetLen1() - 1; bWordSkipped = true; // 強調表示情報によって場合分け if (pNowWord->GetType() == EMP_WORD){ // 単語の時は、それの終了コマンドを挿入する stInsert.m_nPosition = i + 1; stInsert.m_bIsStart = false; m_vecColorInfo.push_back(stInsert); } else{ // スタックを積む pNowWord->m_bDuplix = true; cEmpStack.push(pNowWord); } // 次の文字のループへ移動する goto To_NextLoop; } //終了をチェック if (cEmpStack.size()){ pNowWord = cEmpStack.top(); // 二個目の単語当たりをチェック if ((pNowWord->GetType() == EMP_MULTI_BETWEEN || pNowWord->GetType() == EMP_LINE_BETWEEN) && nStringLen - i >= pNowWord->GetLen2()){ if (MATCH_STR(pNowWord->GetString2(),pNowWord->GetLen2())){ // インデックス番号を先へ移動させる i += pNowWord->GetLen2() - 1; pNowChar += pNowWord->GetLen2() - 1; pNowLower += pNowWord->GetLen2() - 1; bWordSkipped = true; // 終了コマンドを挿入する stInsert.m_nPosition = i + 1; stInsert.m_bIsStart = false; m_vecColorInfo.push_back(stInsert); // スタックを排除 pNowWord->m_bDuplix = false; cEmpStack.pop(); } } } // 次のループへ To_NextLoop:; // サロゲートペアの1文字目で、強調表示が見つからなかったときはさらに一つ進めておく if (!bWordSkipped && IsSurrogateLead(*pNowChar)){ pNowChar++;i++; } } // 次のベクトルへ for (;cEmpStack.size();){ if (cEmpStack.top()->GetType() == EMP_MULTI_BETWEEN) m_vecLineBetweenAfter.push_back(cEmpStack.top()); cEmpStack.top()->m_bDuplix = false; cEmpStack.pop(); } m_bEmphasisChached = true; return !(vecBetweenBackup == m_vecLineBetweenAfter); }
uintptr_t CPROC DrawSectorLines( INDEX pSector, uintptr_t unused ) { _POINT o, n; POBJECT object = CreateObject(); INDEX iWorld = DrawThis.iWorld; INDEX pStart, pCur; int count=0; int priorend = unused; DrawThis.object = object; // origin at z +1 scale( o, VectorConst_Y, 10.0 );//SetPoint( o, VectorConst_Z ); // direction z+1 SetPoint( n, VectorConst_Y ); AddPlane( object, o, n, 0 ); Invert( n ); Invert( o ); AddPlane( object, o, n, 0 ); //DrawSpaceLines( display->pImage, pSector->spacenode ); lprintf( WIDE("Adding Sector %d"), pSector ); pCur = pStart = GetFirstWall( iWorld, pSector, &priorend ); do { _POINT tmp; LOGICAL d = IsSectorClockwise( iWorld, pSector ); //GETWORLD( display->pWorld ); INDEX iLine; PFLATLAND_MYLINESEG Line; //VECTOR p1, p2; iLine = GetWallLine( iWorld, pCur ); GetLineData( iWorld, iLine, &Line ); // stop infinite looping... may be badly linked... count++; if( count > 20 ) { xlprintf(LOG_ALWAYS)( WIDE("Conservative limit of 20 lines on a wall has been reached!") ); DebugBreak(); break; } { _POINT o, n, r; //int d; o[0] = Line->r.o[0]; o[1] = Line->r.o[2]; o[2] = Line->r.o[1]; tmp[0] = Line->r.n[0]; tmp[1] = Line->r.n[2]; tmp[2] = Line->r.n[1]; if( priorend ) { lprintf( WIDE("prior end causes reversal...") ); Invert( tmp ); } if( d ) { lprintf( WIDE("Sector clockwise..>") ); Invert( tmp ); } //SetPoint( o, Line->r.o ); crossproduct( n, VectorConst_Y, tmp ); /* if( priorend ) { d = 1; Invert( n ); } else { d = 1; } */ lprintf( WIDE("Adding plane to object... ") ); PrintVector( o ); PrintVector( n ); AddPlane( DrawThis.object, o, n, (GetMatedWall( iWorld, pCur )==INVALID_INDEX)?0:2 ); } pCur = GetNextWall(l.world , pCur, &priorend ); }while( pCur != pStart ); if( IntersectObjectPlanes( object ) ) { // destroy these planes, and add new ones. //priorend = FALSE; //DestroyObject( &object ); } // oh - add lines first one way and then the other... interesting // to test both directions of priorend! if( !unused ) DrawSectorLines( pSector, 1 ); PutIn( object, DrawThis.root ); { PFLATLAND_TEXTURE texture; INDEX iTexture = GetSectorTexture( l.world, pSector ); GetTextureData( l.world, iTexture, &texture ); SetObjectColor( object, texture->data.color /*BASE_COLOR_BLUE*/ ); } return 0; // continue drawing... non zero breaks loop... }