From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Yuan Fu Newsgroups: gmane.emacs.devel Subject: Re: Line wrap reconsidered Date: Thu, 18 Jun 2020 17:46:53 -0400 Message-ID: <0B30F8C8-9B8F-4FCB-B9FB-1B5A0E993CDB@gmail.com> References: <92FF4412-04FB-4521-B6CE-52B08526E4E5@gmail.com> <878shfsq35.fsf@gnus.org> <83imgivjak.fsf@gnu.org> <83lfletr03.fsf@gnu.org> <4895C6EE-5E1F-44BF-93C1-CC5F7C096F73@gmail.com> <9766BA3D-B8F9-456B-9F59-60D21B86E390@gmail.com> <83sgfls2ul.fsf@gnu.org> <83v9kgq6jy.fsf@gnu.org> <5E75D1E2-8BFF-45DA-A643-40DBD5784508@gmail.com> <83r1v3qlel.fsf@gnu.org> <83blm6lzj3.fsf@gnu.org> <83pnakj8fs.fsf@gnu.org> <83k10sj60l.fsf@gnu.org> Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_93FF080F-E9B5-467E-A6E4-905228E3F3B7" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="104604"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Lars Ingebrigtsen , emacs-devel To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Jun 18 23:48:20 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jm2OR-000RA3-FA for ged-emacs-devel@m.gmane-mx.org; Thu, 18 Jun 2020 23:48:19 +0200 Original-Received: from localhost ([::1]:60594 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jm2OQ-0007JC-Hv for ged-emacs-devel@m.gmane-mx.org; Thu, 18 Jun 2020 17:48:18 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:46884) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jm2N9-0006qa-GU for emacs-devel@gnu.org; Thu, 18 Jun 2020 17:46:59 -0400 Original-Received: from mail-qt1-x832.google.com ([2607:f8b0:4864:20::832]:37691) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jm2N7-0000yS-NE; Thu, 18 Jun 2020 17:46:59 -0400 Original-Received: by mail-qt1-x832.google.com with SMTP id d27so5738372qtg.4; Thu, 18 Jun 2020 14:46:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=O6qhUYT/YdnZf94Sn52w2TQjMKJO6RWJua439Q8xMFc=; b=TnF2+X8Eyw5vK+lVbrbYCLjWoCsdoSb3CqFzzWAi6ye9g4Aa0PnKwMb7RzdNsZ3Ln/ MyJV/oSlObwkM6d1q2DKZqmBZh+Dp2pnmThMXBW05IVxlGSh/7L97twftsAQzhkRWTnJ XjOh5xKvffVN3cuP6+FfWIrO1CwpKGMsYa1rpQOQ4/FgaBx7SFukwSgvX0NkpIMy0OYf Eg0EhwLPzC4TCjw1y/u661jvkc1K69K6ZHRIcIoP39R/yh2DAC5XEu5GSfzLqWxZDNvq nsKjxMHGHCKvW+Bmo1t1L9iG595hnN9QJ2Tuylo3XdEAZLaiFK6d/MRQUlibZt1IvkQg 15WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=O6qhUYT/YdnZf94Sn52w2TQjMKJO6RWJua439Q8xMFc=; b=AOQDTXGrLyM5m4gJTubwJWILnte9MjUzU7Mw8QH0kkxgYOtm8UUh2VDUdvBaZw0glF ekkxpHq04nONhB8uxKIUql8tyTLMi9XymkmkIGXQ1SY6qMF8lX/QL3eZRiurwPe1fk5G bYYcCJx8nAZ36ldkH1TE8Hfvmw2GsVdC2M89dUdxJhjbQy5NfGCLzACBYWWuBPjsWAMQ qOkgP4rcFVhn3wcvW4Q6vAV1XlGJ+BwkeG4cPsJNwHEvCrhd/wMVS+TLXH9LKYy440YD zXosr+Wp0XthHoPeE+Rl3Ml5kbsRcdQB2AzHPb8kTcMAQaScMHxD371azIjTF8aKabNk JgJw== X-Gm-Message-State: AOAM530YrlWlcSdjYNIn3artH1XBLJO1CSzS5Dk742a9alXTrT12o4in nEmZQ0YAYYOMmYz1CpyheRq8cKVuMKUadw== X-Google-Smtp-Source: ABdhPJyxxMBg2TJZTJIgvIezm/vILm4580ChZuuO9w0EtZ/lLfHsJiMHel6vGIb281el/khtPYzKfg== X-Received: by 2002:ac8:724b:: with SMTP id l11mr274459qtp.255.1592516815658; Thu, 18 Jun 2020 14:46:55 -0700 (PDT) Original-Received: from ?IPv6:2601:98a:4200:9210:f9:e10f:5b2e:903c? ([2601:98a:4200:9210:f9:e10f:5b2e:903c]) by smtp.gmail.com with ESMTPSA id p185sm4215006qkd.128.2020.06.18.14.46.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Jun 2020 14:46:54 -0700 (PDT) In-Reply-To: <83k10sj60l.fsf@gnu.org> X-Mailer: Apple Mail (2.3608.80.23.2.2) Received-SPF: pass client-ip=2607:f8b0:4864:20::832; envelope-from=casouri@gmail.com; helo=mail-qt1-x832.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:252327 Archived-At: --Apple-Mail=_93FF080F-E9B5-467E-A6E4-905228E3F3B7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi Eli, Sorry for the delay. >=20 > The iterator thinks the characters are displayed from left to right, > so it does its calculations as usual. The order reversal happens > because each new glyph is prepended to the previous glyphs, not > appended as in the LTR case (but the iterator doesn't know that). So > the white space you see at the left side is actually computed and > added at the end, when all the other characters are already in the > glyph row and their width is known. After reading your reply I went back and scratched my head on why my = code doesn=E2=80=99t work, because based on your information my code = logic is correct. Turns out it=E2=80=99s merely because I didn=E2=80=99t = handle enough cases for it->what (I only handled when it->what =3D=3D = IT_CHARACTER). I updated my code to handle other cases and it now works = in bidi! I have to do another change for kinsoku.el to work right in bidi. = Kinsoku.el defined NOT_AT_BOL and NOT_AT_EOL categories. These = categories are flipped in bidi paragraphs: what was EOL becomes BOL and = vice versa. So I flipped them in my predicate function depending on = it->bidi_p. Now the word wrap and kinsoki works in both normal and bidi paragraph. P.S., I think I fixed all the indentation with tabs. Yuan --Apple-Mail=_93FF080F-E9B5-467E-A6E4-905228E3F3B7 Content-Disposition: attachment; filename=word-wrap.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="word-wrap.patch" Content-Transfer-Encoding: quoted-printable =46rom=20ab82e5a8101b9fb8302e6291be48f3153f4a0020=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20Yuan=20Fu=20=0ADate:=20Tue,=20= 26=20May=202020=2022:47:27=20-0400=0ASubject:=20[PATCH]=20checkpoint=0A=0A= ---=0A=20src/xdisp.c=20|=20149=20= ++++++++++++++++++++++++++++++++++++++--------------=0A=201=20file=20= changed,=20110=20insertions(+),=2039=20deletions(-)=0A=0Adiff=20--git=20= a/src/xdisp.c=20b/src/xdisp.c=0Aindex=20cf15f579b5..8d9bb64258=20100644=0A= ---=20a/src/xdisp.c=0A+++=20b/src/xdisp.c=0A@@=20-447,6=20+447,7=20@@=20= Copyright=20(C)=201985-1988,=201993-1995,=201997-2020=20Free=20Software=20= Foundation,=0A=20#include=20"termchar.h"=0A=20#include=20"dispextern.h"=0A= =20#include=20"character.h"=0A+#include=20"category.h"=0A=20#include=20= "buffer.h"=0A=20#include=20"charset.h"=0A=20#include=20"indent.h"=0A@@=20= -508,6=20+509,57=20@@=20#define=20IT_DISPLAYING_WHITESPACE(it)=09=09=09=09= =09\=0A=20=09=20=20=20&&=20(*BYTE_POS_ADDR=20(IT_BYTEPOS=20(*it))=20=3D=3D= =20'=20'=09=09=09\=0A=20=09=20=20=20=20=20=20=20||=20*BYTE_POS_ADDR=20= (IT_BYTEPOS=20(*it))=20=3D=3D=20'\t'))))=0A=20=0A+/*=20These=20are=20the=20= category=20sets=20we=20use.=20=20*/=0A+#define=20NOT_AT_EOL=2060=20/*=20= <=20*/=0A+#define=20NOT_AT_BOL=2062=20/*=20>=20*/=0A+#define=20= LINE_BREAKABLE=20124=20/*=20|=20*/=0A+=0A+#define=20= IT_CHAR_HAS_CATEGORY(it,=20cat)=09=09=09=09=09\=0A+=20=20((it->what=20=3D=3D= =20IT_CHARACTER=20&&=20CHAR_HAS_CATEGORY=20(it->c,=20cat))=09\=0A+=20=20= ||=20(STRINGP=20(it->string)=09=09=09=09=09=09\=0A+=20=20=20=20=20=20&&=20= CHAR_HAS_CATEGORY(SREF=20(it->string,=20IT_STRING_BYTEPOS=20(*it)),=20= cat))=20\=0A+=20=20||=20(it->s=09=09=09=09=09=09=09=09\=0A+=20=20=20=20=20= =20&&=20CHAR_HAS_CATEGORY(it->s[IT_BYTEPOS=20(*it)],=20cat))=09=09\=0A+=20= =20||=20(IT_BYTEPOS=20(*it)=20<=20ZV_BYTE=09=09=09=09=09\=0A+=20=20=20=20= =20=20&&=20CHAR_HAS_CATEGORY(*BYTE_POS_ADDR=20(IT_BYTEPOS=20(*it)),=20= cat)))=20=20=20=20\=0A+=0A+/*=20Return=20true=20if=20the=20current=20= character=20allows=20wrapping=20before=20it.=20=20=20*/=0A+static=20bool=20= char_can_wrap_before=20(struct=20it=20*it)=0A+{=0A+=20=20/*=20You=20= cannot=20wrap=20before=20a=20space=20or=20tab=20because=0A+=20=20=20=20=20= that=20way=20you'll=20have=20space=20and=20tab=20at=20the=20beginning=20= of=20next=0A+=20=20=20=20=20line.=20=20*/=0A+=20=20/*=20In=20bidi=20= context,=20EOL=20and=20BOL=20are=20flipped.=20=20*/=0A+=20=20if=20= (it->bidi_p)=0A+=20=20=20=20return=20(!IT_DISPLAYING_WHITESPACE=20(it)=0A= +=09=20=20=20=20&&=20(!IT_CHAR_HAS_CATEGORY=20(it,=20NOT_AT_EOL)));=0A+=20= =20=20=20else=0A+=20=20=20=20=20=20return=20(!IT_DISPLAYING_WHITESPACE=20= (it)=0A+=09=20=20=20=20=20=20&&=20(!IT_CHAR_HAS_CATEGORY=20(it,=20= NOT_AT_BOL)));=0A+}=0A+=0A+/*=20Return=20true=20if=20the=20current=20= character=20allows=20wrapping=20after=20it.=20=20=20*/=0A+static=20bool=20= char_can_wrap_after=20(struct=20it=20*it)=0A+{=0A+=20=20/*=20We=20used=20= to=20only=20check=20for=20whitespace=20characters=20for=20wrapping,=0A+=20= =20=20=20=20hence=20this=20macro.=20=20Obviously=20you=20can=20wrap=20= after=20a=20space=20or=0A+=20=20=20=20=20tab.=20=20*/=0A+=20=20if=20= (it->bidi_p)=0A+=20=20=20=20return=20(IT_DISPLAYING_WHITESPACE=20(it)=0A= +=09=20=20=20=20||=20(IT_CHAR_HAS_CATEGORY=20(it,=20LINE_BREAKABLE)=0A+=09= =09&&=20!IT_CHAR_HAS_CATEGORY=20(it,=20NOT_AT_BOL)));=0A+=20=20=20=20= else=0A+=20=20=20=20=20=20return=20(IT_DISPLAYING_WHITESPACE=20(it)=0A+=09= =20=20=20=20=20=20||=20(IT_CHAR_HAS_CATEGORY=20(it,=20LINE_BREAKABLE)=0A= +=09=09=20=20&&=20!IT_CHAR_HAS_CATEGORY=20(it,=20NOT_AT_EOL)));=0A+}=0A+=0A= +#undef=20IT_DISPLAYING_WHITESPACE=0A+#undef=20IT_CHAR_HAS_CATEGORY=0A= +#undef=20NOT_AT_BOL=0A+#undef=20NOT_AT_BOL=0A+#undef=20LINE_BREAKABLE=0A= +=0A=20/*=20If=20all=20the=20conditions=20needed=20to=20print=20the=20= fill=20column=20indicator=20are=0A=20=20=20=20met,=20return=20the=20= (nonnegative)=20column=20number,=20else=20return=20a=20negative=0A=20=20=20= =20value.=20=20*/=0A@@=20-9185,13=20+9237,14=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09{=0A=20=09=20=20if=20= (it->line_wrap=20=3D=3D=20WORD_WRAP=20&&=20it->area=20=3D=3D=20= TEXT_AREA)=0A=20=09=20=20=20=20{=0A-=09=20=20=20=20=20=20if=20= (IT_DISPLAYING_WHITESPACE=20(it))=0A-=09=09may_wrap=20=3D=20true;=0A-=09=20= =20=20=20=20=20else=20if=20(may_wrap)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20/*=20Can=20we=20wrap=20here?=20*/=0A+=09=20=20=20=20=20=20if=20= (may_wrap=20&&=20char_can_wrap_before(it))=0A=20=09=09{=0A=20=09=09=20=20= /*=20We=20have=20reached=20a=20glyph=20that=20follows=20one=20or=20more=0A= -=09=09=20=20=20=20=20whitespace=20characters.=20=20If=20the=20position=20= is=0A-=09=09=20=20=20=20=20already=20found,=20we=20are=20done.=20=20*/=0A= +=09=09=20=20=20=20=20whitespace=20characters=20or=20a=20character=20= that=20allows=0A+=09=09=20=20=20=20=20wrapping=20after=20it.=20=20If=20= this=20character=20allows=0A+=09=09=20=20=20=20=20wrapping=20before=20= it,=20save=20this=20position=20as=20a=0A+=09=09=20=20=20=20=20wrapping=20= point.=20=20*/=0A=20=09=09=20=20if=20(atpos_it.sp=20>=3D=200)=0A=20=09=09= =20=20=20=20{=0A=20=09=09=20=20=20=20=20=20RESTORE_IT=20(it,=20= &atpos_it,=20atpos_data);=0A@@=20-9206,8=20+9259,17=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09=09=20=20=20=20}=0A=20=09= =09=20=20/*=20Otherwise,=20we=20can=20wrap=20here.=20=20*/=0A=20=09=09=20= =20SAVE_IT=20(wrap_it,=20*it,=20wrap_data);=0A-=09=09=20=20may_wrap=20=3D=20= false;=0A=20=09=09}=0A+=09=20=20=20=20=20=20/*=20This=20has=20to=20run=20= after=20the=20previous=20block=20because=20the=0A+=09=09=20previous=20= block=20consumes=20`may_wrap'=20and=20this=20block=0A+=09=09=20sets=20= it,=20but=20the=20value=20set=20by=20this=20block=20is=20intended=0A+=09=09= =20for=20the=20_next_=20character/iteration.=20=20*/=0A+=09=20=20=20=20=20= =20if=20(char_can_wrap_after=20(it))=0A+=09=09/*=20may_wrap=20basically=20= means=20"previous=20char=20allows=0A+=09=09=20=20=20wrapping=20after=20= it".=20=20*/=0A+=09=09may_wrap=20=3D=20true;=0A+=09=20=20=20=20=20=20= else=0A+=09=09may_wrap=20=3D=20false;=0A=20=09=20=20=20=20}=0A=20=09}=0A=20= =0A@@=20-9335,10=20+9397,10=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09=09=09=20=20=20=20{=0A=20= =09=09=09=20=20=20=20=20=20bool=20can_wrap=20=3D=20true;=0A=20=0A-=09=09=09= =20=20=20=20=20=20/*=20If=20we=20are=20at=20a=20whitespace=20character=0A= -=09=09=09=09=20that=20barely=20fits=20on=20this=20screen=20line,=0A-=09=09= =09=09=20but=20the=20next=20character=20is=20also=0A-=09=09=09=09=20= whitespace,=20we=20cannot=20wrap=20here.=20=20*/=0A+=09=09=09=20=20=20=20= =20=20/*=20If=20the=20previous=20character=20says=20we=20can=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20wrap=20after=20it,=20but=20the=20current=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20character=20says=20we=20can't=20wrap=20before=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20it,=20then=20we=20can't=20wrap=20here.=20=20*/=0A=20=09=09=09=20= =20=20=20=20=20if=20(it->line_wrap=20=3D=3D=20WORD_WRAP=0A=20=09=09=09=09= =20=20&&=20wrap_it.sp=20>=3D=200=0A=20=09=09=09=09=20=20&&=20may_wrap=0A= @@=20-9350,7=20+9412,7=20@@=20#define=20IT_RESET_X_ASCENT_DESCENT(IT)=09=09= =09\=0A=20=09=09=09=09=20=20SAVE_IT=20(tem_it,=20*it,=20tem_data);=0A=20=09= =09=09=09=20=20set_iterator_to_next=20(it,=20true);=0A=20=09=09=09=09=20=20= if=20(get_next_display_element=20(it)=0A-=09=09=09=09=20=20=20=20=20=20= &&=20IT_DISPLAYING_WHITESPACE=20(it))=0A+=09=09=09=09=20=20=20=20=20=20= &&=20!char_can_wrap_before(it))=0A=20=09=09=09=09=20=20=20=20can_wrap=20= =3D=20false;=0A=20=09=09=09=09=20=20RESTORE_IT=20(it,=20&tem_it,=20= tem_data);=0A=20=09=09=09=09}=0A@@=20-9429,19=20+9491,18=20@@=20#define=20= IT_RESET_X_ASCENT_DESCENT(IT)=09=09=09\=0A=20=09=09=20=20else=0A=20=09=09= =20=20=20=20IT_RESET_X_ASCENT_DESCENT=20(it);=0A=20=0A-=09=09=20=20/*=20= If=20the=20screen=20line=20ends=20with=20whitespace,=20and=20we=0A-=09=09= =20=20=20=20=20are=20under=20word-wrap,=20don't=20use=20wrap_it:=20it=20= is=20no=0A-=09=09=20=20=20=20=20longer=20relevant,=20but=20we=20won't=20= have=20an=20opportunity=0A-=09=09=20=20=20=20=20to=20update=20it,=20= since=20we=20are=20done=20with=20this=20screen=0A-=09=09=20=20=20=20=20= line.=20=20*/=0A+=09=09=20=20/*=20If=20the=20screen=20line=20ends=20with=20= whitespace=20(or=0A+=09=09=20=20=20=20=20wrap-able=20character),=20and=20= we=20are=20under=20word-wrap,=0A+=09=09=20=20=20=20=20don't=20use=20= wrap_it:=20it=20is=20no=20longer=20relevant,=20but=0A+=09=09=20=20=20=20=20= we=20won't=20have=20an=20opportunity=20to=20update=20it,=20since=0A+=09=09= =20=20=20=20=20we=20are=20done=20with=20this=20screen=20line.=20=20*/=0A=20= =09=09=20=20if=20(may_wrap=20&&=20IT_OVERFLOW_NEWLINE_INTO_FRINGE=20(it)=0A= =20=09=09=20=20=20=20=20=20/*=20If=20the=20character=20after=20the=20one=20= which=20set=20the=0A-=09=09=09=20may_wrap=20flag=20is=20also=20= whitespace,=20we=20can't=0A-=09=09=09=20wrap=20here,=20since=20the=20= screen=20line=20cannot=20be=0A-=09=09=09=20wrapped=20in=20the=20middle=20= of=20whitespace.=0A-=09=09=09=20Therefore,=20wrap_it=20_is_=20relevant=20= in=20that=0A-=09=09=09=20case.=20=20*/=0A-=09=09=20=20=20=20=20=20&&=20= !(moved_forward=20&&=20IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=20= may_wrap=20flag=20says=20we=20can't=20wrap=20before=20it,=0A+=09=09=09=20= we=20can't=20wrap=20here.=20=20Therefore,=20wrap_it=0A+=09=09=09=20= (previously=20found=20wrap-point)=20_is_=20relevant=0A+=09=09=09=20in=20= that=20case.=20=20*/=0A+=09=09=20=20=20=20=20=20&&=20!(moved_forward=20= &&=20char_can_wrap_before(it)))=0A=20=09=09=20=20=20=20{=0A=20=09=09=20=20= =20=20=20=20/*=20If=20we've=20found=20TO_X,=20go=20back=20there,=20as=20= we=20now=0A=20=09=09=09=20know=20the=20last=20word=20fits=20on=20this=20= screen=20line.=20=20*/=0A@@=20-23292,9=20+23353,8=20@@=20#define=20= RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=0A=20=09=20=20if=20= (it->line_wrap=20=3D=3D=20WORD_WRAP=20&&=20it->area=20=3D=3D=20= TEXT_AREA)=0A=20=09=20=20=20=20{=0A-=09=20=20=20=20=20=20if=20= (IT_DISPLAYING_WHITESPACE=20(it))=0A-=09=09may_wrap=20=3D=20true;=0A-=09=20= =20=20=20=20=20else=20if=20(may_wrap)=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20/*=20Can=20we=20wrap=20here?=20*/=0A+=09=20=20=20=20=20=20if=20= (may_wrap=20&&=20char_can_wrap_before(it))=0A=20=09=09{=0A=20=09=09=20=20= SAVE_IT=20(wrap_it,=20*it,=20wrap_data);=0A=20=09=09=20=20wrap_x=20=3D=20= x;=0A@@=20-23308,9=20+23368,13=20@@=20#define=20RECORD_MAX_MIN_POS(IT)=09= =09=09=09=09\=0A=20=09=09=20=20wrap_row_min_bpos=20=3D=20min_bpos;=0A=20=09= =09=20=20wrap_row_max_pos=20=3D=20max_pos;=0A=20=09=09=20=20= wrap_row_max_bpos=20=3D=20max_bpos;=0A-=09=09=20=20may_wrap=20=3D=20= false;=0A=20=09=09}=0A-=09=20=20=20=20}=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20/*=20This=20has=20to=20run=20after=20the=20previous=20block.=20= =20*/=0A+=09=20=20=20=20=20=20if=20(char_can_wrap_after=20(it))=0A+=09=09= may_wrap=20=3D=20true;=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20else=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20may_wrap=20=3D=20false;=0A= +=20=20=20=20=20=20=20=20=20=20=20=20}=0A=20=09}=0A=20=0A=20=20=20=20=20=20= =20PRODUCE_GLYPHS=20(it);=0A@@=20-23433,14=20+23497,18=20@@=20#define=20= RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=09=09=09=20=20/*=20If=20= line-wrap=20is=20on,=20check=20if=20a=20previous=0A=20=09=09=09=20=20=20=20= =20wrap=20point=20was=20found.=20=20*/=0A=20=09=09=09=20=20if=20= (!IT_OVERFLOW_NEWLINE_INTO_FRINGE=20(it)=0A-=09=09=09=20=20=20=20=20=20= &&=20wrap_row_used=20>=200=0A+=09=09=09=20=20=20=20=20=20&&=20= wrap_row_used=20>=200=20/*=20Found.=20=20*/=0A=20=09=09=09=20=20=20=20=20= =20/*=20Even=20if=20there=20is=20a=20previous=20wrap=0A=20=09=09=09=09=20= point,=20continue=20the=20line=20here=20as=0A=20=09=09=09=09=20usual,=20= if=20(i)=20the=20previous=20character=0A-=09=09=09=09=20was=20a=20space=20= or=20tab=20AND=20(ii)=20the=0A-=09=09=09=09=20current=20character=20is=20= not.=20=20*/=0A-=09=09=09=20=20=20=20=20=20&&=20(!may_wrap=0A-=09=09=09=09= =20=20||=20IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=09=20allows=20= wrapping=20after=20it,=20AND=20(ii)=0A+=09=09=09=09=20the=20current=20= character=20allows=20wrapping=0A+=09=09=09=09=20before=20it.=20=20= Because=20this=20is=20a=20valid=0A+=09=09=09=09=20break=20point,=20we=20= can=20just=20continue=20to=0A+=09=09=09=09=20the=20next=20line=20at=20= here,=20there=20is=20no=0A+=09=09=09=09=20need=20to=20wrap=20early=20at=20= the=20previous=0A+=09=09=09=09=20wrap=20point.=20=20*/=0A+=09=09=09=20=20= =20=20=20=20&&=20(!may_wrap=20||=20!char_can_wrap_before(it)))=0A=20=09=09= =09=20=20=20=20goto=20back_to_wrap;=0A=20=0A=20=09=09=09=20=20/*=20= Record=20the=20maximum=20and=20minimum=20buffer=0A@@=20-23468,13=20= +23536,16=20@@=20#define=20RECORD_MAX_MIN_POS(IT)=09=09=09=09=09\=0A=20=09= =09=09=20=20=20=20=20=20/*=20If=20line-wrap=20is=20on,=20check=20if=20a=0A= =20=09=09=09=09=20previous=20wrap=20point=20was=20found.=20=20*/=0A=20=09= =09=09=20=20=20=20=20=20else=20if=20(wrap_row_used=20>=200=0A-=09=09=09=09= =20=20=20=20=20=20=20/*=20Even=20if=20there=20is=20a=20previous=20wrap=0A= -=09=09=09=09=09=20=20point,=20continue=20the=20line=20here=20as=0A-=09=09= =09=09=09=20=20usual,=20if=20(i)=20the=20previous=20character=0A-=09=09=09= =09=09=20=20was=20a=20space=20or=20tab=20AND=20(ii)=20the=0A-=09=09=09=09= =09=20=20current=20character=20is=20not.=20=20*/=0A-=09=09=09=09=20=20=20= =20=20=20=20&&=20(!may_wrap=0A-=09=09=09=09=09=20=20=20||=20= IT_DISPLAYING_WHITESPACE=20(it)))=0A+=09=09=09=09=20=20=20=20=20=20=20/*=20= Even=20if=20there=20is=20a=20previous=0A+=09=09=09=09=09=20=20wrap=20= point,=20continue=20the=0A+=09=09=09=09=09=20=20line=20here=20as=20= usual,=20if=20(i)=0A+=09=09=09=09=09=20=20the=20previous=20character=20= was=20a=0A+=09=09=09=09=09=20=20space=20or=20tab=20AND=20(ii)=20the=0A+=09= =09=09=09=09=20=20current=20character=20is=20not,=0A+=09=09=09=09=09=20=20= AND=20(iii)=20the=20current=0A+=09=09=09=09=09=20=20character=20allows=20= wrapping=0A+=09=09=09=09=09=20=20before=20it.=20=20*/=0A+=09=09=09=09=20=20= =20=20=20=20=20&&=20(!may_wrap=20||=20!char_can_wrap_before(it)))=0A=20=09= =09=09=09goto=20back_to_wrap;=0A=20=0A=20=09=09=09=20=20=20=20}=0A--=20=0A= 2.27.0=0A=0A= --Apple-Mail=_93FF080F-E9B5-467E-A6E4-905228E3F3B7--