c# pdf viewer open source : Reorder pages of pdf software SDK cloud windows winforms azure class World%20of%20Warcraft%20Programming%20(2nd%20Edition)135-part1801

Appendix A
Best Practices 1309
{ name = “Picture of Ziggart“,
file = “Interface\\AddOns\\MyMod\\Images\\ziggart.tga“
},
{ name = “Frame Background“,
file = “Interface\\AddOns\\MyMod\\Images\\bg.tga“
},
{ name = “Some other texture“,
file = “Interface\\AddOns\\MyMod\\Images\\other.tga“
},
}
for id, entry in ipairs(textures) do
MyAddon.MakeTexture(entry.name, id, entry.file)
end
Now if you want to add a new texture, you can just create a new entry in
the table. If you insert one in the middle, the rest will automatically have the
correctIDs.Tables are alsomorerecognizableas a data structure,so they make
more sense semantically than calling
MakeTexture
four times with the various
parameters.
Break Apart Long Functions
Thereis an upperlimittothenumberofwordsona lineoftextorin aparagraph
before our brains have trouble absorbing the information. In a similarfashion,
functions that drag on and on over multiple screens become hard to follow.
If you have a really long function that does several different tasks, you might
want to break it apart into smaller functions that are called by one ‘‘master.’’
Afairly common rule of thumb is to keep functions down to one screen of
code or less.
Use Consistent Programming Style
Much of programming is a matter of personal style and preference. From
indentation format to variable names, you can make many choices that affect
theoverall look andfeel of yourcode.Byremainingconsistent in thesechoices,
youwill serveyourselfin thelongrun.Followingaresomeexamplesof choices
you will have to make for yourself. Obviously, we could never hope to create
acomplete list, but this provides a good sample to get you thinking.
Naming conventions—Do you begin all your functions with capital
or lowercase letters? Do you differentiate words with underscores or
‘‘camel case’’ (
num_slots
vs.
numSlots
)? Doall functions followa specific
grammar (
Verb
,
VerbNoun
,and so on)?
Whitespace—How many blank lines do you have between functions?
Do you use tabs or spaces for indenting? How wide should indents be?
Do you split long statements into multiple lines?
Reorder pages of pdf - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
pdf reorder pages; how to move pages in a pdf document
Reorder pages of pdf - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
reordering pages in pdf; move pages in a pdf file
1310 Part V
Appendixes
Organization—Do you split your source into multiple files by function-
ality? Are your functions mostly local or do you use a namespace table?
If you’re using a table, do you use method syntax or simple indexing
(
MyMod:function
vs.
MyMod.function
)?
Comment format—Do all of your functions have descriptions of their
parametersandeffects?Doyouincludeacopyrightnoticeatthebeginning
ofyourfiles? Doyouuseinlinecommentstodescribecomplex algorithms?
Lua Tips
The simplicity of the Lua languagecan be deceptive.On the surface it displays
a clean, consistent syntax with intuitive keywords, and it has enough in
common with other languages that experienced programmers can get the
hang of it quite easily. However, to use Lua to its fullest extent takes a bit
of creative thinking. Many of its features are unique (or at least rare) and
certain idioms are downright foreign to programmers from other languages
(let alone people new to programming in general). To help you in this regard,
this section presents some tips that apply to Lua in general: some idiomatic
concepts that will help you take full advantage of its features, and various
optimizations to help you tune the performance of your addons.
Use Local Variables
As youmay remember from Part I, variables are always global unless defined
with the
local
keyword. Global variables, while suitable for many purposes,
have a couple of important caveats.Each time you reference a global variable,
Lua has to do a table lookup on the global environment (
_G
)with the name
of said variable. Locals, on the other hand, are stored in a location of memory
determined when the code is compiled. In fact, their names are both irrelevant
and inaccessible during runtime.
Additionally,eachglobalvariablehas thepotentialforconflict.Ifyounamea
function something simple, like
clear
,or
process
,youmayend upconflicting
with anotheraddon thatdoes thesame. Some addons usedtoprovide a global
print
function, and because each one treated its arguments uniquely, there
often were real-world conflicts. And they all suffered the now-realized possi-
bility that WoW itself would one day include a function with the same name.
One obvious solution would be to give the function a more unique name,
perhaps tacking your addon name to the beginning, but that would unnec-
essarily add to your typing requirements. It would also add information to
your code that provides no meaningful advantage in understanding the logic,
potentially making it harder to follow.
For these reasons, you should use locals for every variable or function that
does not need to be referenced outside of a given scope (whether it’s the file,
C# TIFF: How to Reorder, Rearrange & Sort TIFF Pages Using C# Code
Reorder, Rearrange and Sort TIFF Document Pages in C#.NET Application. C# TIFF Page Sorting Overview. Reorder TIFF Pages in C#.NET Application.
how to move pages within a pdf document; reorder pdf page
VB.NET PowerPoint: Sort and Reorder PowerPoint Slides by Using VB.
Sort and Reorder PowerPoint Slides Range with VB amount of robust PPT slides/pages editing methods powerful & profession imaging controls, PDF document, image
reverse page order pdf online; how to move pages in pdf reader
Appendix A
Best Practices 1311
afunction, or even within an
if
block). Also, if you have a legitimate global
variable but performance is an issue, create a local copy. For example, if your
addon needs to use
string.find
several times per frame, add the following
line to the beginning (you can name it anything youwant, perhaps
strfind
):
local string_find = string.find
Notice that this doesn’t call
string.find
(as shown by the lack of paren-
theses), but merely copies the function reference to the new local variable. By
using
string_find
throughout the file, you will save two table lookups on
each call (
_G
string
find
). These savings can add up quite quickly for
addons that do a lot of data processing each frame.
There is a practical limit to how many local variables a function can hold
reference to, but you aren’t likely to encounter it in your addon development.
Rememberthatthereis atrade-offbetween makingportions(such asconstants)
available, and making them local for performance. Ensure you understand
your own code, and choose whatever makes the most sense.
Minimize Unnecessary Garbage
Lua is a garbage-collected language. Every so often, it will go through all the
objects in its memory and remove anything that is no longer being referenced.
Say you have a function that creates a local table when it runs. After that
function exits there are no references to that table, so it its memory will be
reclaimed later.
The Lua runtime is very fast by virtual machine standards. It outperforms
manyothercommon scriptinglanguages invarioustasks.However,nothingin
the worldis free—especially in computing.Every timeyoucall yourfunction,
it creates a new table. Depending on how much information you pack into it,
how often you call thefunction,and a fewother factors,collecting this garbage
can make a noticeable dent in WoW’s performance.
The three main garbage-collected objects that you will encounter are tables,
strings, and closures. Tables are definitely the most frequently abused objects.
Strings are less obvious but can be just as troublesome. Each unique string is
acollectable object. Once there are no more variables set to a particular string,
that string can be collected. Finally, each time you create a new function it
makesa closurethatincludesthefunctionitselfand referencestoanyupvalues.
Just like waste in real life, you should make an effort to reduce, reuse, and
recycle. This will help prevent the garbage collection cycle from getting out
of hand.
However, don’t go overboard trying to wipe out every trace of garbage
creation from your addon. The garbage collector is there for a reason. If
you have a situation where you only need to create a new table, string, or
closure sporadically, go ahead. Simplicity should take priority over efficiency,
Read PDF in Web Image Viewer| Online Tutorials
from PDF documents; Extract images from PDF documents; Add, reorder pages in PDF files; Save and print PDF as you wish; More PDF Reading
reorder pdf pages; move pages in pdf file
VB.NET TIFF: Modify TIFF File by Adding, Deleting & Sort TIFF
Users can use it to reorder TIFF pages in ''' &ltsummary> ''' Sort TIFF document pages in designed powerful & profession imaging controls, PDF document, image
rearrange pdf pages online; change pdf page order reader
1312 Part V
Appendixes
especiallywhen you’refirstdesigningyouraddon.If younoticea performance
bottleneck, then it’s time to investigate further optimizations.
It should also be noted that some of these techniques may actually take
longer to run than the avoided garbage collection operation. Unfortunately,
there is no sure way to know if this will be the case. It depends entirely on
how much data is being used and what kind of processing is going on. If you
start out using one technique and find that some areas need optimization, try
it the other way.
How to Reduce Garbage
The most obvious way to improve your addon’s garbage situation is not to
create any in the first place.
Use Multiple Returns and Variable Arguments Instead of Tables
When you need to return multiple values, or accept multiple arguments,
you may be tempted to simply wrap them in tables. If you come to Lua
from another programming language, you are probably used to dealing with
structures, arrays, and such when you want to operate on a set of data.
Sometimes,however,tables are unnecessary and even wasteful.
If a function needs to return a set of data, it may be best to return multiple
values unless the fundamental purpose of the function is to return some sort
of table. This way, the calling function has complete control over how to treat
the data. Itcan pack the returns into a table for later use, pass them to another
function for further processing, or simply store them in local variables as
needed.
You have seen plenty of examples of multiple returns thanks to their
extensive use in WoW’s API. However, most of those functions return a fixed
number of values. To return an arbitrary amount of data to a calling function,
you must use some form of recursion, which is explored a little later in this
appendix.
Receiving arguments, both fixed and variable, have been covered fairly
extensively in this book. The next section shows a way to operate on every
value passed through thevararg (
...
)and return the modifiedvalues without
using any intermediary tables.
Avoid Creating Unnecessary Strings
Try to steer clear of building strings piece by piece, adding new elements one
by one. If possible, store each element in a variable and then put them all
together in one mass concatenation. For example,say you are buildinga string
such as
“123g 45s 67c“
.You may be tempted to break it down as follows:
money = gold..“g “
money = money..silver..“s “
money = money..copper..“c“
C# PDF Page Rotate Library: rotate PDF page permanently in C#.net
page, it is also featured with the functions to merge PDF files using C# .NET, add new PDF page, delete certain PDF page, reorder existing PDF pages and split
pdf move pages; rearrange pages in pdf file
C# PDF: C# Code to Process PDF Document Page Using C#.NET PDF
just following attached links. C# PDF: Add, Delete, Reorder PDF Pages Using C#.NET, C# PDF: Merge or Split PDF Files Using C#.NET.
how to move pages in pdf; move pages in pdf reader
Appendix A
Best Practices 1313
In this example, each line creates an entirely new string. Once the third line
executes, the first two strings that were created are now garbage and can be
collected. You can prevent this by building the entire string in one statement.
Each of the following lines achieves the same result:
money = gold..“g “..silver..“s “..copper..“c“
money = strconcat(gold, “g “, silver, “s “, copper, “c“)
money = string.format(“%dg %ds %dc“, gold, silver, copper)
In eachcase,only one stringresults fromthe operation,reducingtheamount
of garbage. The third line actually has a slight advantage over the other two.
This means that the original example actually contains five entirely wasted
strings. In the
string.format
example, though, there’s only one:
“%dg %ds
%dc“
.
NOTE
The function strconcat is actually specific to WoW. However, its
behavior is fundamental enough that it is appropriate for this section. It is simply a
function version ofthe concatenation operator (..). strconcat’s main advantage
over .. is that it can take a variable number ofitems to concatenate—something
you will see in the next example.
This function is very similar to the table.concat() function provided in the Lua
standard libraries, only it doesn’t require the use of a table.
SETFORMATTEDTEXT
Another WoW-specific tip that belongs here is the use of SetFormattedText.
Suppose you intend to do something like the following after the code in the
Money example:
text:SetText(money)
In this case, you can reduce created garbage further still and get a slight per-
formance improvement by combining the string.format example and the
SetFormattedText function.
text:SetFormattedText(“%dg %ds %dc“, gold, silver, copper)
The only garbage you create now is the formatting string. The
SetFormattedText method does not generate the final string in the
Lua environment at all. It exists entirely in the UI engine.
There are also somesituations where amoregarbage-friendlysolutionis not
immediately apparent. Building a string in a loop, for instance, does not lend
.NET Multipage TIFF SDK| Process Multipage TIFF Files
SDK, developers are easily to access, extract, swap, reorder, insert, mark up and delete pages in any multi upload to SharePoint and save to PDF documents.
change page order in pdf reader; how to rearrange pages in a pdf reader
C# Word: How to Create Word Document Viewer in C#.NET Imaging
in C#.NET; Offer mature Word file page manipulation functions (add, delete & reorder pages) in document viewer; Rich options to add
reverse page order pdf; how to change page order in pdf acrobat
1314 Part V
Appendixes
itself to the preceding approach. Consider the following loop(and forgive the
contrived example):
local sequence = ““
for i = 1, 10 do
sequence = sequence..i
end
The price you pay for its simplicity is that every single time through the
loop it creates a brand new string. In addition to creating garbage, the Lua
interpreter must copy the existing string data each time through, which also
takesextra CPUtime.Oneapparentsolutiontothe garbage stringproblemisto
use a table tostoreeach new addition tothestringand then call
table.concat
.
But that still creates a garbage string for each elementas well as generating an
extraneous table.
Luckily,there’s anothertrickusingvariableargumentsandmultiplereturns.
This time you add recursion to the mix:
local function MakeSequence(n, ...)
if n > 1 then
return MakeSequence(n - 1, n, ...)
else
return n, ...
end
end
local sequence = strconcat(MakeSequence(10))
If you haven’t had much experience with recursive functions, it may be
hard to understand how this works. Let’s run through the execution of
MakeSequence
.
1.
MakeSequence
is called with a single argument of
10
.
2. Because
n
is more than
1
,you call
MakeSequence
with the arguments
9
(
n - 1
)and
10
(
n
).
...
is emptysonothingelseis passedthistime around.
3. You are now one level deeper in recursion.
n
is
9
and
...
contains one
argument,
10
.Again, because
n
is more than
1
,you call
MakeSequence
with the arguments
8
(
n - 1
),
9
(
n
), and
10
(
...
).
4. Recursion continues in this manner until the arguments to
MakeSequence
are
n
:
1
and
...
:
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
.
5.
n
has finally reached
1
,so you return the entire sequence from 1 to 10.
This is passed back down through each level of recursion until it reaches
the original call.
Appendix A
Best Practices 1315
Or to put it more concisely:
MakeSequence(10)
MakeSequence(9, 10)
[Repetitive lines omitted]
MakeSequence(2, 3, 4, 5, 6, 7, 8, 9, 10)
MakeSequence(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
[Repetitive lines omitted]
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Once the final call to
MakeSequence
returns, the values are passed to
strconcat
,which joins them all together as in the earlier money example.
In this way,youtake advantageof Lua’s stack to store each stepof the process.
Because items on the stack cease to exist as soon as the function ends, none of
the data you pass back and forth needs to be garbage-collected.
As with all of these suggestions, you must carefully consider the structure
and readability of your code. In addition, function calls themselves aren’t
completely free. In many cases you should seriously consider using a work
table, and the
table.concat()
function.
TAIL CALLS
You may have noticed that all the returns in the previous diagram are
identical. In reality, Lua processes the recursive function a bit differently than
presented. Take a look at the line where you call MakeSequence inside itself.
Because you are simply returning the results to the previous level without
making any modifications, Lua uses a technique called a tail call.
Normally, when you call a function, the parameters are pushed onto the
stack along with the location in your program where the function should
return. Then control is passed to the function being called. When that function
finishes, it returns to the location you pushed originally.
In a tail call situation, on the other hand, the same return location is used
for every level of recursion. When any level of MakeSequence returns, it goes
to the location of the very first call. Here is a more realistic diagram to illus-
trate what’s actually going on:
MakeSequence(10)
MakeSequence(9, 10)
[Repetitive lines omitted]
MakeSequence(2, 3, 4, 5, 6, 7, 8, 9, 10)
MakeSequence(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
(continued)
1316 Part V
Appendixes
TAIL CALLS (continued)
To reiterate, tail calls are used only when you do not do anything to the
values being returned by the function you call. That means you must use a
return statement in conjunction with the call. Even if the function you are
calling does not return any values, as in the following example, Lua has no
way to know this for certain at compile time.
function foo()
-- Do stuff without returning anything
end
function bar()
foo()
end
When bar calls foo, there is a hidden operation of discarding any values
returned by foo, which breaks your chance to use tail recursion. Changing the
line inside bar to the following is all you need to fix it:
return foo()
Tail call recursion uses the function call stack more efficiently, since it
replaces the current function call with the new tail call, rather than simply
adding it on top. Think of each new function call as adding a layer on a
cake. To get back to your original location, you would need to remove all of
the layers you have added. Tail recursion helps the programming language
optimize by replacing the current level with a new one, instead of adding to
the stack.
Obviously, each unique problem requires slightly different logic. Let’s look
at another example to help you think recursively.
Many addons define a custom
print
function to make text output simpler
and to differentiate the addon’s output from a normal
print
,or to direct the
output to something other than the chat window. Most first attempts look
something like the following (notice the similarity to the original sequence
example):
local function print(...)
local output = ““
local n = select(“#“, ...)
for i = 1, n do
output = output..tostring(select(i, ...))
if i < n then
output = output..“, “
end
end
DEFAULT_CHAT_FRAME:AddMessage(“MyAddon: “..output)
end
Appendix A
Best Practices 1317
In this function you have two main problems to solve:
1. Each parameter must be converted into a string because concatenation
does not automatically convert anything but numbers to strings.
2. The various parametersmust be joinedtogetherwith commas in between
each entry.
You can handle the first problemwith a dedicatedfunction to convert all its
parameters to strings and return the lot of them:
local function toManyStrings(...)
if select(“#“, ...) > 0 then
return tostring((...)), toManyStrings(select(2, ...))
end
end
When
toManyStrings
is called with more than one argument, it returns its
first argument converted to a string plus the
toManyStrings
ed versions of the
rest of its arguments. Again, because you are not modifying the results of the
inner call to
toManyStrings
,Lua will use a tail call so youdon’t have to worry
about the number of arguments.
The second problem has already been solved for you. WoW comes with
afunction called
strjoin
that works a bit like
strconcat
,taking a variable
number of arguments andputtingthemtogether.However,the firstparameter
to
strjoin
is a separator that is placed in between each element ofthe concate-
nation. For example,
strjoin(“ sep “, “hello“, “middle“, “goodbye“)
returns the string
“hello sep middle sep goodbye“
.Putting these two solu-
tions together, your
print
function now becomes much simplerand produces
far less garbage:
local function print(...)
DEFAULT_CHAT_FRAME:AddMessage(“MyAddon: “..strjoin(“, “, toManyStrings(...)))
end
Recyclable Objects
Recycling objects is easy to do, but the need and manner to do so may not be
immediatelyapparent.Considerthefollowingfunction,which hidesa number
of predefined frames:
local function HideFrames()
local frames = {
PlayerFrame,
TargetFrame,
MinimapCluster,
}
for _, frame in ipairs(frames) do
frame:Hide()
end
end
1318 Part V
Appendixes
Each time you call this function it re-creates the
frames
table. After the
function exits,
frames
goes out of scope and becomes collectable. The solution
is simply to move the table to the same scope as the
HideFrames
function
itself:
local frames = {
PlayerFrame,
TargetFrame,
MinimapCluster,
}
local function HideFrames()
for _, frame in ipairs(frames) do
frame:Hide()
end
end
The referenceto the table will now persist as longas the scope it shares with
HideFrames
exists.
Thereisa tradeoffmadeusingthis technique.Bydefining the
frames
table at
the file level, the memory is consumed at load time. With the previous listing,
we defer creation of the table until it’s actually needed.However,this tradeoff
is easilydismissed in nearly every situation.Once thememoryis allocated,itis
completely free. Without garbage collection to worry about, it uses absolutely
no processor time to remain in existence. Furthermore,
HideFrames
operates
more quickly because the original version has to go through the process of
creating the table each time.
In the same way, you should not be creating functions inside other
functions—
function() end
is to functions what
{ }
is to tables—unless
you have a specific need for a new closure.
Recycle Tables
Tables are the only mutable garbage-collected objects in Lua. Unlike strings
and functions, you can directly manipulate the contents of tables. This unique
characteristic allows you to empty individual tables and reuse them.
There are a few ways to accomplish table recycling. In fact, some addon
authors have created libraries for just this purpose. The simplest method
uses a table to store the empty tables, a function to get an empty table,
and another function to recycle an unneeded table. Following is one possible
implementation:
local freeTables = {}
function GetTable()
return table.remove(freeTables) or {}
end
Documents you may be interested
Documents you may be interested