// Return the partner of this TabVector if the vector qualifies as // being a vertical text line, otherwise NULL. TabVector* TabVector::VerticalTextlinePartner() { if (!partners_.singleton()) return NULL; TabVector_C_IT partner_it(&partners_); TabVector* partner = partner_it.data(); BLOBNBOX_C_IT box_it1(&boxes_); BLOBNBOX_C_IT box_it2(&partner->boxes_); // Count how many boxes are also in the other list. // At the same time, gather the mean width and median vertical gap. if (textord_debug_tabfind > 1) { Print("Testing for vertical text"); partner->Print(" partner"); } int num_matched = 0; int num_unmatched = 0; int total_widths = 0; int width = startpt().x() - partner->startpt().x(); if (width < 0) width = -width; STATS gaps(0, width * 2); BLOBNBOX* prev_bbox = NULL; box_it2.mark_cycle_pt(); for (box_it1.mark_cycle_pt(); !box_it1.cycled_list(); box_it1.forward()) { BLOBNBOX* bbox = box_it1.data(); TBOX box = bbox->bounding_box(); if (prev_bbox != NULL) { gaps.add(box.bottom() - prev_bbox->bounding_box().top(), 1); } while (!box_it2.cycled_list() && box_it2.data() != bbox && box_it2.data()->bounding_box().bottom() < box.bottom()) { box_it2.forward(); } if (!box_it2.cycled_list() && box_it2.data() == bbox && bbox->region_type() >= BRT_UNKNOWN && (prev_bbox == NULL || prev_bbox->region_type() >= BRT_UNKNOWN)) ++num_matched; else ++num_unmatched; total_widths += box.width(); prev_bbox = bbox; } if (num_unmatched + num_matched == 0) return NULL; double avg_width = total_widths * 1.0 / (num_unmatched + num_matched); double max_gap = textord_tabvector_vertical_gap_fraction * avg_width; int min_box_match = static_cast<int>((num_matched + num_unmatched) * textord_tabvector_vertical_box_ratio); bool is_vertical = (gaps.get_total() > 0 && num_matched >= min_box_match && gaps.median() <= max_gap); if (textord_debug_tabfind > 1) { tprintf("gaps=%d, matched=%d, unmatched=%d, min_match=%d " "median gap=%.2f, width=%.2f max_gap=%.2f Vertical=%s\n", gaps.get_total(), num_matched, num_unmatched, min_box_match, gaps.median(), avg_width, max_gap, is_vertical?"Yes":"No"); } return (is_vertical) ? partner : NULL; }
/* * Class: org_coolreader_crengine_ReaderView * Method: updateSelectionInternal * Signature: (Lorg/coolreader/crengine/Selection;)V */ JNIEXPORT void JNICALL Java_org_coolreader_crengine_ReaderView_updateSelectionInternal (JNIEnv * _env, jobject _this, jobject _sel) { CRJNIEnv env(_env); ReaderViewNative * p = getNative(_env, _this); CRObjectAccessor sel(_env, _sel); CRStringField sel_startPos(sel, "startPos"); CRStringField sel_endPos(sel, "endPos"); CRStringField sel_text(sel, "text"); CRStringField sel_chapter(sel, "chapter"); CRIntField sel_startX(sel, "startX"); CRIntField sel_startY(sel, "startY"); CRIntField sel_endX(sel, "endX"); CRIntField sel_endY(sel, "endY"); CRIntField sel_percent(sel, "percent"); lvPoint startpt ( sel_startX.get(), sel_startY.get() ); lvPoint endpt ( sel_endX.get(), sel_endY.get() ); ldomXPointer startp = p->_docview->getNodeByPoint( startpt ); ldomXPointer endp = p->_docview->getNodeByPoint( endpt ); if ( !startp.isNull() && !endp.isNull() ) { ldomXRange r( startp, endp ); if ( r.getStart().isNull() || r.getEnd().isNull() ) return; r.sort(); if ( !r.getStart().isVisibleWordStart() ) r.getStart().prevVisibleWordStart(); //lString16 start = r.getStart().toString(); if ( !r.getEnd().isVisibleWordEnd() ) r.getEnd().nextVisibleWordEnd(); if ( r.isNull() ) return; //lString16 end = r.getEnd().toString(); //CRLog::debug("Range: %s - %s", UnicodeToUtf8(start).c_str(), UnicodeToUtf8(end).c_str()); r.setFlags(1); p->_docview->selectRange( r ); int page = p->_docview->getBookmarkPage(startp); int pages = p->_docview->getPageCount(); lString16 titleText; lString16 posText; p->_docview->getBookmarkPosText(startp, titleText, posText); int percent = 0; if ( pages>1 ) percent = 10000 * page/(pages-1); lString16 selText = r.getRangeText( '\n', 8192 ); sel_percent.set(percent); sel_startPos.set( startp.toString() ); sel_endPos.set( endp.toString() ); sel_text.set(selText); sel_chapter.set(titleText); } }
/* * Class: org_coolreader_crengine_ReaderView * Method: moveSelectionInternal * Signature: (Lorg/coolreader/crengine/Selection;II)Z */ JNIEXPORT jboolean JNICALL Java_org_coolreader_crengine_ReaderView_moveSelectionInternal (JNIEnv * _env, jobject _this, jobject _sel, jint _cmd, jint _param) { CRJNIEnv env(_env); ReaderViewNative * p = getNative(_env, _this); CRObjectAccessor sel(_env, _sel); CRStringField sel_startPos(sel, "startPos"); CRStringField sel_endPos(sel, "endPos"); CRStringField sel_text(sel, "text"); CRStringField sel_chapter(sel, "chapter"); CRIntField sel_startX(sel, "startX"); CRIntField sel_startY(sel, "startY"); CRIntField sel_endX(sel, "endX"); CRIntField sel_endY(sel, "endY"); CRIntField sel_percent(sel, "percent"); int res = p->_docview->doCommand( (LVDocCmd)_cmd, (int)_param ); if ( res ) { ldomXRangeList & sel = p->_docview->getDocument()->getSelections(); if ( sel.length()>0 ) { ldomXRange currSel; currSel = *sel[0]; if ( !currSel.isNull() ) { sel_startPos.set( currSel.getStart().toString() ); sel_endPos.set( currSel.getEnd().toString() ); lvPoint startpt ( currSel.getStart().toPoint() ); lvPoint endpt ( currSel.getEnd().toPoint() ); sel_startX.set( startpt.x ); sel_startY.set( startpt.y ); sel_endX.set( endpt.x ); sel_endY.set( endpt.y ); int page = p->_docview->getBookmarkPage(currSel.getStart()); int pages = p->_docview->getPageCount(); lString16 titleText; lString16 posText; p->_docview->getBookmarkPosText(currSel.getStart(), titleText, posText); int percent = 0; if ( pages>1 ) percent = 10000 * page/(pages-1); lString16 selText = currSel.getRangeText( '\n', 8192 ); sel_percent.set(percent); sel_text.set(selText); sel_chapter.set(titleText); return JNI_TRUE; } } } return JNI_FALSE; }
Adesk::Boolean AsdkSmiley::worldDraw(AcGiWorldDraw *wd) { assertReadEnabled(); AcGeVector3d offset(0,0,0); AcGeCircArc3d face = mfacecircle; // If dragging, don't fill the smiley // if( wd->isDragging() ){ wd->subEntityTraits().setColor( colorIndex() ); wd->subEntityTraits().setFillType( kAcGiFillNever ); } else wd->subEntityTraits().setFillType( kAcGiFillAlways ); // Give the circle a GS marker of 1 // wd->subEntityTraits().setSelectionMarker( 1 ); wd->geometry().circle( face.center(), face.radius(), mnormal ); if( !wd->isDragging() ) wd->subEntityTraits().setColor( 250 ); // Give the eyes GS markers of 2 etc. // AcGePoint3dArray eyearray; eyes( eyearray ); for( int i = 0; i < eyearray.length(); i++ ){ wd->subEntityTraits().setSelectionMarker( i + 2 ); wd->geometry().circle( eyearray.at(i) + offset, meyesize, mnormal ); } AcGePoint3d smilecen( mouthCenter() + offset ), startpt( mouthLeft() + offset ), endpt( mouthRight() + offset ); AcGeVector3d startvec = startpt - smilecen, endvec = endpt - smilecen; double mouthangle = startvec.angleTo( endvec ); wd->subEntityTraits().setSelectionMarker( eyearray.length() + 2 ); wd->geometry().circularArc( smilecen, mouthRadius(), mnormal, startvec, mouthangle, kAcGiArcChord ); return Adesk::kTrue; }
/** * Returns the baseline of the current object at the given level. * The baseline is the line that passes through (x1, y1) and (x2, y2). * WARNING: with vertical text, baselines may be vertical! */ bool PageIterator::Baseline(PageIteratorLevel level, int* x1, int* y1, int* x2, int* y2) const { if (it_->word() == NULL) return false; // Already at the end! ROW* row = it_->row()->row; WERD* word = it_->word()->word; TBOX box = (level == RIL_WORD || level == RIL_SYMBOL) ? word->bounding_box() : row->bounding_box(); int left = box.left(); ICOORD startpt(left, static_cast<inT16>(row->base_line(left) + 0.5)); int right = box.right(); ICOORD endpt(right, static_cast<inT16>(row->base_line(right) + 0.5)); // Rotate to image coordinates and convert to global image coords. startpt.rotate(it_->block()->block->re_rotation()); endpt.rotate(it_->block()->block->re_rotation()); *x1 = startpt.x() / scale_ + rect_left_; *y1 = (rect_height_ - startpt.y()) / scale_ + rect_top_; *x2 = endpt.x() / scale_ + rect_left_; *y2 = (rect_height_ - endpt.y()) / scale_ + rect_top_; return true; }
void GiGraphics::drawArrayHead(const GiContext& ctx, MgPath& path, int type, float px, float scale) { float xoffset = _arrayHeads[type - 1].xoffset * scale; Point2d startpt(path.getStartPoint()); path.trimStart(startpt, xoffset + px / 2); Matrix2d mat(Matrix2d::translation(startpt.asVector())); Vector2d vec(mgIsZero(xoffset) ? path.getStartTangent() : path.getStartPoint() - startpt); mat *= Matrix2d::rotation(vec.angle2(), startpt); mat *= Matrix2d::scaling(scale, startpt); MgPath headPath(_arrayHeads[type - 1].types); headPath.transform(mat); GiContext ctxhead(ctx); if (_arrayHeads[type - 1].fill) { ctxhead.setFillColor(ctxhead.getLineColor()); ctxhead.setNullLine(); } drawPath_(&ctxhead, headPath, ctxhead.hasFillColor(), Matrix2d::kIdentity()); }
void AsdkSmiley::ensureRadius() { AcGeVector2d vec( meyesapart / 2, meyesheight ); if (( vec.length() + 1.2 * meyesize ) > radius() ) setRadius( vec.length() + 1.2 * meyesize); AcGePoint3d center( center() ), smilecen( mouthCenter() ), startpt( mouthLeft() ), endpt( mouthRight() ), botpt( mouthBottom() ); AcGeVector3d vecstart = startpt - smilecen; if ( center.distanceTo( startpt ) > radius() / 1.1 ) setRadius( 1.1 * center.distanceTo( startpt )); if ( center.distanceTo( endpt ) > radius() / 1.1 ) setRadius( 1.1 * center.distanceTo( endpt )); if ( center.distanceTo( botpt ) > radius() / 1.1 ) setRadius( 1.1 * center.distanceTo( botpt )); }
Acad::ErrorStatus AsdkSmiley::explode(AcDbVoidPtrArray& entities) const { assertReadEnabled(); AcDbCircle *pCircle = new AcDbCircle( center(), mnormal, radius() ); entities.append( pCircle ); // Create eyes // AcGePoint3dArray eyearray; eyes( eyearray ); for( int i = 0; i < eyearray.length(); i++ ){ AcDbCircle *pCircle = new AcDbCircle( eyearray.at(i), mnormal, meyesize ); entities.append( pCircle ); } // Create smile arc // AcGePoint3d smilecen( mouthCenter() ), startpt( mouthLeft() ), endpt( mouthRight() ); AcGeVector3d normvec( 1, 0, 0 ), startvec = startpt - smilecen, endvec = endpt - smilecen; double startang = 2 * kPi - startvec.angleTo( normvec ), endang = 2 * kPi - endvec.angleTo( normvec ); AcDbArc *pArc = new AcDbArc( smilecen, mnormal, mouthRadius(), startang, endang ); entities.append( pArc ); // Create smile arc chord // AcDbLine *pLine = new AcDbLine( startpt, endpt ); entities.append( pLine ); return Acad::eOk; }
static int getTextFromPositions(lua_State *L) { CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument"); int x0 = luaL_checkint(L, 2); int y0 = luaL_checkint(L, 3); int x1 = luaL_checkint(L, 4); int y1 = luaL_checkint(L, 5); LVDocView *tv = doc->text_view; lvRect margin = tv->getPageMargins(); lvPoint startpt(x0, y0); lvPoint endpt(x1, y1); ldomXPointer startp = tv->getNodeByPoint(startpt); ldomXPointer endp = tv->getNodeByPoint(endpt); if (!startp.isNull() && !endp.isNull()) { lua_newtable(L); // new text boxes ldomXRange r(startp, endp); if (r.getStart().isNull() || r.getEnd().isNull()) return 0; r.sort(); if (!r.getStart().isVisibleWordStart()) r.getStart().prevVisibleWordStart(); if (!r.getEnd().isVisibleWordEnd()) r.getEnd().nextVisibleWordEnd(); if (r.isNull()) return 0; if (r.getStart() == r.getEnd()) { // for single CJK character ldomNode * node = r.getStart().getNode(); lString16 text = node->getText(); int textLen = text.length(); int offset = r.getEnd().getOffset(); if (offset < textLen - 1) r.getEnd().setOffset(offset + 1); } r.setFlags(1); tv->selectRange(r); // we don't need native highlight of selection int page = tv->getBookmarkPage(startp); int pages = tv->getPageCount(); lString16 titleText; lString16 posText; tv->getBookmarkPosText(startp, titleText, posText); lString16 selText = r.getRangeText( '\n', 8192 ); lua_pushstring(L, "text"); lua_pushstring(L, UnicodeToLocal(selText).c_str()); lua_settable(L, -3); lua_pushstring(L, "pos0"); lua_pushstring(L, UnicodeToLocal(r.getStart().toString()).c_str()); lua_settable(L, -3); lua_pushstring(L, "pos1"); lua_pushstring(L, UnicodeToLocal(r.getEnd().toString()).c_str()); lua_settable(L, -3); lua_pushstring(L, "title"); lua_pushstring(L, UnicodeToLocal(titleText).c_str()); lua_settable(L, -3); lua_pushstring(L, "context"); lua_pushstring(L, UnicodeToLocal(posText).c_str()); lua_settable(L, -3); lua_pushstring(L, "percent"); lua_pushnumber(L, 1.0*page/(pages-1)); lua_settable(L, -3); return 1; } return 0; }