/* ----------- ID_CLEAR Command ---------- */ static void ClearCmd(WINDOW wnd) { if (TextBlockMarked(wnd)) { char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; int len = (int) (bel - bbl); SaveDeletedText(wnd, bbl, len); wnd->CurrLine = TextLineNumber(wnd, bbl); wnd->CurrCol = wnd->BlkBegCol; wnd->WndRow = wnd->BlkBegLine - wnd->wtop; if (wnd->WndRow < 0) { wnd->WndRow = 0; wnd->wtop = wnd->BlkBegLine; } /* ------ change all text lines in block to \n ----- */ while (bbl < bel) { char *cp = strchr(bbl, '\n'); if (cp > bel) cp = bel; strcpy(bbl, cp); bel -= (int) (cp - bbl); bbl++; } ClearTextBlock(wnd); BuildTextPointers(wnd); SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); wnd->TextChanged = TRUE; } }
void EditorScreen::writeEntity(int entity) { bool breaker = entity == (int) LCDChar_RBTriangle; int newCursorLineIndex = breaker ? _cursorLineIndex + 1 : _cursorLineIndex; int newCursorOffset = breaker ? 0 : _cursorOffset + entityToChars((LCDOperator) entity).count(); if (!_lines.count()) { _lines << TextLine(entity); if (breaker) _lines << TextLine(); } else { TextLine &textLine = _lines[_cursorLineIndex]; if (_cursorOffset >= textLine.charLength()) { textLine << entity; // Append the next line if new char is not a breaker and we aren't in insert mode if (!breaker && !_insertMode && _cursorLineIndex < _lines.count() - 1) { textLine << _lines[_cursorLineIndex + 1]; _lines.removeAt(_cursorLineIndex + 1); } else if (breaker) _lines << TextLine(); } else { // Get LCDString under the cursor int index = textLine.entityAt(_cursorOffset); if (index >= 0) { if (_insertMode) textLine.insert(index, entity); else textLine[index] = entity; } if (breaker && _cursorOffset < textLine.charLength() - 1) { // Insert a new line TextLine newLine; for (int i = index + 1; i < textLine.count(); ++i) newLine << textLine[i]; _lines.insert(_cursorLineIndex + 1, newLine); // Remove the last entities in <textLine> int newCount = textLine.count() - index - 1; for (int i = 0; i < newCount; ++i) textLine.removeLast(); } } } feedScreen(); emit screenChanged(); moveCursor(newCursorLineIndex, newCursorOffset); restartBlink(); }
void EditorScreen::carriageReturn() { bool insertion = false; if (_insertMode) { insertion = true; if (!_lines.count()) _lines << TextLine(); else { TextLine &textLine = _lines[_cursorLineIndex]; if (_cursorOffset < textLine.charLength()) { TextLine newTextLine; int toRemove = 0; int strIndex = textLine.entityAt(_cursorOffset); for (int i = strIndex; i < textLine.count(); ++i) { newTextLine << textLine[i]; toRemove++; } _lines.insert(_cursorLineIndex + 1, newTextLine); while (toRemove) { textLine.removeLast(); toRemove--; } } else if (_cursorLineIndex < _lines.count() - 1) _lines.insert(_cursorLineIndex + 1, TextLine()); else _lines << TextLine(); } } else if (_cursorLineIndex >= _lines.count() - 1) { _lines << TextLine(); insertion = true; } if (insertion) feedScreen(); bool scrolled; moveCursor(_cursorLineIndex + 1, 0, &scrolled); // Go to the next line if (scrolled || insertion) emit screenChanged(); restartBlink(); }
/* ----- Extend the marked block to the new x,y position ---- */ static void ExtendBlock(WINDOW wnd, int x, int y) { int bbl, bel; int ptop = min(wnd->BlkBegLine, wnd->BlkEndLine); int pbot = max(wnd->BlkBegLine, wnd->BlkEndLine); char *lp = TextLine(wnd, wnd->wtop+y); int len = (int) (strchr(lp, '\n') - lp); x = max(0, min(x, len)); y = max(0, y); wnd->BlkEndCol = min(len, x+wnd->wleft); wnd->BlkEndLine = y+wnd->wtop; SendMessage(wnd, KEYBOARD_CURSOR, wnd->BlkEndCol, wnd->BlkEndLine); bbl = min(wnd->BlkBegLine, wnd->BlkEndLine); bel = max(wnd->BlkBegLine, wnd->BlkEndLine); while (ptop < bbl) { WriteTextLine(wnd, NULL, ptop, FALSE); ptop++; } for (y = bbl; y <= bel; y++) WriteTextLine(wnd, NULL, y, FALSE); while (pbot > bel) { WriteTextLine(wnd, NULL, pbot, FALSE); --pbot; } }
void ShellContent::processLine() { _history.push_back( _entry ); _hpos = _history.size(); // _output->addTextLine ( (string) _prompt + _entry.str() ); TextSpan end = TextSpan ( _output->end(), _output->end() ); _output->insertSpan ( _prompt + _entry.str() + "\n", end ); if ( _entry.substr(0,1) != "/" ) { if ( _entry.size() > 0 ) if ( _console ) { _console->send_command( _entry.str() ); } else { make_system_call(_entry.str() ); } } else { if ( _entry.str() == "/shell" ) { start_shell(); } else { ClientSessionManagerImp::instance()->console_request( _entry.str() ); } } _entry = TextLine(); _loc.chr = 0; }
void MenuWindow::EndMenu(const char *prompt) { if (prompt == nullptr) { m_prompt.clear(); } else { m_prompt = prompt; m_header.push_back(TextLine(WindowAttribute::None, WindowColor::Gray, m_prompt)); m_header.push_back(TextLine(WindowAttribute::None, WindowColor::Gray, "")); } m_selectedItem = m_menu.end(); }
void ShellContent::hist_down() { if ( _hpos < _history.size() - 1 ) { _entry = _history[++_hpos]; } else { _hpos = _history.size(); _entry = TextLine(); } _loc.chr = _entry.size(); }
/* ----------- ID_DELETETEXT Command ---------- */ static void DeleteTextCmd(WINDOW wnd) { if (TextBlockMarked(wnd)) { char *bbl=TextLine(wnd,wnd->BlkBegLine)+wnd->BlkBegCol; char *bel=TextLine(wnd,wnd->BlkEndLine)+wnd->BlkEndCol; int len = (int) (bel - bbl); SaveDeletedText(wnd, bbl, len); wnd->TextChanged = TRUE; strcpy(bbl, bel); wnd->CurrLine = TextLineNumber(wnd, bbl-wnd->BlkBegCol); wnd->CurrCol = wnd->BlkBegCol; wnd->WndRow = wnd->BlkBegLine - wnd->wtop; if (wnd->WndRow < 0) { wnd->wtop = wnd->BlkBegLine; wnd->WndRow = 0; } SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); ClearTextBlock(wnd); BuildTextPointers(wnd); } }
void MenuWindow::GenerateLines(void) { m_lines.clear(); for (auto & item : m_menu) { std::string text(""); if (item.m_accelerator) { text.push_back(item.m_accelerator); if (item.IsSelectable() && item.IsSelected()) { text.append(" + "); } else { text.append(" - "); } } text.append(item.m_text); std::string count(" "); if (item.m_accelerator) { if (item.IsSelectable() && item.IsSelected()) { if (item.m_count == MenuItem::kCountAll) { text.append(" #all "); } else { char buf[10]; sprintf_s(buf, sizeof(buf), " #%-5d", item.m_count); count = buf; } } } text += count; if (text.size() > Console::kWidth) { text.resize(Console::kWidth); } m_lines.push_back(TextLine(item.m_attribute, WindowColor::Gray, text)); } }
void GLFont::drawText(const char *text, int halign) { int width = getStringWidth(text); int lines = 1; if (textWidth < width) textWidth = width; for (const char *pc = text; *pc; pc++) { if (*pc == '\n') lines++; } textLines.push_back(TextLine(text, halign, width, lines)); textHeight += lines * bmfont.common.lineHeight; }
/* ----- stick the moving cursor to the end of the line ---- */ static void StickEnd(WINDOW wnd) { char *cp = TextLine(wnd, wnd->CurrLine); char *cp1 = strchr(cp, '\n'); int len = cp1 ? (int) (cp1 - cp) : 0; wnd->CurrCol = min(len, wnd->CurrCol); if (wnd->wleft > wnd->CurrCol) { wnd->wleft = max(0, wnd->CurrCol - 4); SendMessage(wnd, PAINT, 0, 0); } else if (wnd->CurrCol-wnd->wleft >= ClientWidth(wnd)) { wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1); SendMessage(wnd, PAINT, 0, 0); } }
void CDisplayText::ClearText() { Ui::CWindow* pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW2)); for (int i = 0; i < MAXDTLINE; i++) { if (pw != nullptr) { pw->DeleteControl(EventType(EVENT_DT_GROUP0+i)); pw->DeleteControl(EventType(EVENT_DT_LABEL0+i)); pw->DeleteControl(EventType(EVENT_DT_VISIT0+i)); } m_textLines[i] = TextLine(); } }
bool GetFileLine(char* sOut, size_t sOutSize, char* sFile, int iLine) { bool is_found = false; int iLen; char sTemp[20] = { 0 }; char* sData; iLen = FileToString(sFile, (unsigned char**)(&sData)); if(TextLine(sData, iLen, sTemp, 20, iLine)) { is_found = true; sprintf_s(sOut, sOutSize, "%s", sTemp); } free(sData); return is_found; }
void ShellContent::processLine() { _history.push_back( _entry ); _hpos = _history.size(); _output->addTextLine ( _entry ); // TextSpan end = TextSpan ( _output->end(), _output->end() ); // _output->insertSpan ( _entry.str() + "\n", end ); make_system_call(_entry.str() ); _entry = TextLine(); _loc.chr = 0; }
void TextBuffer::clear () { // not allowed during editing Q_ASSERT (m_editingTransactions == 0); invalidateRanges(); // new block for empty buffer TextBlock *newBlock = new TextBlock (this, 0); newBlock->appendLine (TextLine (new TextLineData())); // clean out all cursors and lines, either move them to newBlock or invalidate them, if belonging to a range foreach(TextBlock* block, m_blocks) block->clearBlockContent (newBlock); // kill all buffer blocks qDeleteAll (m_blocks); m_blocks.clear (); // insert one block with one empty line m_blocks.append (newBlock); // reset lines and last used block m_lines = 1; m_lastUsedBlock = 0; // reset revision m_revision = 0; // reset bom detection m_generateByteOrderMark = false; // reset the filter device m_mimeTypeForFilterDev = "text/plain"; // clear edit history m_history.clear (); // we got cleared emit cleared (); }
bool TextBuffer::load (const QString &filename, bool &encodingErrors) { // fallback codec must exist Q_ASSERT (m_fallbackTextCodec); // codec must be set! Q_ASSERT (m_textCodec); /** * first: clear buffer in any case! */ clear (); /** * check if this is a normal file or not, else exit */ KDE_struct_stat sbuf; if (KDE::stat(filename, &sbuf) != 0 || !S_ISREG(sbuf.st_mode)) return false; /** * construct the file loader for the given file, with correct prober type */ Kate::TextLoader file (filename, m_encodingProberType); /** * triple play, maximal three loading rounds * 0) use the given encoding, be done, if no encoding errors happen * 1) use BOM to decided if unicode or if that fails, use encoding prober, if no encoding errors happen, be done * 2) use fallback encoding, be done, if no encoding errors happen * 3) use again given encoding, be done in any case */ for (int i = 0; i < 4; ++i) { /** * kill all blocks beside first one */ for (int b = 1; b < m_blocks.size(); ++b) { TextBlock* block = m_blocks.at(b); block->m_lines.clear (); delete block; } m_blocks.resize (1); /** * remove lines in first block */ m_blocks.last()->m_lines.clear (); m_lines = 0; /** * try to open file, with given encoding * in round 0 + 3 use the given encoding from user * in round 1 use 0, to trigger detection * in round 2 use fallback */ QTextCodec *codec = m_textCodec; if (i == 1) codec = 0; else if (i == 2) codec = m_fallbackTextCodec; if (!file.open (codec)) { // create one dummy textline, in any case m_blocks.last()->appendLine (TextLine (new TextLineData())); m_lines++; return false; } // read in all lines... encodingErrors = false; while ( !file.eof() ) { // read line int offset = 0, length = 0; bool currentError = !file.readLine (offset, length); encodingErrors = encodingErrors || currentError; // bail out on encoding error, if not last round! if (encodingErrors && i < 3) { kDebug (13020) << "Failed try to load file" << filename << "with codec" << (file.textCodec() ? file.textCodec()->name() : "(null)"); break; } // get unicode data for this line const QChar *unicodeData = file.unicode () + offset; // construct new text line with content from file TextLine textLine = TextLine (new TextLineData(QString (unicodeData, length))); // ensure blocks aren't too large if (m_blocks.last()->lines() >= m_blockSize) m_blocks.append (new TextBlock (this, m_blocks.last()->startLine() + m_blocks.last()->lines())); m_blocks.last()->appendLine (textLine); m_lines++; } // if no encoding error, break out of reading loop if (!encodingErrors) { // remember used codec m_textCodec = file.textCodec (); break; } } // remember if BOM was found if (file.byteOrderMarkFound ()) setGenerateByteOrderMark (true); // remember eol mode, if any found in file if (file.eol() != eolUnknown) setEndOfLineMode (file.eol()); // remember mime type for filter device m_mimeTypeForFilterDev = file.mimeTypeForFilterDev (); // assert that one line is there! Q_ASSERT (m_lines > 0); // report CODEC + ERRORS kDebug (13020) << "Loaded file " << filename << "with codec" << m_textCodec->name() << (encodingErrors ? "with" : "without") << "encoding errors"; // report BOM kDebug (13020) << (file.byteOrderMarkFound () ? "Found" : "Didn't find") << "byte order mark"; // report filter device mime-type kDebug (13020) << "used filter device for mime-type" << m_mimeTypeForFilterDev; // emit success emit loaded (filename, encodingErrors); // file loading worked, modulo encoding problems return true; }
void CharacterAnalysis::analyze() { timespec startTime; getTimeMonotonic(&startTime); pipeline_data->clearThresholds(); pipeline_data->thresholds = produceThresholds(pipeline_data->crop_gray, config); timespec contoursStartTime; getTimeMonotonic(&contoursStartTime); pipeline_data->textLines.clear(); for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++) { TextContours tc(pipeline_data->thresholds[i]); allTextContours.push_back(tc); } if (config->debugTiming) { timespec contoursEndTime; getTimeMonotonic(&contoursEndTime); cout << " -- Character Analysis Find Contours Time: " << diffclock(contoursStartTime, contoursEndTime) << "ms." << endl; } //Mat img_equalized = equalizeBrightness(img_gray); timespec filterStartTime; getTimeMonotonic(&filterStartTime); for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++) { this->filter(pipeline_data->thresholds[i], allTextContours[i]); if (config->debugCharAnalysis) cout << "Threshold " << i << " had " << allTextContours[i].getGoodIndicesCount() << " good indices." << endl; } if (config->debugTiming) { timespec filterEndTime; getTimeMonotonic(&filterEndTime); cout << " -- Character Analysis Filter Time: " << diffclock(filterStartTime, filterEndTime) << "ms." << endl; } PlateMask plateMask(pipeline_data); plateMask.findOuterBoxMask(allTextContours); pipeline_data->hasPlateBorder = plateMask.hasPlateMask; pipeline_data->plateBorderMask = plateMask.getMask(); if (plateMask.hasPlateMask) { // Filter out bad contours now that we have an outer box mask... for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++) { filterByOuterMask(allTextContours[i]); } } int bestFitScore = -1; int bestFitIndex = -1; for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++) { int segmentCount = allTextContours[i].getGoodIndicesCount(); if (segmentCount > bestFitScore) { bestFitScore = segmentCount; bestFitIndex = i; bestThreshold = pipeline_data->thresholds[i]; bestContours = allTextContours[i]; } } if (this->config->debugCharAnalysis) cout << "Best fit score: " << bestFitScore << " Index: " << bestFitIndex << endl; if (bestFitScore <= 1) { pipeline_data->disqualified = true; pipeline_data->disqualify_reason = "Low best fit score in characteranalysis"; return; } //getColorMask(img, allContours, allHierarchy, charSegments); if (this->config->debugCharAnalysis) { Mat img_contours = bestContours.drawDebugImage(bestThreshold); displayImage(config, "Matching Contours", img_contours); } LineFinder lf(pipeline_data); vector<vector<Point> > linePolygons = lf.findLines(pipeline_data->crop_gray, bestContours); vector<TextLine> tempTextLines; for (unsigned int i = 0; i < linePolygons.size(); i++) { vector<Point> linePolygon = linePolygons[i]; LineSegment topLine = LineSegment(linePolygon[0].x, linePolygon[0].y, linePolygon[1].x, linePolygon[1].y); LineSegment bottomLine = LineSegment(linePolygon[3].x, linePolygon[3].y, linePolygon[2].x, linePolygon[2].y); vector<Point> textArea = getCharArea(topLine, bottomLine); TextLine textLine(textArea, linePolygon, pipeline_data->crop_gray.size()); tempTextLines.push_back(textLine); } filterBetweenLines(bestThreshold, bestContours, tempTextLines); // Sort the lines from top to bottom. std::sort(tempTextLines.begin(), tempTextLines.end(), sort_text_line); // Now that we've filtered a few more contours, re-do the text area. for (unsigned int i = 0; i < tempTextLines.size(); i++) { vector<Point> updatedTextArea = getCharArea(tempTextLines[i].topLine, tempTextLines[i].bottomLine); vector<Point> linePolygon = tempTextLines[i].linePolygon; if (updatedTextArea.size() > 0 && linePolygon.size() > 0) { pipeline_data->textLines.push_back(TextLine(updatedTextArea, linePolygon, pipeline_data->crop_gray.size())); } } pipeline_data->plate_inverted = isPlateInverted(); if (pipeline_data->textLines.size() > 0) { int confidenceDrainers = 0; int charSegmentCount = this->bestContours.getGoodIndicesCount(); if (charSegmentCount == 1) confidenceDrainers += 91; else if (charSegmentCount < 5) confidenceDrainers += (5 - charSegmentCount) * 10; // Use the angle for the first line -- assume they'll always be parallel for multi-line plates int absangle = abs(pipeline_data->textLines[0].topLine.angle); if (absangle > config->maxPlateAngleDegrees) confidenceDrainers += 91; else if (absangle > 1) confidenceDrainers += (config->maxPlateAngleDegrees - absangle) ; // If a multiline plate has only one line, disqualify if (pipeline_data->isMultiline && pipeline_data->textLines.size() < 2) { if (config->debugCharAnalysis) std::cout << "Did not detect multiple lines on multi-line plate" << std::endl; confidenceDrainers += 95; } if (confidenceDrainers >= 90) { pipeline_data->disqualified = true; pipeline_data->disqualify_reason = "Low confidence in characteranalysis"; } else { float confidence = 100 - confidenceDrainers; pipeline_data->confidence_weights.setScore("CHARACTER_ANALYSIS_SCORE", confidence, 1.0); } } else { pipeline_data->disqualified = true; pipeline_data->disqualify_reason = "No text lines found in characteranalysis"; } if (config->debugTiming) { timespec endTime; getTimeMonotonic(&endTime); cout << "Character Analysis Time: " << diffclock(startTime, endTime) << "ms." << endl; } // Draw debug dashboard if (this->pipeline_data->config->debugCharAnalysis && pipeline_data->textLines.size() > 0) { vector<Mat> tempDash; for (unsigned int z = 0; z < pipeline_data->thresholds.size(); z++) { Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type()); pipeline_data->thresholds[z].copyTo(tmp); cvtColor(tmp, tmp, CV_GRAY2BGR); tempDash.push_back(tmp); } Mat bestVal(this->bestThreshold.size(), this->bestThreshold.type()); this->bestThreshold.copyTo(bestVal); cvtColor(bestVal, bestVal, CV_GRAY2BGR); for (unsigned int z = 0; z < this->bestContours.size(); z++) { Scalar dcolor(255,0,0); if (this->bestContours.goodIndices[z]) dcolor = Scalar(0,255,0); drawContours(bestVal, this->bestContours.contours, z, dcolor, 1); } tempDash.push_back(bestVal); displayImage(config, "Character Region Step 1 Thresholds", drawImageDashboard(tempDash, bestVal.type(), 3)); } }
void TextWindow::Putstr(WindowAttribute attribute, const char * line) { // Text windows should accumulate text and then display the text // appropriate at display time. m_lines.push_back(TextLine(attribute, WindowColor::Gray, line)); }
// Must delete this pointer in parent class void LicensePlateCandidate::recognize() { charSegmenter = NULL; pipeline_data->plate_area_confidence = 0; pipeline_data->isMultiline = config->multiline; Rect expandedRegion = this->pipeline_data->regionOfInterest; pipeline_data->crop_gray = Mat(this->pipeline_data->grayImg, expandedRegion); resize(pipeline_data->crop_gray, pipeline_data->crop_gray, Size(config->templateWidthPx, config->templateHeightPx)); CharacterAnalysis textAnalysis(pipeline_data); if (textAnalysis.confidence > 10) { EdgeFinder edgeFinder(pipeline_data); pipeline_data->plate_corners = edgeFinder.findEdgeCorners(); if (edgeFinder.confidence > 0) { timespec startTime; getTime(&startTime); Mat originalCrop = pipeline_data->crop_gray; Transformation imgTransform(this->pipeline_data->grayImg, pipeline_data->crop_gray, expandedRegion); Size cropSize = imgTransform.getCropSize(pipeline_data->plate_corners, Size(pipeline_data->config->ocrImageWidthPx, pipeline_data->config->ocrImageHeightPx)); Mat transmtx = imgTransform.getTransformationMatrix(pipeline_data->plate_corners, cropSize); pipeline_data->crop_gray = imgTransform.crop(cropSize, transmtx); if (this->config->debugGeneral) displayImage(config, "quadrilateral", pipeline_data->crop_gray); // Apply a perspective transformation to the TextLine objects // to match the newly deskewed license plate crop vector<TextLine> newLines; for (unsigned int i = 0; i < pipeline_data->textLines.size(); i++) { vector<Point2f> textArea = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].textArea); vector<Point2f> linePolygon = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].linePolygon); vector<Point2f> textAreaRemapped; vector<Point2f> linePolygonRemapped; textAreaRemapped = imgTransform.remapSmallPointstoCrop(textArea, transmtx); linePolygonRemapped = imgTransform.remapSmallPointstoCrop(linePolygon, transmtx); newLines.push_back(TextLine(textAreaRemapped, linePolygonRemapped)); } pipeline_data->textLines.clear(); for (unsigned int i = 0; i < newLines.size(); i++) pipeline_data->textLines.push_back(newLines[i]); if (config->debugTiming) { timespec endTime; getTime(&endTime); cout << "deskew Time: " << diffclock(startTime, endTime) << "ms." << endl; } charSegmenter = new CharacterSegmenter(pipeline_data); pipeline_data->plate_area_confidence = 100; } } }
std::vector<cv::Point2f> EdgeFinder::findEdgeCorners() { TextLineCollection tlc(pipeline_data->textLines); vector<Point> corners; // If the character segment is especially small, just expand the existing box // If it's a nice, long segment, then guess the correct box based on character height/position if (tlc.longerSegment.length > tlc.charHeight * 3) { float charHeightToPlateWidthRatio = pipeline_data->config->plateWidthMM / pipeline_data->config->charHeightMM; float idealPixelWidth = tlc.charHeight * (charHeightToPlateWidthRatio * 1.03); // Add 3% so we don't clip any characters float charHeightToPlateHeightRatio = pipeline_data->config->plateHeightMM / pipeline_data->config->charHeightMM; float idealPixelHeight = tlc.charHeight * charHeightToPlateHeightRatio; float verticalOffset = (idealPixelHeight * 1.5 / 2); float horizontalOffset = (idealPixelWidth * 1.25 / 2); LineSegment topLine = tlc.centerHorizontalLine.getParallelLine(verticalOffset); LineSegment bottomLine = tlc.centerHorizontalLine.getParallelLine(-1 * verticalOffset); LineSegment leftLine = tlc.centerVerticalLine.getParallelLine(-1 * horizontalOffset); LineSegment rightLine = tlc.centerVerticalLine.getParallelLine(horizontalOffset); Point topLeft = topLine.intersection(leftLine); Point topRight = topLine.intersection(rightLine); Point botRight = bottomLine.intersection(rightLine); Point botLeft = bottomLine.intersection(leftLine); corners.push_back(topLeft); corners.push_back(topRight); corners.push_back(botRight); corners.push_back(botLeft); } else { //cout << "HEYOOO!" << endl; int expandX = (int) ((float) pipeline_data->crop_gray.cols) * 0.15f; int expandY = (int) ((float) pipeline_data->crop_gray.rows) * 0.15f; int w = pipeline_data->crop_gray.cols; int h = pipeline_data->crop_gray.rows; corners.push_back(Point(-1 * expandX, -1 * expandY)); corners.push_back(Point(expandX + w, -1 * expandY)); corners.push_back(Point(expandX + w, expandY + h)); corners.push_back(Point(-1 * expandX, expandY + h)); // for (int i = 0; i < 4; i++) // { // std::cout << "CORNER: " << corners[i].x << " - " << corners[i].y << std::endl; // } } // Re-crop an image (from the original image) using the new coordinates Transformation imgTransform(pipeline_data->grayImg, pipeline_data->crop_gray, pipeline_data->regionOfInterest); vector<Point2f> remappedCorners = imgTransform.transformSmallPointsToBigImage(corners); Size cropSize = imgTransform.getCropSize(remappedCorners, Size(pipeline_data->config->templateWidthPx, pipeline_data->config->templateHeightPx)); Mat transmtx = imgTransform.getTransformationMatrix(remappedCorners, cropSize); Mat newCrop = imgTransform.crop(cropSize, transmtx); // Re-map the textline coordinates to the new crop vector<TextLine> newLines; for (unsigned int i = 0; i < pipeline_data->textLines.size(); i++) { vector<Point2f> textArea = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].textArea); vector<Point2f> linePolygon = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].linePolygon); vector<Point2f> textAreaRemapped; vector<Point2f> linePolygonRemapped; textAreaRemapped = imgTransform.remapSmallPointstoCrop(textArea, transmtx); linePolygonRemapped = imgTransform.remapSmallPointstoCrop(linePolygon, transmtx); newLines.push_back(TextLine(textAreaRemapped, linePolygonRemapped)); } // Find the PlateLines for this crop PlateLines plateLines(pipeline_data); plateLines.processImage(newCrop, newLines, 1.05); // Get the best corners PlateCorners cornerFinder(newCrop, &plateLines, pipeline_data, newLines); vector<Point> smallPlateCorners = cornerFinder.findPlateCorners(); confidence = cornerFinder.confidence; // Transform the best corner points back to the original image std::vector<Point2f> imgArea; imgArea.push_back(Point2f(0, 0)); imgArea.push_back(Point2f(newCrop.cols, 0)); imgArea.push_back(Point2f(newCrop.cols, newCrop.rows)); imgArea.push_back(Point2f(0, newCrop.rows)); Mat newCropTransmtx = imgTransform.getTransformationMatrix(imgArea, remappedCorners); vector<Point2f> cornersInOriginalImg = imgTransform.remapSmallPointstoCrop(smallPlateCorners, newCropTransmtx); return cornersInOriginalImg; }
//----------------------------------------------------------------------------------------------- inline void CommandConsole::WriteTextToLog( const std::string& text, const Color& textColor, const Color& backgroundColor, const Color& textShadowColor ) { m_log.StoreLine( TextLine( text, textColor, backgroundColor, textShadowColor ) ); }
void TextBuffer::addLine( std::string s, int pos ) { if ( pos > (int)_lines.size() || pos == -1 ) { _lines.push_back(TextLine(s)); } else { _lines.insert(_lines.begin()+pos, TextLine(s) ); } }
/* ----------- LEFT_BUTTON Message ---------- */ static int LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2) { int MouseX = (int) p1 - GetClientLeft(wnd); int MouseY = (int) p2 - GetClientTop(wnd); RECT rc = ClientRect(wnd); char *lp; int len; if (KeyBoardMarking) return TRUE; if (WindowMoving || WindowSizing) return FALSE; if (isMultiLine(wnd)) { if (TextMarking) { if (!InsideRect(p1, p2, rc)) { int x = MouseX, y = MouseY; int dir; MESSAGE msg = 0; if ((int)p2 == GetTop(wnd)) y++, dir = FALSE, msg = SCROLL; else if ((int)p2 == GetBottom(wnd)) --y, dir = TRUE, msg = SCROLL; else if ((int)p1 == GetLeft(wnd)) --x, dir = FALSE, msg = HORIZSCROLL; else if ((int)p1 == GetRight(wnd)) x++, dir = TRUE, msg = HORIZSCROLL; if (msg != 0) { if (SendMessage(wnd, msg, dir, 0)) ExtendBlock(wnd, x, y); SendMessage(wnd, PAINT, 0, 0); } } return TRUE; } if (!InsideRect(p1, p2, rc)) return FALSE; if (TextBlockMarked(wnd)) { ClearTextBlock(wnd); SendMessage(wnd, PAINT, 0, 0); } if (wnd->wlines) { if (MouseY > wnd->wlines-1) return TRUE; lp = TextLine(wnd, MouseY+wnd->wtop); len = (int) (strchr(lp, '\n') - lp); MouseX = min(MouseX, len); if (MouseX < wnd->wleft) { MouseX = 0; SendMessage(wnd, KEYBOARD, HOME, 0); } ButtonDown = TRUE; ButtonX = MouseX; ButtonY = MouseY; } else MouseX = MouseY = 0; wnd->WndRow = MouseY; SetLinePointer(wnd, MouseY+wnd->wtop); } if (isMultiLine(wnd) || (!TextBlockMarked(wnd) && MouseX+wnd->wleft < strlen(wnd->text))) wnd->CurrCol = MouseX+wnd->wleft; SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); return TRUE; }
/* --------- All displayable typed keys ------------- */ static void KeyTyped(WINDOW wnd, int c) { char *currchar = CurrChar; if ((c != '\n' && c < ' ') || (c & 0x1000)) /* ---- not recognized by editor --- */ return; if (!isMultiLine(wnd) && TextBlockMarked(wnd)) { SendMessage(wnd, CLEARTEXT, 0, 0); currchar = CurrChar; } /* ---- test typing at end of text ---- */ if (currchar == wnd->text+wnd->MaxTextLength) { /* ---- typing at the end of maximum buffer ---- */ beep(); return; } if (*currchar == '\0') { /* --- insert a newline at end of text --- */ *currchar = '\n'; *(currchar+1) = '\0'; BuildTextPointers(wnd); } /* --- displayable char or newline --- */ if (c == '\n' || wnd->InsertMode || *currchar == '\n') { /* ------ inserting the keyed character ------ */ if (wnd->text[wnd->textlen-1] != '\0') { /* --- the current text buffer is full --- */ if (wnd->textlen == wnd->MaxTextLength) { /* --- text buffer is at maximum size --- */ beep(); return; } /* ---- increase the text buffer size ---- */ wnd->textlen += GROWLENGTH; /* --- but not above maximum size --- */ if (wnd->textlen > wnd->MaxTextLength) wnd->textlen = wnd->MaxTextLength; wnd->text = DFrealloc(wnd->text, wnd->textlen+2); wnd->text[wnd->textlen-1] = '\0'; currchar = CurrChar; } memmove(currchar+1, currchar, strlen(currchar)+1); ModTextPointers(wnd, wnd->CurrLine+1, 1); if (isMultiLine(wnd) && wnd->wlines > 1) wnd->textwidth = max(wnd->textwidth, (int) (TextLine(wnd, wnd->CurrLine+1)- TextLine(wnd, wnd->CurrLine))); else wnd->textwidth = max(wnd->textwidth, strlen(wnd->text)); WriteTextLine(wnd, NULL, wnd->wtop+wnd->WndRow, FALSE); } /* ----- put the char in the buffer ----- */ *currchar = c; wnd->TextChanged = TRUE; if (c == '\n') { wnd->wleft = 0; BuildTextPointers(wnd); End(wnd); Forward(wnd); SendMessage(wnd, PAINT, 0, 0); return; } /* ---------- test end of window --------- */ if (WndCol == ClientWidth(wnd)-1) { if (!isMultiLine(wnd)) { if (!(currchar == wnd->text+wnd->MaxTextLength-2)) SendMessage(wnd, HORIZSCROLL, TRUE, 0); } else { char *cp = currchar; while (*cp != ' ' && cp != TextLine(wnd, wnd->CurrLine)) --cp; if (cp == TextLine(wnd, wnd->CurrLine) || !wnd->WordWrapMode) SendMessage(wnd, HORIZSCROLL, TRUE, 0); else { int dif = 0; if (c != ' ') { dif = (int) (currchar - cp); wnd->CurrCol -= dif; SendMessage(wnd, KEYBOARD, DEL, 0); --dif; } SendMessage(wnd, KEYBOARD, '\n', 0); currchar = CurrChar; wnd->CurrCol = dif; if (c == ' ') return; } } } /* ------ display the character ------ */ SetStandardColor(wnd); PutWindowChar(wnd, c, WndCol, wnd->WndRow); /* ----- advance the pointers ------ */ wnd->CurrCol++; }
/* ----------- ID_PARAGRAPH Command ---------- */ static void ParagraphCmd(WINDOW wnd) { int bc, fl; char *bl, *bbl, *bel, *bb; ClearTextBlock(wnd); /* ---- forming paragraph from cursor position --- */ fl = wnd->wtop + wnd->WndRow; bbl = bel = bl = TextLine(wnd, wnd->CurrLine); if ((bc = wnd->CurrCol) >= ClientWidth(wnd)) bc = 0; Home(wnd); /* ---- locate the end of the paragraph ---- */ while (*bel) { int blank = TRUE; char *bll = bel; /* --- blank line marks end of paragraph --- */ while (*bel && *bel != '\n') { if (*bel != ' ') blank = FALSE; bel++; } if (blank) { bel = bll; break; } if (*bel) bel++; } if (bel == bbl) { SendMessage(wnd, KEYBOARD, DN, 0); return; } if (*bel == '\0') --bel; if (*bel == '\n') --bel; /* --- change all newlines in block to spaces --- */ while (CurrChar < bel) { if (*CurrChar == '\n') { *CurrChar = ' '; wnd->CurrLine++; wnd->CurrCol = 0; } else wnd->CurrCol++; } /* ---- insert newlines at new margin boundaries ---- */ bb = bbl; while (bbl < bel) { bbl++; if ((int)(bbl - bb) == ClientWidth(wnd)-1) { while (*bbl != ' ' && bbl > bb) --bbl; if (*bbl != ' ') { bbl = strchr(bbl, ' '); if (bbl == NULL || bbl >= bel) break; } *bbl = '\n'; bb = bbl+1; } } BuildTextPointers(wnd); /* --- put cursor back at beginning --- */ wnd->CurrLine = TextLineNumber(wnd, bl); wnd->CurrCol = bc; if (fl < wnd->wtop) wnd->wtop = fl; wnd->WndRow = fl - wnd->wtop; SendMessage(wnd, PAINT, 0, 0); SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow); wnd->TextChanged = TRUE; BuildTextPointers(wnd); }