Пример #1
0
// 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;
}
Пример #2
0
/*
 * 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);
    }

}
Пример #3
0
/*
 * 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;
}
Пример #4
0
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;
}
Пример #5
0
/**
 * 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;
}
Пример #6
0
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());
}
Пример #7
0
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 ));
}
Пример #8
0
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;
}
Пример #9
0
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;
}