• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • graphics API Reference
  • KDE Home
  • Contact Us
 

digikam

  • extragear
  • graphics
  • digikam
  • core
  • dplugins
  • generic
  • tools
  • mediaserver
  • upnpsdk
  • Neptune
  • Source
  • Core
NptArray.h
Go to the documentation of this file.
1 /*****************************************************************
2 |
3 | Neptune - Arrays
4 |
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 ****************************************************************/
31 
32 #ifndef _NPT_ARRAY_H_
33 #define _NPT_ARRAY_H_
34 
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "NptConfig.h"
39 #if defined(NPT_CONFIG_HAVE_NEW_H)
40 #include <new>
41 #endif
42 #include "NptTypes.h"
43 #include "NptResults.h"
44 
45 /*----------------------------------------------------------------------
46 | constants
47 +---------------------------------------------------------------------*/
48 const int NPT_ARRAY_INITIAL_MAX_SIZE = 128; // bytes
49 
50 /*----------------------------------------------------------------------
51 | NPT_Array
52 +---------------------------------------------------------------------*/
53 template <typename T>
54 class NPT_Array
55 {
56 public:
57  // types
58  typedef T Element;
59  typedef T* Iterator;
60 
61  // methods
62  NPT_Array<T>(): m_Capacity(0), m_ItemCount(0), m_Items(0) {}
63  explicit NPT_Array<T>(NPT_Cardinal count);
64  NPT_Array<T>(NPT_Cardinal count, const T& item);
65  NPT_Array<T>(const T* items, NPT_Cardinal item_count);
66  ~NPT_Array<T>();
67  NPT_Array<T>(const NPT_Array<T>& copy);
68  NPT_Array<T>& operator=(const NPT_Array<T>& copy);
69  bool operator==(const NPT_Array<T>& other) const;
70  bool operator!=(const NPT_Array<T>& other) const;
71  NPT_Cardinal GetItemCount() const { return m_ItemCount; }
72  NPT_Result Add(const T& item);
73  T& operator[](NPT_Ordinal pos) { return m_Items[pos]; }
74  const T& operator[](NPT_Ordinal pos) const { return m_Items[pos]; }
75  NPT_Result Erase(Iterator which);
76  NPT_Result Erase(NPT_Ordinal which) { return Erase(&m_Items[which]); }
77  NPT_Result Erase(Iterator first, Iterator last);
78  NPT_Result Erase(NPT_Ordinal first, NPT_Ordinal last) { return Erase(&m_Items[first], &m_Items[last]); }
79  NPT_Result Insert(Iterator where, const T& item, NPT_Cardinal count = 1);
80  NPT_Result Reserve(NPT_Cardinal count);
81  NPT_Cardinal GetCapacity() const { return m_Capacity; }
82  NPT_Result Resize(NPT_Cardinal count);
83  NPT_Result Resize(NPT_Cardinal count, const T& fill);
84  NPT_Result Clear();
85  bool Contains(const T& data) const;
86  Iterator GetFirstItem() const { return m_ItemCount?&m_Items[0]:NULL; }
87  Iterator GetLastItem() const { return m_ItemCount?&m_Items[m_ItemCount-1]:NULL; }
88  Iterator GetItem(NPT_Ordinal n) { return n<m_ItemCount?&m_Items[n]:NULL; }
89 
90  // template list operations
91  // keep these template members defined here because MSV6 does not let
92  // us define them later
93  template <typename X>
94  NPT_Result Apply(const X& function) const
95  {
96  for (unsigned int i=0; i<m_ItemCount; i++) function(m_Items[i]);
97  return NPT_SUCCESS;
98  }
99 
100  template <typename X, typename P>
101  NPT_Result ApplyUntil(const X& function, const P& predicate, bool* match = NULL) const
102  {
103  for (unsigned int i=0; i<m_ItemCount; i++) {
104  NPT_Result return_value;
105  if (predicate(function(m_Items[i]), return_value)) {
106  if (match) *match = true;
107  return return_value;
108  }
109  }
110  if (match) *match = false;
111  return NPT_SUCCESS;
112  }
113 
114  template <typename X>
115  T* Find(const X& predicate, NPT_Ordinal n=0, NPT_Ordinal* pos = NULL) const
116  {
117  if (pos) *pos = -1;
118 
119  for (unsigned int i=0; i<m_ItemCount; i++) {
120  if (predicate(m_Items[i])) {
121  if (pos) *pos = i;
122  if (n == 0) return &m_Items[i];
123  --n;
124  }
125  }
126  return NULL;
127  }
128 
129 protected:
130  // methods
131  T* Allocate(NPT_Cardinal count, NPT_Cardinal& allocated);
132 
133  // members
134  NPT_Cardinal m_Capacity;
135  NPT_Cardinal m_ItemCount;
136  T* m_Items;
137 };
138 
139 /*----------------------------------------------------------------------
140 | NPT_Array<T>::NPT_Array<T>
141 +---------------------------------------------------------------------*/
142 template <typename T>
143 inline
144 NPT_Array<T>::NPT_Array(NPT_Cardinal count) :
145  m_Capacity(0),
146  m_ItemCount(0),
147  m_Items(0)
148 {
149  Reserve(count);
150 }
151 
152 /*----------------------------------------------------------------------
153 | NPT_Array<T>::NPT_Array<T>
154 +---------------------------------------------------------------------*/
155 template <typename T>
156 inline
157 NPT_Array<T>::NPT_Array(const NPT_Array<T>& copy) :
158  m_Capacity(0),
159  m_ItemCount(0),
160  m_Items(0)
161 {
162  Reserve(copy.GetItemCount());
163  for (NPT_Ordinal i=0; i<copy.m_ItemCount; i++) {
164  new ((void*)&m_Items[i]) T(copy.m_Items[i]);
165  }
166  m_ItemCount = copy.m_ItemCount;
167 }
168 
169 /*----------------------------------------------------------------------
170 | NPT_Array<T>::NPT_Array<T>
171 +---------------------------------------------------------------------*/
172 template <typename T>
173 inline
174 NPT_Array<T>::NPT_Array(NPT_Cardinal count, const T& item) :
175  m_Capacity(0),
176  m_ItemCount(count),
177  m_Items(0)
178 {
179  Reserve(count);
180  for (NPT_Ordinal i=0; i<count; i++) {
181  new ((void*)&m_Items[i]) T(item);
182  }
183 }
184 
185 /*----------------------------------------------------------------------
186 | NPT_Array<T>::NPT_Array<T>
187 +---------------------------------------------------------------------*/
188 template <typename T>
189 inline
190 NPT_Array<T>::NPT_Array(const T* items, NPT_Cardinal item_count) :
191  m_Capacity(0),
192  m_ItemCount(item_count),
193  m_Items(0)
194 {
195  Reserve(item_count);
196  for (NPT_Ordinal i=0; i<item_count; i++) {
197  new ((void*)&m_Items[i]) T(items[i]);
198  }
199 }
200 
201 /*----------------------------------------------------------------------
202 | NPT_Array<T>::~NPT_Array<T>
203 +---------------------------------------------------------------------*/
204 template <typename T>
205 inline
206 NPT_Array<T>::~NPT_Array()
207 {
208  // remove all items
209  Clear();
210 
211  // free the memory
212  ::operator delete((void*)m_Items);
213 }
214 
215 /*----------------------------------------------------------------------
216 | NPT_Array<T>::operator=
217 +---------------------------------------------------------------------*/
218 template <typename T>
219 NPT_Array<T>&
220 NPT_Array<T>::operator=(const NPT_Array<T>& copy)
221 {
222  // do nothing if we're assigning to ourselves
223  if (this == &copy) return *this;
224 
225  // destroy all elements
226  Clear();
227 
228  // copy all elements from the other object
229  Reserve(copy.GetItemCount());
230  m_ItemCount = copy.m_ItemCount;
231  for (NPT_Ordinal i=0; i<copy.m_ItemCount; i++) {
232  new ((void*)&m_Items[i]) T(copy.m_Items[i]);
233  }
234 
235  return *this;
236 }
237 
238 /*----------------------------------------------------------------------
239 | NPT_Array<T>::Clear
240 +---------------------------------------------------------------------*/
241 template <typename T>
242 NPT_Result
243 NPT_Array<T>::Clear()
244 {
245  // destroy all items
246  for (NPT_Ordinal i=0; i<m_ItemCount; i++) {
247  m_Items[i].~T();
248  }
249 
250  m_ItemCount = 0;
251 
252  return NPT_SUCCESS;
253 }
254 
255 /*----------------------------------------------------------------------
256 | NPT_Array<T>::Allocate
257 +---------------------------------------------------------------------*/
258 template <typename T>
259 T*
260 NPT_Array<T>::Allocate(NPT_Cardinal count, NPT_Cardinal& allocated)
261 {
262  if (m_Capacity) {
263  allocated = 2*m_Capacity;
264  } else {
265  // start with just enough elements to fill
266  // NPT_ARRAY_INITIAL_MAX_SIZE worth of memory
267  allocated = NPT_ARRAY_INITIAL_MAX_SIZE/sizeof(T);
268  if (allocated == 0) allocated = 1;
269  }
270  if (allocated < count) allocated = count;
271 
272  // allocate the items
273  return (T*)::operator new(allocated*sizeof(T));
274 }
275 
276 /*----------------------------------------------------------------------
277 | NPT_Array<T>::Reserve
278 +---------------------------------------------------------------------*/
279 template <typename T>
280 NPT_Result
281 NPT_Array<T>::Reserve(NPT_Cardinal count)
282 {
283  if (count <= m_Capacity) return NPT_SUCCESS;
284 
285  // (re)allocate the items
286  NPT_Cardinal new_capacity;
287  T* new_items = Allocate(count, new_capacity);
288  if (new_items == NULL) {
289  return NPT_ERROR_OUT_OF_MEMORY;
290  }
291  if (m_ItemCount && m_Items) {
292  for (unsigned int i=0; i<m_ItemCount; i++) {
293  // construct the copy
294  new ((void*)&new_items[i])T(m_Items[i]);
295 
296  // destroy the item
297  m_Items[i].~T();
298  }
299  }
300  ::operator delete((void*)m_Items);
301  m_Items = new_items;
302  m_Capacity = new_capacity;
303 
304  return NPT_SUCCESS;
305 }
306 
307 /*----------------------------------------------------------------------
308 | NPT_Array<T>::Add
309 +---------------------------------------------------------------------*/
310 template <typename T>
311 inline
312 NPT_Result
313 NPT_Array<T>::Add(const T& item)
314 {
315  // ensure capacity
316  NPT_Result result = Reserve(m_ItemCount+1);
317  if (result != NPT_SUCCESS) return result;
318 
319  // store the item
320  new ((void*)&m_Items[m_ItemCount++]) T(item);
321 
322  return NPT_SUCCESS;
323 }
324 
325 /*----------------------------------------------------------------------
326 | NPT_Array<T>::Erase
327 +---------------------------------------------------------------------*/
328 template <typename T>
329 inline
330 NPT_Result
331 NPT_Array<T>::Erase(Iterator which)
332 {
333  return Erase(which, which);
334 }
335 
336 /*----------------------------------------------------------------------
337 | NPT_Array<T>::Erase
338 +---------------------------------------------------------------------*/
339 template <typename T>
340 NPT_Result
341 NPT_Array<T>::Erase(Iterator first, Iterator last)
342 {
343  // check parameters
344  if (first == NULL || last == NULL) return NPT_ERROR_INVALID_PARAMETERS;
345 
346  // check the bounds
347  NPT_Ordinal first_index = (NPT_Ordinal)(NPT_POINTER_TO_LONG(first-m_Items));
348  NPT_Ordinal last_index = (NPT_Ordinal)(NPT_POINTER_TO_LONG(last-m_Items));
349  if (first_index >= m_ItemCount ||
350  last_index >= m_ItemCount ||
351  first_index > last_index) {
352  return NPT_ERROR_INVALID_PARAMETERS;
353  }
354 
355  // shift items to the left
356  NPT_Cardinal interval = last_index-first_index+1;
357  NPT_Cardinal shifted = m_ItemCount-last_index-1;
358  for (NPT_Ordinal i=first_index; i<first_index+shifted; i++) {
359  m_Items[i] = m_Items[i+interval];
360  }
361 
362  // destruct the remaining items
363  for (NPT_Ordinal i=first_index+shifted; i<m_ItemCount; i++) {
364  m_Items[i].~T();
365  }
366 
367  // update the item count
368  m_ItemCount -= interval;
369 
370  return NPT_SUCCESS;
371 }
372 
373 /*----------------------------------------------------------------------
374 | NPT_Array<T>::Insert
375 +---------------------------------------------------------------------*/
376 template <typename T>
377 NPT_Result
378 NPT_Array<T>::Insert(Iterator where, const T& item, NPT_Cardinal repeat)
379 {
380  // check bounds
381  NPT_Ordinal where_index = where?((NPT_Ordinal)NPT_POINTER_TO_LONG(where-m_Items)):m_ItemCount;
382  if (where > &m_Items[m_ItemCount] || repeat == 0) return NPT_ERROR_INVALID_PARAMETERS;
383 
384  NPT_Cardinal needed = m_ItemCount+repeat;
385  if (needed > m_Capacity) {
386  // allocate more memory
387  NPT_Cardinal new_capacity;
388  T* new_items = Allocate(needed, new_capacity);
389  if (new_items == NULL) return NPT_ERROR_OUT_OF_MEMORY;
390  m_Capacity = new_capacity;
391 
392  // move the items before the insertion point
393  for (NPT_Ordinal i=0; i<where_index; i++) {
394  new((void*)&new_items[i])T(m_Items[i]);
395  m_Items[i].~T();
396  }
397 
398  // move the items after the insertion point
399  for (NPT_Ordinal i=where_index; i<m_ItemCount; i++) {
400  new((void*)&new_items[i+repeat])T(m_Items[i]);
401  m_Items[i].~T();
402  }
403 
404  // use the new items instead of the current ones
405  ::operator delete((void*)m_Items);
406  m_Items = new_items;
407  } else {
408  // shift items after the insertion point to the right
409  for (NPT_Ordinal i=m_ItemCount; i>where_index; i--) {
410  new((void*)&m_Items[i+repeat-1])T(m_Items[i-1]);
411  m_Items[i-1].~T();
412  }
413  }
414 
415  // insert the new items
416  for (NPT_Cardinal i=where_index; i<where_index+repeat; i++) {
417  new((void*)&m_Items[i])T(item);
418  }
419 
420  // update the item count
421  m_ItemCount += repeat;
422 
423  return NPT_SUCCESS;
424 }
425 
426 /*----------------------------------------------------------------------
427 | NPT_Array<T>::Resize
428 +---------------------------------------------------------------------*/
429 template <typename T>
430 NPT_Result
431 NPT_Array<T>::Resize(NPT_Cardinal size)
432 {
433  if (size < m_ItemCount) {
434  // shrink
435  for (NPT_Ordinal i=size; i<m_ItemCount; i++) {
436  m_Items[i].~T();
437  }
438  m_ItemCount = size;
439  } else if (size > m_ItemCount) {
440  return Resize(size, T());
441  }
442 
443  return NPT_SUCCESS;
444 }
445 
446 /*----------------------------------------------------------------------
447 | NPT_Array<T>::Resize
448 +---------------------------------------------------------------------*/
449 template <typename T>
450 NPT_Result
451 NPT_Array<T>::Resize(NPT_Cardinal size, const T& fill)
452 {
453  if (size < m_ItemCount) {
454  return Resize(size);
455  } else if (size > m_ItemCount) {
456  Reserve(size);
457  for (NPT_Ordinal i=m_ItemCount; i<size; i++) {
458  new ((void*)&m_Items[i]) T(fill);
459  }
460  m_ItemCount = size;
461  }
462 
463  return NPT_SUCCESS;
464 }
465 
466 /*----------------------------------------------------------------------
467 | NPT_Array<T>::Contains
468 +---------------------------------------------------------------------*/
469 template <typename T>
470 bool
471 NPT_Array<T>::Contains(const T& data) const
472 {
473  for (NPT_Ordinal i=0; i<m_ItemCount; i++) {
474  if (m_Items[i] == data) return true;
475  }
476 
477  return false;
478 }
479 
480 /*----------------------------------------------------------------------
481 | NPT_Array<T>::operator==
482 +---------------------------------------------------------------------*/
483 template <typename T>
484 bool
485 NPT_Array<T>::operator==(const NPT_Array<T>& other) const
486 {
487  // we need the same number of items
488  if (other.m_ItemCount != m_ItemCount) return false;
489 
490  // compare all items
491  for (NPT_Ordinal i=0; i<m_ItemCount; i++) {
492  if (!(m_Items[i] == other.m_Items[i])) return false;
493  }
494 
495  return true;
496 }
497 
498 /*----------------------------------------------------------------------
499 | NPT_Array<T>::operator!=
500 +---------------------------------------------------------------------*/
501 template <typename T>
502 inline
503 bool
504 NPT_Array<T>::operator!=(const NPT_Array<T>& other) const
505 {
506  return !(*this == other);
507 }
508 
509 #endif // _NPT_ARRAY_H_
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
NPT_Array::Insert
NPT_Result Insert(Iterator where, const T &item, NPT_Cardinal count=1)
Definition: NptArray.h:378
T
#define T
Definition: libraw_cxx_defs.h:59
NPT_SUCCESS
#define NPT_SUCCESS
Result indicating that the operation or call succeeded.
Definition: NptResults.h:104
NPT_Array::Add
NPT_Result Add(const T &item)
Definition: NptArray.h:313
NPT_Array::GetLastItem
Iterator GetLastItem() const
Definition: NptArray.h:87
NptResults.h
NPT_Array::GetCapacity
NPT_Cardinal GetCapacity() const
Definition: NptArray.h:81
NPT_Array::Erase
NPT_Result Erase(NPT_Ordinal first, NPT_Ordinal last)
Definition: NptArray.h:78
NPT_Array::m_Capacity
NPT_Cardinal m_Capacity
Definition: NptArray.h:134
NPT_Array::GetItemCount
NPT_Cardinal GetItemCount() const
Definition: NptArray.h:71
NPT_Array::GetFirstItem
Iterator GetFirstItem() const
Definition: NptArray.h:86
NPT_Array
Definition: NptArray.h:54
NPT_Array::Contains
bool Contains(const T &data) const
Definition: NptArray.h:471
NPT_Array::Find
T * Find(const X &predicate, NPT_Ordinal n=0, NPT_Ordinal *pos=NULL) const
Definition: NptArray.h:115
NPT_Ordinal
unsigned int NPT_Ordinal
Definition: NptTypes.h:58
NPT_Array::m_Items
T * m_Items
Definition: NptArray.h:136
PLT_Service
UPnP Service.
Definition: PltService.h:67
NPT_ERROR_OUT_OF_MEMORY
#define NPT_ERROR_OUT_OF_MEMORY
Definition: NptResults.h:130
NPT_ERROR_INVALID_PARAMETERS
#define NPT_ERROR_INVALID_PARAMETERS
Definition: NptResults.h:128
NptConfig.h
NPT_Array::NPT_Array
NPT_Array()
Definition: NptArray.h:62
NPT_Array::operator!=
bool operator!=(const NPT_Array< T > &other) const
Definition: NptArray.h:504
NPT_Array::Erase
NPT_Result Erase(NPT_Ordinal which)
Definition: NptArray.h:76
NPT_ARRAY_INITIAL_MAX_SIZE
const int NPT_ARRAY_INITIAL_MAX_SIZE
Definition: NptArray.h:48
NPT_Array::Iterator
T * Iterator
Definition: NptArray.h:59
NPT_Array::GetItem
Iterator GetItem(NPT_Ordinal n)
Definition: NptArray.h:88
NPT_Array::operator=
NPT_Array< T > & operator=(const NPT_Array< T > &copy)
Definition: NptArray.h:220
NPT_Array::Resize
NPT_Result Resize(NPT_Cardinal count)
Definition: NptArray.h:431
NPT_Array::Clear
NPT_Result Clear()
Definition: NptArray.h:243
NPT_Array::operator==
bool operator==(const NPT_Array< T > &other) const
Definition: NptArray.h:485
NPT_Array::~NPT_Array
~NPT_Array()
Definition: NptArray.h:206
NptTypes.h
NPT_Array::operator[]
const T & operator[](NPT_Ordinal pos) const
Definition: NptArray.h:74
NPT_Array::ApplyUntil
NPT_Result ApplyUntil(const X &function, const P &predicate, bool *match=NULL) const
Definition: NptArray.h:101
NPT_Array::Apply
NPT_Result Apply(const X &function) const
Definition: NptArray.h:94
NPT_POINTER_TO_LONG
#define NPT_POINTER_TO_LONG(_p)
Definition: NptConfig.h:304
NPT_Array::Erase
NPT_Result Erase(Iterator which)
Definition: NptArray.h:331
NPT_Array::Element
T Element
Definition: NptArray.h:58
NPT_Array::m_ItemCount
NPT_Cardinal m_ItemCount
Definition: NptArray.h:135
NPT_Array::Allocate
T * Allocate(NPT_Cardinal count, NPT_Cardinal &allocated)
Definition: NptArray.h:260
NPT_Array::Reserve
NPT_Result Reserve(NPT_Cardinal count)
Definition: NptArray.h:281
NPT_Result
int NPT_Result
Definition: NptTypes.h:56
NULL
#define NULL
Definition: NptConstants.h:39
NPT_Cardinal
unsigned int NPT_Cardinal
Definition: NptTypes.h:57
NPT_Array::operator[]
T & operator[](NPT_Ordinal pos)
Definition: NptArray.h:73
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Sun Dec 15 2019 03:23:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

digikam

Skip menu "digikam"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages
-->

graphics API Reference

Skip menu "graphics API Reference"
  • digikam
  • KDiagram
  •     KChart
  •     KGantt
  • KPhotoAlbum
  •   AndroidRemoteControl
  • Krita
  •   libs
  •     KritaBasicFlakes
  •     brush
  •     KritaUndo2
  •     KritaFlake
  •     image
  •     KritaPlugin
  •     Krita
  •     KritaOdf
  •     KritaPigment
  •     KritaStore
  •     ui
  •     KritaWidgets
  •     KritaWidgetUtils
  •   plugins
  •     Assitants
  •     Extensions
  •     Filters
  •         KritaText
  •         KritaTextLayout
  •     Generators
  •     Formats
  •             src
  •     PaintOps
  •       libpaintop
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal