34 #if defined(ASSERTION_USED)
37 return cd1 == 0 || cd2 != -1;
49 static void paintDebugInfo(
AW_device *device,
int color,
const Position& pos,
const char *txt) {
54 static void paintStrandDebugInfo(
AW_device *device,
int color, SEC_helix_strand *strand) {
55 AW_click_cd cd(device, strand->self(), strand->rightAttachAbspos()); paintDebugInfo(device, color, strand->rightAttachPoint(),
"RAP");
56 cd.
set_cd2(strand->leftAttachAbspos()); paintDebugInfo(device, color, strand->leftAttachPoint(),
"LAP");
57 cd.set_cd2(strand->startAttachAbspos()); paintDebugInfo(device, color, strand->get_fixpoint(), strand->isRootsideFixpoint() ?
"RFP" :
"FP");
75 gc_edit4_to_secedit[gc] = -1;
102 line_property_gc[gc][gc2] = prop_gc;
110 return gc_edit4_to_secedit[edit4_gc];
118 return line_property_gc[gc1][gc2];
129 double noteDistance,
const char *text,
130 bool lineToPos,
bool linesToLeftRight,
bool boxText)
142 Vector strand(left, right);
143 Angle pos2note(strand);
147 double half_charSize = center_char[fontgc].length();
153 AW_pos half_height = center_char[fontgc].y();
155 double note_distance =
max(half_height, half_width) * (boxText ? 1.3 : 1.0);
156 note_distance =
max(note_distance, noteDistance);
164 if (lineToPos || linesToLeftRight) {
169 device->
line(gc, boxText ? note_center : note_center-dist, pos+dist);
171 if (linesToLeftRight) {
172 Vector out(pos, note_center);
175 Vector toLeft(note_center, left);
176 Vector toRight(note_center, right);
178 device->
line(gc, boxText ? note_center : note_center+toLeft*(half_width/toLeft.
length()),
180 device->
line(gc, boxText ? note_center : note_center+toRight*(half_width/toRight.
length()),
187 Position rightOut = right+out+rightIndent;
188 Position leftOut = left+out-rightIndent;
191 device->
line(gc, right+posPad, rightOut);
193 device->
line(gc, left+posPad, leftOut);
196 device->
line(gc, leftOut, rightOut);
199 Vector rightTextPad(note_center, rightOut);
202 device->
line(gc, note_center+rightTextPad, rightOut);
203 device->
line(gc, note_center-rightTextPad, leftOut);
209 Vector center_textcorner(-half_width, half_height);
210 Position textcorner = note_center+center_textcorner;
213 Vector center_corner(-half_width-half_height*0.3, half_height*1.3);
214 Rectangle box(note_center+center_corner, -2*center_corner);
220 device->
text(gc, text, textcorner);
231 const Position&
pos1 = drawnPositions->drawn_before(absPos, &abs1);
232 const Position&
pos2 = drawnPositions->drawn_after (absPos, &abs2);
238 const Position *posDrawn = drawnPositions->drawn_at(absPos);
250 paintAnnotation(device, gc, pos, pos1, pos2, vec12.
length(), text, lineToBase,
false, boxText);
253 void SEC_root::paintEcoliPositions(
AW_device *device) {
254 long abspos = db->ecoli()->rel_2_abs(0);
255 paintPosAnnotation(device,
SEC_GC_ECOLI,
size_t(abspos),
"1",
true,
true);
264 void SEC_root::paintHelixNumbers(
AW_device *device) {
267 SEC_helix& helix =
static_cast<SEC_helix&
>(*elem);
270 SEC_helix_strand *strand = helix.strandToRoot()->is3end() ? helix.strandToRoot() : helix.strandToOutside();
272 int absPos = strand->startAttachAbspos();
273 const char *helixNr = helixNrAt(absPos);
276 if (helix.standardSize() == 0) {
278 strand->startAttachAbspos(), helixNr,
true,
true);
282 const Position& end = strand->endAttachPoint();
287 helixCenter, start, end,
289 displayParams.distance_between_strands,
290 helixNr,
false,
true,
true);
298 #if defined(PAINT_ABSOLUTE_POSITION)
299 void SEC_root::showSomeAbsolutePositions(
AW_device *device) {
308 PosMap::const_iterator end = drawnPositions->end();
309 for (PosMap::const_iterator pos = drawnPositions->begin(); pos != end; ++pos) {
310 if (showInside.contains(pos->second)) {
316 #endif // PAINT_ABSOLUTE_POSITION
319 drawnPositions->announce(base_pos, draw_pos);
323 drawnPositions->
clear();
326 void SEC_root::delete_announced_positions() {
327 delete drawnPositions;
328 drawnPositions =
NULp;
335 void SEC_helix_strand::paint_constraints(
AW_device *device) {
336 double minS = helix_info->minSize();
337 double maxS = helix_info->maxSize();
339 if (minS>0 || maxS>0) {
340 const Position& startP = startAttachPoint();
341 const Position& endP = endAttachPoint();
343 bool drawMidLine = minS>0 && maxS>0;
344 Position minP = startP +
Vector(startP, endP) * (drawMidLine ? minS/maxS : 0.5);
346 AW_click_cd cd(device,
self(), startAttachAbspos());
349 get_root()->display_params().distance_between_strands*2,
351 drawMidLine,
true,
true);
355 void SEC_loop::paint_constraints(
AW_device *device) {
356 int abspos = get_fixpoint_strand()->startAttachAbspos();
358 double minS = minSize();
359 double maxS = maxSize();
361 if (minS>0 || maxS>0) {
374 void SEC_root::cacheBackgroundColor() {
378 int len = db->length();
383 const char *bg_sai = displayParams.display_sai ? host().get_SAI_background(start, end) :
NULp;
384 const char *bg_search = displayParams.display_search ? host().get_search_background(start, end) :
NULp;
388 for (
int i = start; i <= end; ++i) {
389 bg_color[i] = bg_search[i] ? bg_search[i] : bg_sai[i];
392 else memcpy(bg_color, bg_sai, len);
395 if (bg_search) memcpy(bg_color, bg_search, len);
396 else memset(bg_color, 0, len);
411 if (color1 >= 0 || color2 >= 0 || displayParams.show_strSkeleton) {
412 const double& radius1 = get_char_radius(gc1);
413 const double& radius2 = get_char_radius(gc2);
423 if (color1 == color2 && color1 >= 0) {
425 device->
line(color1, p1, p2);
428 if (displayParams.show_strSkeleton) {
433 if (displayParams.hide_bases) {
438 double vlen = v12.
length();
443 const double CORR = skelThickWorld;
445 if ((radius1+radius2+CORR) < vlen) {
446 s1 = p1 + v12*((radius1+CORR/2)/vlen);
447 s2 = p2 - v12*((radius2+CORR/2)/vlen);
455 if (displayParams.show_debug) { s1 = p1; s2 = p2; }
457 device->
line(skel_gc, s1, s2);
464 int searchColor = getBackgroundColor(clickedPos);
475 "Signature (region)",
476 "Signature (global)",
483 aw_message(
"Please click on a search result");
491 if (base1 && base2) {
492 char e4_symbol = helix->get_symbol(base1, base2);
495 paint_symbol(device,
SEC_GC_BONDS, symbol, p1, p2, toNextBase, char_radius);
500 void SEC_bond_def::paint_symbol(
AW_device *device,
int GC,
char bondChar,
const Position& p1,
const Position& p2,
const Vector& toNextBase,
const double& char_radius)
const {
502 double oppoDist = v12.length();
503 double bondLen = oppoDist-2*char_radius;
505 if (bondLen <= 0.0)
return;
507 Vector pb = v12*(char_radius/oppoDist);
514 Vector aside = toNextBase;
517 double aside_len = aside.
length();
519 if (max_aside_len<aside_len) {
520 aside *= max_aside_len/aside_len;
527 device->
line(GC, b1, b2);
532 device->
line(GC, b1+aside, b2+aside);
533 device->
line(GC, b1-aside, b2-aside);
535 if (bondChar ==
'#') {
536 Vector outside = v12*(bondLen/oppoDist/4);
542 device->
line(GC, c1-aside, c1+aside);
543 device->
line(GC, c2-aside, c2+aside);
548 double radius = aside.
length();
550 double maxRadius = bondLen/4;
551 if (maxRadius<radius) radius = maxRadius;
554 Vector outside = v12*(radius/oppoDist);
561 Angle angle(outside);
562 int deg =
AW_INT(angle.degrees());
564 const int INSIDE = 2;
565 const int OUTSIDE = 15;
567 Vector vRadius(radius, radius);
575 device->
line(GC, center-aside, center+aside);
576 if (2*aside.
length() < bondLen) {
578 device->
line(GC, center-aside, center+aside);
581 device->
line(GC, b1, b2);
587 double radius = aside.
length();
588 if (bondChar ==
'o') radius *= 2;
595 sprintf(buf,
"'%c'", bondChar);
598 if (bondLen>4*char_radius) {
601 device->
line(GC, b1, c1);
602 device->
line(GC, b2, c2);
621 void SEC_helix_strand::paint_strands(
AW_device *device,
const Vector& strand_vec,
const double& strand_len) {
623 static int allocated = 0;
625 const SEC_region* Region[2] = { get_region(), other_strand->get_region() };
628 sec_assert(Region[1]->get_base_count() == base_count);
634 if (allocated<base_count) {
637 allocated = base_count;
643 double base_dist = base_count>1 ? strand_len / (base_count-1) : 1;
644 Vector vnext = strand_vec * base_dist;
650 int idx[2] = { 0, base_count-1 };
651 Position pos[2] = { leftAttach, rightAttach };
654 toNonBind[0] = -toNonBind[1];
656 for (
int strand = 0; strand<2; ++strand) {
659 curr->
drawn[strand] = (curr->
abs[strand] >= 0);
662 for (
int dIdx = 1; ; ++dIdx) {
666 int oneAbs = curr->
drawn[0] ? curr->
abs[0] : curr->
abs[1];
670 for (
int strand = 0; strand<2; ++strand) {
672 curr->
realpos[strand] = pos[strand];
673 curr->
drawn[strand] =
true;
676 curr->
realpos[strand] = pos[strand]+toNonBind[strand];
682 if (dIdx >= base_count)
break;
690 for (
int strand = 0; strand<2; ++strand) {
691 pos[strand] += vnext;
694 curr->
drawn[strand] = (curr->
abs[strand] >= 0);
706 for (
int pos = 1; pos<base_count; ++pos) {
708 for (
int strand = 0; strand<2; ++strand) {
709 if (curr->
drawn[strand]) {
713 ?
max(prev->
abs[strand], curr->
abs[strand])
714 :
min(prev->
abs[strand], curr->
abs[strand]);
727 char baseBuf[20] =
"x";
728 for (
int pos = 0; pos<base_count; ++pos) {
730 char base[2] = { 0, 0 };
732 int gc = pair2helixGC[curr->
isPair];
735 for (
int strand = 0; strand<2; ++strand) {
736 if (curr->
drawn[strand]) {
737 int abs = curr->
abs[strand];
742 base[strand] = db->
baseAt(abs);
746 baseBuf[0] = base[strand];
747 Position base_pos = realPos + center_char;
750 if (disp.show_debug) device->
line(gc, realPos, base_pos);
768 void SEC_helix_strand::paint(
AW_device *device) {
771 Vector strand_vec(rightAttach, other_strand->leftAttach);
772 double strand_len = strand_vec.
length();
781 other_strand->origin_loop->paint(device);
782 paint_strands(device, strand_vec, strand_len);
791 strandArrow =
LineVector(get_fixpoint(), strand_vec);
794 Vector fix2arrowStart(get_fixpoint(), leftAttachPoint());
795 fix2arrowStart.rotate90deg();
796 strandArrow =
LineVector(get_fixpoint()-fix2arrowStart, 2*fix2arrowStart);
799 AW_click_cd cd(device, get_helix()->
self(), startAttachAbspos());
813 if (disp.show_debug) paintStrandDebugInfo(device,
SEC_GC_HELIX, other_strand);
823 void SEC_segment::paint(
AW_device *device, SEC_helix_strand *previous_strand_pointer) {
824 int base_count = get_region()->get_base_count();
826 const Position& startP = previous_strand_pointer->rightAttachPoint();
827 const Position& endP = next_helix_strand->leftAttachPoint();
835 Vector seg_start_radius(center1, startP);
836 radius1 = seg_start_radius.length();
837 current = seg_start_radius;
839 Vector seg_end_radius(center2, endP);
840 radius2 = seg_end_radius.length();
841 end = seg_end_radius;
844 int steps = base_count+1;
846 double step = ((end-current)/steps).radian();
849 if ((alpha - (step*steps)) >
M_PI) {
850 step += (2*
M_PI)/steps;
853 double radStep = (radius2-radius1)/steps;
855 Vector cstep(center1, center2);
862 if (disp.show_debug) {
863 paintStrandDebugInfo(device,
SEC_GC_LOOP, previous_strand_pointer);
865 int startAbsPos = previous_strand_pointer->rightAttachAbspos();
866 int endAbsPos = next_helix_strand->leftAttachAbspos();
873 cd.set_cd2(endAbsPos);
874 paintDebugInfo(device,
SEC_GC_LOOP, center2,
"SC2");
879 char baseBuf[5] =
"?";
881 int abs = previous_strand_pointer->rightAttachAbspos();
887 double currRadius = radius1;
889 Angle step_angle(step);
891 for (
int i = -1; i<base_count; i++) {
892 current += step_angle;
894 currRadius += radStep;
899 if (i == (base_count-1)) {
900 nextAbs = next_helix_strand->leftAttachAbspos();
902 nextAbs = next_helix_strand->getNextAbspos();
907 nextAbs = get_region()->getBasePos(i+1);
919 baseBuf[0] = abs>0 ? db->
baseAt(abs) :
'?';
921 Position base_pos = pos + center_char;
943 void SEC_loop::paint(
AW_device *device) {
945 seg->paint(device, seg->get_previous_strand());
948 if (strand->isRootsideFixpoint()) strand->paint(device);
954 SEC_helix_strand *fixpoint_strand = get_fixpoint_strand();
955 int abspos = fixpoint_strand->startAttachAbspos();
961 paintStrandDebugInfo(device,
SEC_GC_CURSOR, fixpoint_strand);
972 SEC_loop *rootLoop = get_root_loop();
974 clear_announced_positions();
976 const BI_helix *helix = get_helixDef();
984 font_group.unregisterAll();
986 font_group.registerFont(device, gc,
"ACGTU-.");
987 center_char[gc] = device->
rtransform(
Vector(-0.5*font_group.get_width(gc), 0.5*font_group.get_ascent(gc)));
993 int maxSize =
hypotenuse(font_group.get_width(gc), font_group.get_ascent(gc));
994 bg_linewidth[gc] = maxSize*0.75;
1000 skelThickWorld = device->
rtransform_size(displayParams.skeleton_thickness);
1001 bondThickWorld = device->
rtransform_size(displayParams.bond_thickness);
1003 cacheBackgroundColor();
1012 const Position& loop_center = rootLoop->get_center();
1017 Vector center2corner(-1, -1);
1018 center2corner.set_length(rootLoop->drawnSize()*0.33);
1020 Position upperleft_corner = loop_center+center2corner;
1021 Vector diagonal = -2*center2corner;
1029 #if defined(CHECK_INTEGRITY)
1030 check_integrity(CHECK_ALL);
1031 #endif // CHECK_INTEGRITY
1033 rootLoop->paint(device);
1036 if (displayParams.show_ecoli_pos) paintEcoliPositions(device);
1038 if (displayParams.show_helixNrs) {
1039 paintHelixNumbers(device);
1042 #if defined(PAINT_ABSOLUTE_POSITION)
1043 if (displayParams.show_debug) showSomeAbsolutePositions(device);
1044 #endif // PAINT_ABSOLUTE_POSITION
1047 if (!drawnPositions->empty() &&
1054 if (displayParams.edit_rightward) {
1055 pos1 = drawnPositions->drawn_before(cursorAbsPos, &abs1);
1056 pos2 = drawnPositions->drawn_after(cursorAbsPos-1, &abs2);
1060 pos1 = drawnPositions->drawn_before(cursorAbsPos+1, &abs1);
1061 pos2 = drawnPositions->drawn_after(cursorAbsPos, &abs2);
1066 #if defined(DEBUG) && 1
1076 double drawn_length = v_drawn.
length();
1080 double cursor_size = 1.3 *
max(font_group.get_max_width(), font_group.get_max_ascent());
1081 double stretch = cursor_size*0.5/drawn_length;
1089 set_last_drawed_cursor_position(cursor);
1098 switch (displayParams.show_curpos) {
1105 disp_pos = host().get_base_position(curAbs+1);
1117 if (cursor_gc >= 0) {
1118 paintPosAnnotation(device, cursor_gc, curAbs,
GBS_global_string(
"%u", disp_pos),
true,
true);
1130 int incr[2] = { 1, -1 };
1132 int *new_absarr[2] = {
NULp,
NULp };
1135 for (
int r = 0; r<2; ++r) {
1136 absarr[r] = reg[r]->abspos_array;
1139 for (
int write = 0; write < 2; ++write) {
1140 int curr[2] = { 0, reg[1]->baseCount-1 };
1141 int last[2] = { reg[0]->baseCount-1, 0 };
1142 int newp[2] = { 0, 0 };
1144 while (curr[0] <= last[0] && curr[1] >= last[1]) {
1148 for (
int r = 0; r<2; ++r) {
1149 abs[r] = absarr[r][curr[r]];
1150 ispair[r] = abs[r] >= 0 && helix->
is_pairpos(abs[r]);
1153 if (ispair[0] && ispair[1]) {
1162 for (
int r = 0; r<2; ++r) {
1163 while (newp[r]<newp[1-r]) {
1165 new_absarr[r][newp[r]] = -1;
1173 for (
int r = 0; r<2; ++r) {
1174 if (write) new_absarr[r][newp[r]] = abs[r];
1175 newp[r]++; curr[r] += incr[r];
1179 bool collected =
false;
1180 for (
int r = 0; r<2; ++r) {
1181 if (abs[r] >= 0 && !ispair[r]) {
1183 new_absarr[r][newp[r]] = abs[r];
1185 newp[r]++; curr[r] += incr[r];
1190 for (
int r = 0; r<2; ++r) {
1191 if (abs[r]<0) curr[r] += incr[r];
1199 for (
int r = 0; r<2; ++r) {
1203 int *arr = new_absarr[1];
1204 for (
int p = 0; p<p2; ++p, --p2) {
1205 swap(arr[p], arr[p2]);
1209 delete [] reg[r]->abspos_array;
1210 reg[r]->abspos_array = new_absarr[r];
1211 #if defined(ASSERTION_USED)
1212 reg[r]->abspos_array_size = newp[r];
1213 #endif // ASSERTION_USED
1214 reg[r]->set_base_count(newp[r]);
1218 new_absarr[r] =
new int[newp[r]];
bool is_pairpos(size_t pos) const
int get_base_count() const
static PaintData paintData
AW::Vector transform(const AW::Vector &vec) const
void align_helix_strands(SEC_root *root, SEC_region *other_region)
void paint(AW_device *device, char base1, char base2, const Position &p1, const Position &p2, const Vector &toNextBase, const double &char_radius) const
const AW_bitset AW_PRINTER_EXT
const AW_bitset AW_SCREEN
double centroid(const double &val1, const double &val2)
int rel_2_abs(int rel) const
const AW_screen_area & get_area_size() const
Position centroid() const
const SEC_db_interface * get_db() const
CONSTEXPR_INLINE unsigned char safeCharIndex(char c)
const double & get_char_radius(int gc) const
void set_line_attributes(int gc, short width, AW_linestyle style)
void paintSearchPatternStrings(AW_device *device, int clickedPos, AW_pos xPos, AW_pos yPos)
int getBackgroundColor(int abspos)
virtual void clear_part(const AW::Rectangle &rect, AW_bitset filteri)
const BI_helix * get_helixDef() const
const char * GBS_global_string(const char *templat,...)
const SEC_displayParams & display_params() const
size_t opposite_position(size_t pos) const
SEC_BASE_TYPE get_show_constraints()
const Vector & normal() const
Vector & set_length(double new_length)
SEC_structure_toggler * structure() const
const AW_bitset AW_ALL_DEVICES_SCALED
static HelixNrInfo * start
int get_linePropertyGC(int gc1, int gc2)
const AW_bitset AW_PRINTER
void paintBackgroundColor(AW_device *device, SEC_bgpaint_mode mode, const Position &p1, int color1, int gc1, const Position &p2, int color2, int gc2, int skel_gc)
double rtransform_size(const double &size) const
AW_bitset get_filter() const
int abs_2_rel(int abs) const
const Vector & get_center_char_vector(int gc)
int get_string_size(int gc, long textlen) const
TYPE * ARB_alloc(size_t nelem)
bool circle(int gc, AW::FillStyle filled, const AW::Position ¢er, const AW::Vector &radius, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
const double & ypos() const
double distance_between_strands
double hypotenuse(double cath1, double cath2)
static GB_ERROR get_error()
bool line(int gc, const AW::LineVector &Line, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
AW::Vector rtransform(const AW::Vector &vec) const
static void error(const char *msg)
const Position & upper_left_corner() const
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
double get_bondThickWorld() const
ASSERTING_CONSTEXPR_INLINE int info2bio(int infopos)
void clear_announced_positions()
const char * helixNr(size_t pos) const
CONSTEXPR_INLINE bool valid(SpeciesCreationMode m)
void paintAnnotation(AW_device *device, int gc, const Position &annotate, const Position &left, const Position &right, double noteDistance, const char *text, bool lineToAnnotated, bool linesToLeftRight, bool boxText)
const Vector & diagonal() const
const Vector & line_vector() const
GB_ERROR paint(AW_device *device)
ASSERTING_CONSTEXPR_INLINE int bio2info(int biopos)
const double & length() const
BI_ecoli_ref * ecoli() const
void announce_base_position(int base_pos, const Position &draw_pos)
int getBasePos(int basenr) const
void paintPosAnnotation(AW_device *device, int gc, size_t absPos, const char *text, bool lineToBase, bool boxText)
const AW_bitset AW_ALL_DEVICES_UNSCALED
void aw_message(const char *msg)
char baseAt(size_t abspos) const
int convert_BackgroundGC(int edit4_gc) const
bool arc(int gc, AW::FillStyle filled, AW_pos x0, AW_pos y0, AW_pos xradius, AW_pos yradius, int start_degrees, int arc_degrees, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
const double & xpos() const
bool is_pairpos(int abspos) const
SEC_bond_def * bonds() const
bool box(int gc, AW::FillStyle filled, const AW::Rectangle &rect, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
bool valid_cb_params(AW_CL cd1, AW_CL cd2)
bool text(int gc, const SizedCstr &cstr, const AW::Position &pos, AW_pos alignment=0.0, AW_bitset filteri=AW_ALL_DEVICES_UNSCALED)
const AW_click_cd * get_click_cd() const
GB_ERROR mid(GBL_command_arguments *args, int start_index)