<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Joe Ranieri &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/author/joe/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Wed, 15 Feb 2017 19:55:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.5</generator>
	<item>
		<title>Advanced Retina/HiDPI: BitmapForCaching and ScaleFactorChanged</title>
		<link>https://blog.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/</link>
					<comments>https://blog.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/#comments</comments>
		
		<dc:creator><![CDATA[Joe Ranieri]]></dc:creator>
		<pubDate>Thu, 07 Apr 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[HiDPi]]></category>
		<category><![CDATA[Retina]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/</guid>

					<description><![CDATA[The most direct way to support HiDPI for custom controls is to draw into the Graphics object passed into the Paint event. But you can also BitmapForCaching and ScaleFactorChanged]]></description>
										<content:encoded><![CDATA[<p>The most direct way to support HiDPI* for custom controls is to draw into the Graphics object passed into the Paint event. That graphics object is already configured with the appropriate scale factor and double buffering- the entire control will be handled correctly by the framework if the DoubleBuffer property is set.</p>
<p><em>*As with other posts, we&#8217;ll use &#8220;HiDPI&#8221; to refer to both HiDPI on Windows and Retina on OS X.</em></p>
<p><span id="more-232"></span></p>
<p>If drawing directly into the Graphics object passed into the control&#8217;s Paint event isn&#8217;t feasible or you need to manage your own caching of costly drawing for some reason, the BitmapForCaching function can be used to create a mutable bitmap thatâs configured appropriately for using as a cache. This bitmap has some screen-specific properties, like the scale factor, and should be thrown away in the ScaleFactorChanged event. For example:</p>
<pre>Class Foo<br />
 Inherits Canvas</p>
<p> Sub Paint(g As Graphics) Handles Event<br />
  CreateCacheIfNeeded()<br />
  g.DrawPicture(mCachedContent, 0, 0)<br />
 End Sub</p>
<p> Sub ScaleFactorChanged() Handles Event<br />
  mCachedContent = Nil<br />
 End Sub</p>
<p> Private Sub CreateCacheIfNeeded()<br />
  If mCachedContent &lt;&gt; Nil Then Exit Sub</p>
<p>  // Pretend this is a costly operation<br />
  mCachedContent = Self.TrueWindow.BitmapForCaching(100, 100)<br />
  Dim g As Graphics = mCachedContent.Graphics<br />
  g.FillRect(0, 0, g.Width, g.Height)<br />
 End Sub</p>
<p> Private Dim mCachedContent As Picture<br />
End Class</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Speeding Up TextArea Modifications In OS X</title>
		<link>https://blog.xojo.com/2015/12/28/speeding-up-textarea-modifications-in-os-x/</link>
		
		<dc:creator><![CDATA[Joe Ranieri]]></dc:creator>
		<pubDate>Mon, 28 Dec 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[OS X]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/12/28/speeding-up-textarea-modifications-in-os-x/</guid>

					<description><![CDATA[Speeding up TextArea modifications Under Cocoa]]></description>
										<content:encoded><![CDATA[<p>When doing a lot of manipulation to a TextArea&#8217;s contents under Cocoa, performance can suffer due to the underlying NSTextView doing work on layout and glyph selection. This can be sped up by telling the text view that you&#8217;re going to begin editing. You can do this by using a few Cocoa Declares.</p>
<p><span id="more-249"></span></p>
<p>The Declare statements are relatively simple:</p>
<pre>Declare Function documentView Lib "AppKit" Selector "documentView" _
  ( obj As Integer ) As Integer
Declare Function textStorage Lib "AppKit" Selector "textStorage" _
  ( obj As Integer ) As Integer
Declare Sub beginEditing Lib "AppKit" Selector "beginEditing" _
  ( obj As Integer )
Declare Sub endEditing Lib "AppKit" Selector "endEditing" _
  ( obj As Integer )</pre>
<p>These Declares give you access to methods for enabling &#8220;batch-editing mode&#8221; for the underlying NSTextView.</p>
<p>First, you want to get the text storage for the document, which is a two-step process. In the first step, you take the TextArea&#8217;s Handle property (an NSScrollView instance) and ask for its document view:</p>
<pre>Dim docView As Integer
docView = documentView(MyTextArea.Handle)</pre>
<p>Now you get the NSTextStorage for the NSTextView:</p>
<pre>Dim storage As Integer
storage = textStorage(docView)</pre>
<p>With the text storage, you can now enable batch-editing mode by calling beginEditing:</p>
<pre>beginEditing(storage)</pre>
<p>Now you can make your significant changes to the TextArea:</p>
<pre>For i As Integer = 0 To 5000
 MyTextArea.AppendText("Lorem ipsum dolor sit amet. ")
Next</pre>
<p>And when you are finished disable batch-editing mode:</p>
<pre>endEditing(storage)</pre>
<p>So how much does this improve performance? In my tests, the For loop by itself takes about 4.3 seconds to complete. Using batch-edit mode with these Declares drops it to 0.02 seconds. That&#8217;s almost instantaneous!</p>
<p>If you find you are going to use these Declare often, you can add them to a module as Extension methods so that you can call them more easily (as shown in the sample project):</p>
<ul>
<li><a href="http://files.xojo.com/BlogExamples/FastCocoaTextAreaUpdates.xojo_binary_project.zip">Download Sample Project</a></li>
</ul>
<p><strong><span style="font-size: 10px;">Originally published on November 26, 2012 by Joe Ranieri</span></strong> <span id="hs-cta-wrapper-85379a6a-4918-471b-8a83-e3a826fc5e01" class="hs-cta-wrapper"><span id="hs-cta-85379a6a-4918-471b-8a83-e3a826fc5e01" class="hs-cta-node hs-cta-85379a6a-4918-471b-8a83-e3a826fc5e01"><br />
</span></span> <!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Testing The Compiler</title>
		<link>https://blog.xojo.com/2015/06/17/testing-the-compiler/</link>
		
		<dc:creator><![CDATA[Joe Ranieri]]></dc:creator>
		<pubDate>Wed, 17 Jun 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/06/17/testing-the-compiler/</guid>

					<description><![CDATA[Testing The Compiler]]></description>
										<content:encoded><![CDATA[<p>Over the course of the last year, there have been a huge number of changes to the Xojo compiler (just under 800 commits). We made large refactorings, like rewriting how unqualified name lookup works. We fixed around 35 bugs, some of them dating back years. We added major new features to the language, including <a href="http://www.xojo.com/blog/en/2015/04/using-using.php">&#8216;Using&#8217;</a>, I<a href="http://www.xojo.com/blog/en/2015/02/iterators.php">terators</a>, and new <a href="http://developer.xojo.com/webinar-all-about-data-types">data types</a>. To top it all off, we shipped support for a completely new platform, iOS, and then met Apple&#8217;s deadline for building 64-bit iOS apps.</p>
<p>And after all of that, we ended up with around eight <a href="https://en.wikipedia.org/wiki/Software_regression">regressions</a> in the compiler. While not the perfect zero, I think this is just as impressive as the changes themselves.</p>
<p><span id="more-223"></span></p>
<p>One of the biggest factors in the low regression rate is the compiler&#8217;s testing setup. For each bug we fix or feature we add, we create additional tests. Due to how the compiler is structured, not all parts can be tested, but we still added over a hundred tests in the course of the year.</p>
<p>The test suite itself is simply a collection of raw Xojo source files on disk. Each test case can have expectations, which specify what the compiler should emit for the line in terms of errors or warnings. The expectations are specified in specially-formatted comments inside of the script itself. The end result is that test cases are self-contained, play nicely with version control, and are easy to write (which is by far the most important factor).</p>
<p>Here&#8217;s a simple test case, which accompanied the fix for <a href="http://feedback.xojo.com/case/21462">Feedback case #21462</a>:</p>
<pre style="overflow-x: scroll;">Function Pointless() As Object
  Return -Nil // expected-error 
End Function</pre>
<p>Of course, not all test cases are quite so straightforward or short. For example, the test for <a href="http://feedback.xojo.com/case/34479">Feedback case #34479</a> is over 200 lines long, due to the edge cases that were found while fixing it. There are also times where test cases have to be somewhat contorted:</p>
<pre style="overflow-x: scroll;">Sub Foo(param As Int32, _ // no-error
        param As Int32) // expected-error 
End Sub</pre>
<p>The test harness is a fairly simple Xojo console application. The harness recursively searches through the folder of test cases, executes the test via the <a href="http://developer.xojo.com/webinar-xojoscript">XojoScript</a> class, and compares the XojoScript results against expected results.</p>
<p>The expectations are extracted from the script via a simple parser that understands just enough of the Xojo language to read all of the comments. The compiler&#8217;s own functions were intentionally avoided because they are a fundamental part of what is being tested.</p>
<p>Overall, the test harness took about two weeks to write and polish off. The time spent was well worth it and I would encourage the use of automated testing, even if you can&#8217;t test every part of your product. Every bug that the test suite catches is one less bug that ends up in your customers&#8217; hands.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Why are there diamonds in my user interface?</title>
		<link>https://blog.xojo.com/2013/08/20/why-are-there-diamonds-in-my-user-interface/</link>
		
		<dc:creator><![CDATA[Joe Ranieri]]></dc:creator>
		<pubDate>Tue, 20 Aug 2013 00:00:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2013/08/20/why-are-there-diamonds-in-my-user-interface/</guid>

					<description><![CDATA[Why are there diamonds in my user interface?]]></description>
										<content:encoded><![CDATA[<p>You may have seen text that has strange diamond characters in it. If so, you likely have an encoding problem.</p>
<p><span id="more-51"></span></p>
<p>Fundamentally, Xojo strings are a series of bytes and a TextEncoding object that specifies how to interpret the bytes. It&#8217;s up to the programmer to make sure that the bytes are tagged with the correct TextEncoding object. You can do this using the <a href="http://documentation.xojo.com/api/text/encoding_text/defineencoding.html" target="_blank">DefineEncoding</a> method or by passing in a TextEncoding parameter to various functions like <a href="http://documentation.xojo.com/api/language/readable.html#readable-read" target="_blank">BinaryStream.Read</a>. Informally speaking, strings without an encoding are considered to be a simple &#8220;bag of bytes&#8221;, much like a MemoryBlock. Strings with a valid encoding are considered to be &#8220;textual&#8221; strings.</p>
<p>In the Xojo Cocoa framework, just about everything you see in the user interface, including drawing to a Graphics object or setting a TextArea&#8217;s Text property, requires a &#8220;textual&#8221; string. If the Xojo Cocoa framework needs a &#8220;textual&#8221; string but is passed a &#8220;bag of bytes&#8221; or a string that has a TextEncoding that isn&#8217;t correct for the bytes, it attempts to provide a fairly graceful fallback to avoid crashes. The fallback path tries its best to display <em>something</em>, which often means inserting the Unicode replacement character &#8212; the diamonds seen in the screenshot below:</p>
<p><img fetchpriority="high" decoding="async" class="mt-image-center" src="https://blog.xojo.com/wp-content/uploads/2013/08/screen20shot202013-08-2020at209.24.0420am-thumb-303x213-100.pngt1466486449161ampwidth303ampheight213" sizes="(max-width: 303px) 100vw, 303px" alt="Screen Shot 2013-08-20 at 9.24.04 AM.png" width="303" height="213" /></p>
<p>The exact behavior of the fallback path might change over time, but it currently works like this:</p>
<ul>
<li>If the string is marked as UTF-8 but isn&#8217;t valid UTF-8, the framework attempts to parse it as UTF-8 and replace any invalid sequences it finds with the Unicode replacement character.</li>
<li>If the string had no encoding or it was otherwise invalid, the framework treats the string as ASCII and replaces anything non-printable with the Unicode replacement character.</li>
</ul>
<p>To avoid this fallback behavior, you just need to make sure that the encoding of your string is defined properly. If all your strings are defined within Xojo, then you are all set because they use UTF-8 by default. But if your strings come in from external files, Internet communication or databases you may need to specifically define (or convert) the encoding.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
