Ejemplo n.º 1
0
int QDockAreaLayout::layoutItems( const QRect &rect, bool testonly )
{
    if ( !dockWindows || !dockWindows->first() )
	return 0;

    dirty = FALSE;

    // some corrections
    QRect r = rect;
    if ( orientation() == Vertical )
	r.setHeight( r.height() - 3 );

    // init
    lines.clear();
    ls.clear();
    QPtrListIterator<QDockWindow> it( *dockWindows );
    QDockWindow *dw = 0;
    int start = start_pos( r, orientation() );
    int pos = start;
    int sectionpos = 0;
    int linestrut = 0;
    QValueList<DockData> lastLine;
    int tbstrut = -1;
    int maxsize = size_extent( rect.size(), orientation() );
    int visibleWindows = 0;

    // go through all widgets in the dock
    while ( ( dw = it.current() ) != 0 ) {
	++it;
	if ( dw->isHidden() )
	    continue;
	++visibleWindows;
	// find position for the widget: This is the maximum of the
	// end of the previous widget and the offset of the widget. If
	// the position + the width of the widget dosn't fit into the
	// dock, try moving it a bit back, if possible.
	int op = pos;
	int dockExtend = dock_extent( dw, orientation(), maxsize );
	if ( !dw->isStretchable() ) {
	    pos = QMAX( pos, dw->offset() );
	    if ( pos + dockExtend > size_extent( r.size(), orientation() ) - 1 )
		pos = QMAX( op, size_extent( r.size(), orientation() ) - 1 - dockExtend );
	}
	if ( !lastLine.isEmpty() && !dw->newLine() && space_left( rect, pos, orientation() ) < dockExtend )
	    shrink_extend( dw, dockExtend, space_left( rect, pos, orientation() ), orientation() );
	// if the current widget doesn't fit into the line anymore and it is not the first widget of the line
	if ( !lastLine.isEmpty() &&
	     ( space_left( rect, pos, orientation() ) < dockExtend || dw->newLine() ) ) {
	    if ( !testonly ) // place the last line, if not in test mode
		place_line( lastLine, orientation(), linestrut, size_extent( r.size(), orientation() ), tbstrut, maxsize, this );
	    // remember the line coordinats of the last line
	    if ( orientation() == Horizontal )
		lines.append( QRect( 0, sectionpos, r.width(), linestrut ) );
	    else
		lines.append( QRect( sectionpos, 0, linestrut, r.height() ) );
	    // do some clearing for the next line
	    lastLine.clear();
	    sectionpos += linestrut;
	    linestrut = 0;
	    pos = start;
	    tbstrut = -1;
	}

	// remeber first widget of a line
	if ( lastLine.isEmpty() ) {
	    ls.append( dw );
	    // try to make the best position
	    int op = pos;
	    if ( !dw->isStretchable() )
		pos = QMAX( pos, dw->offset() );
	    if ( pos + dockExtend > size_extent( r.size(), orientation() ) - 1 )
		pos = QMAX( op, size_extent( r.size(), orientation() ) - 1 - dockExtend );
	}
	// do some calculations and add the remember the rect which the docking widget requires for the placing
	QRect dwRect(pos, sectionpos, dockExtend, dock_strut( dw, orientation()  ) );
	lastLine.append( DockData( dw, dwRect ) );
	if ( ::qt_cast<QToolBar*>(dw) )
	    tbstrut = QMAX( tbstrut, dock_strut( dw, orientation() ) );
	linestrut = QMAX( dock_strut( dw, orientation() ), linestrut );
	add_size( dockExtend, pos, orientation() );
    }

    // if some stuff was not placed/stored yet, do it now
    if ( !testonly )
	place_line( lastLine, orientation(), linestrut, size_extent( r.size(), orientation() ), tbstrut, maxsize, this );
    if ( orientation() == Horizontal )
	lines.append( QRect( 0, sectionpos, r.width(), linestrut ) );
    else
	lines.append( QRect( sectionpos, 0, linestrut, r.height() ) );
    if ( *(--lines.end()) == *(--(--lines.end())) )
	lines.remove( lines.at( lines.count() - 1 ) );

    it.toFirst();
    bool hadResizable = FALSE;
    while ( ( dw = it.current() ) != 0 ) {
	++it;
	if ( !dw->isVisibleTo( parentWidget ) )
	    continue;
	hadResizable = hadResizable || dw->isResizeEnabled();
	dw->updateSplitterVisibility( visibleWindows > 1 ); //!dw->area()->isLastDockWindow( dw ) );
    }
    return sectionpos + linestrut;
}
Ejemplo n.º 2
0
// Extracts Tesseract features and appends them to the features vector.
// Startpt to lastpt, inclusive, MUST have the same src_outline member,
// which may be NULL. The vector from lastpt to its next is included in
// the feature extraction. Hidden edges should be excluded by the caller.
// If force_poly is true, the features will be extracted from the polygonal
// approximation even if more accurate data is available.
static void ExtractFeaturesFromRun(
    const EDGEPT* startpt, const EDGEPT* lastpt,
    const DENORM& denorm, double feature_length, bool force_poly,
    GenericVector<INT_FEATURE_STRUCT>* features) {
  const EDGEPT* endpt = lastpt->next;
  const C_OUTLINE* outline = startpt->src_outline;
  if (outline != NULL && !force_poly) {
    // Detailed information is available. We have to normalize only from
    // the root_denorm to denorm.
    const DENORM* root_denorm = denorm.RootDenorm();
    int total_features = 0;
    // Get the features from the outline.
    int step_length = outline->pathlength();
    int start_index = startpt->start_step;
    // pos is the integer coordinates of the binary image steps.
    ICOORD pos = outline->position_at_index(start_index);
    // We use an end_index that allows us to use a positive increment, but that
    // may be beyond the bounds of the outline steps/ due to wrap-around, to
    // so we use % step_length everywhere, except for start_index.
    int end_index = lastpt->start_step + lastpt->step_count;
    if (end_index <= start_index)
      end_index += step_length;
    LLSQ prev_points;
    LLSQ prev_dirs;
    FCOORD prev_normed_pos = outline->sub_pixel_pos_at_index(pos, start_index);
    denorm.NormTransform(root_denorm, prev_normed_pos, &prev_normed_pos);
    LLSQ points;
    LLSQ dirs;
    FCOORD normed_pos;
    int index = GatherPoints(outline, feature_length, denorm, root_denorm,
                             start_index, end_index, &pos, &normed_pos,
                             &points, &dirs);
    while (index <= end_index) {
      // At each iteration we nominally have 3 accumulated sets of points and
      // dirs: prev_points/dirs, points/dirs, next_points/dirs and sum them
      // into sum_points/dirs, but we don't necessarily get any features out,
      // so if that is the case, we keep accumulating instead of rotating the
      // accumulators.
      LLSQ next_points;
      LLSQ next_dirs;
      FCOORD next_normed_pos;
      index = GatherPoints(outline, feature_length, denorm, root_denorm,
                           index, end_index, &pos, &next_normed_pos,
                           &next_points, &next_dirs);
      LLSQ sum_points(prev_points);
      // TODO(rays) find out why it is better to use just dirs and next_dirs
      // in sum_dirs, instead of using prev_dirs as well.
      LLSQ sum_dirs(dirs);
      sum_points.add(points);
      sum_points.add(next_points);
      sum_dirs.add(next_dirs);
      bool made_features = false;
      // If we have some points, we can try making some features.
      if (sum_points.count() > 0) {
        // We have gone far enough from the start. Make a feature and restart.
        FCOORD fit_pt = sum_points.mean_point();
        FCOORD fit_vector = MeanDirectionVector(sum_points, sum_dirs,
                                                prev_normed_pos, normed_pos);
        // The segment to which we fit features is the line passing through
        // fit_pt in direction of fit_vector that starts nearest to
        // prev_normed_pos and ends nearest to normed_pos.
        FCOORD start_pos = prev_normed_pos.nearest_pt_on_line(fit_pt,
                                                              fit_vector);
        FCOORD end_pos = normed_pos.nearest_pt_on_line(fit_pt, fit_vector);
        // Possible correction to match the adjacent polygon segment.
        if (total_features == 0 && startpt != endpt) {
          FCOORD poly_pos(startpt->pos.x, startpt->pos.y);
          denorm.LocalNormTransform(poly_pos, &start_pos);
        }
        if (index > end_index && startpt != endpt) {
          FCOORD poly_pos(endpt->pos.x, endpt->pos.y);
          denorm.LocalNormTransform(poly_pos, &end_pos);
        }
        int num_features = ComputeFeatures(start_pos, end_pos, feature_length,
                                           features);
        if (num_features > 0) {
          // We made some features so shuffle the accumulators.
          prev_points = points;
          prev_dirs = dirs;
          prev_normed_pos = normed_pos;
          points = next_points;
          dirs = next_dirs;
          made_features = true;
          total_features += num_features;
        }
        // The end of the next set becomes the end next time around.
        normed_pos = next_normed_pos;
      }
      if (!made_features) {
        // We didn't make any features, so keep the prev accumulators and
        // add the next ones into the current.
        points.add(next_points);
        dirs.add(next_dirs);
      }
    }
  } else {
    // There is no outline, so we are forced to use the polygonal approximation.
    const EDGEPT* pt = startpt;
    do {
      FCOORD start_pos(pt->pos.x, pt->pos.y);
      FCOORD end_pos(pt->next->pos.x, pt->next->pos.y);
      denorm.LocalNormTransform(start_pos, &start_pos);
      denorm.LocalNormTransform(end_pos, &end_pos);
      ComputeFeatures(start_pos, end_pos, feature_length, features);
    } while ((pt = pt->next) != endpt);
  }
}
Ejemplo n.º 3
0
inT32 C_OUTLINE::count_transitions(                 //winding number
                                   inT32 threshold  //on size
                                  ) {
  BOOL8 first_was_max_x;         //what was first
  BOOL8 first_was_max_y;
  BOOL8 looking_for_max_x;       //what is next
  BOOL8 looking_for_min_x;
  BOOL8 looking_for_max_y;       //what is next
  BOOL8 looking_for_min_y;
  int stepindex;                 //current step
  inT32 total_steps;             //steps to do
                                 //current limits
  inT32 max_x, min_x, max_y, min_y;
  inT32 initial_x, initial_y;    //initial limits
  inT32 total;                   //total changes
  ICOORD pos;                    //position of point
  ICOORD next_step;              //step to next pix

  pos = start_pos ();
  total_steps = pathlength ();
  total = 0;
  max_x = min_x = pos.x ();
  max_y = min_y = pos.y ();
  looking_for_max_x = TRUE;
  looking_for_min_x = TRUE;
  looking_for_max_y = TRUE;
  looking_for_min_y = TRUE;
  first_was_max_x = FALSE;
  first_was_max_y = FALSE;
  initial_x = pos.x ();
  initial_y = pos.y ();          //stop uninit warning
  for (stepindex = 0; stepindex < total_steps; stepindex++) {
                                 //all intersected
    next_step = step (stepindex);
    pos += next_step;
    if (next_step.x () < 0) {
      if (looking_for_max_x && pos.x () < min_x)
        min_x = pos.x ();
      if (looking_for_min_x && max_x - pos.x () > threshold) {
        if (looking_for_max_x) {
          initial_x = max_x;
          first_was_max_x = FALSE;
        }
        total++;
        looking_for_max_x = TRUE;
        looking_for_min_x = FALSE;
        min_x = pos.x ();        //reset min
      }
    }
    else if (next_step.x () > 0) {
      if (looking_for_min_x && pos.x () > max_x)
        max_x = pos.x ();
      if (looking_for_max_x && pos.x () - min_x > threshold) {
        if (looking_for_min_x) {
          initial_x = min_x;     //remember first min
          first_was_max_x = TRUE;
        }
        total++;
        looking_for_max_x = FALSE;
        looking_for_min_x = TRUE;
        max_x = pos.x ();
      }
    }
    else if (next_step.y () < 0) {
      if (looking_for_max_y && pos.y () < min_y)
        min_y = pos.y ();
      if (looking_for_min_y && max_y - pos.y () > threshold) {
        if (looking_for_max_y) {
          initial_y = max_y;     //remember first max
          first_was_max_y = FALSE;
        }
        total++;
        looking_for_max_y = TRUE;
        looking_for_min_y = FALSE;
        min_y = pos.y ();        //reset min
      }
    }
    else {
      if (looking_for_min_y && pos.y () > max_y)
        max_y = pos.y ();
      if (looking_for_max_y && pos.y () - min_y > threshold) {
        if (looking_for_min_y) {
          initial_y = min_y;     //remember first min
          first_was_max_y = TRUE;
        }
        total++;
        looking_for_max_y = FALSE;
        looking_for_min_y = TRUE;
        max_y = pos.y ();
      }
    }

  }
  if (first_was_max_x && looking_for_min_x) {
    if (max_x - initial_x > threshold)
      total++;
    else
      total--;
  }
  else if (!first_was_max_x && looking_for_max_x) {
    if (initial_x - min_x > threshold)
      total++;
    else
      total--;
  }
  if (first_was_max_y && looking_for_min_y) {
    if (max_y - initial_y > threshold)
      total++;
    else
      total--;
  }
  else if (!first_was_max_y && looking_for_max_y) {
    if (initial_y - min_y > threshold)
      total++;
    else
      total--;
  }

  return total;
}