1 /*$
2  Copyright (C) 2013-2020 Azel.
3 
4  This file is part of AzPainter.
5 
6  AzPainter is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  AzPainter is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 $*/
19 
20 /*****************************************
21  * ブラシサイズリストデータ
22  *****************************************/
23 
24 #include <stdlib.h>
25 
26 #include "mDef.h"
27 #include "mMemAuto.h"
28 #include "mUtilStr.h"
29 
30 
31 //-----------------
32 
33 typedef struct
34 {
35 	mMemAuto mem;
36 	int num;      //現在のデータ個数
37 }_brushsize;
38 
39 static _brushsize g_dat;
40 
41 //-----------------
42 
43 #define _MAXNUM      500
44 #define _EXPAND_SIZE (16 * 2)
45 #define _SIZE_MIN    3
46 #define _SIZE_MAX    6000
47 
48 //-----------------
49 
50 
51 /** 解放 */
52 
BrushSizeList_free()53 void BrushSizeList_free()
54 {
55 	mMemAutoFree(&g_dat.mem);
56 }
57 
58 /** 初期化 */
59 
BrushSizeList_init()60 void BrushSizeList_init()
61 {
62 	mMemzero(&g_dat, sizeof(_brushsize));
63 
64 	//バッファ確保
65 
66 	mMemAutoAlloc(&g_dat.mem, 64, _EXPAND_SIZE);
67 }
68 
69 /** 指定個数分を確保 (ファイルからの読み込み時) */
70 
BrushSizeList_alloc(int num)71 mBool BrushSizeList_alloc(int num)
72 {
73 	if(num > _MAXNUM) num = _MAXNUM;
74 
75 	return mMemAutoAlloc(&g_dat.mem, num << 1, _EXPAND_SIZE);
76 }
77 
78 /** 個数をセット (ファイルからの読み込み時) */
79 
BrushSizeList_setNum(int num)80 void BrushSizeList_setNum(int num)
81 {
82 	g_dat.num = num;
83 	g_dat.mem.curpos = num << 1;
84 }
85 
86 /** 個数を取得 */
87 
BrushSizeList_getNum()88 int BrushSizeList_getNum()
89 {
90 	return g_dat.num;
91 }
92 
93 /** バッファポインタを取得 */
94 
BrushSizeList_getBuf()95 uint16_t *BrushSizeList_getBuf()
96 {
97 	return (uint16_t *)g_dat.mem.buf;
98 }
99 
100 /** 指定位置のデータを取得 */
101 
BrushSizeList_getValue(int pos)102 int BrushSizeList_getValue(int pos)
103 {
104 	return *((uint16_t *)g_dat.mem.buf + pos);
105 }
106 
107 /** 文字列から追加
108  *
109  * '/' で区切って複数 */
110 
BrushSizeList_addFromText(const char * text)111 void BrushSizeList_addFromText(const char *text)
112 {
113 	const char *top,*end;
114 	uint16_t *pbuf;
115 	int size,pos,i,n;
116 
117 	for(top = text; mGetStrNextSplit(&top, &end, '/'); top = end)
118 	{
119 		//サイズ値
120 
121 		size = (int)(atof(top) * 10 + 0.5);
122 
123 		if(size < _SIZE_MIN)
124 			size = _SIZE_MIN;
125 		else if(size > _SIZE_MAX)
126 			size = _SIZE_MAX;
127 
128 		//挿入位置
129 		/* 値の小さい順。同じ値の場合は追加しない。 */
130 
131 		pbuf = (uint16_t *)g_dat.mem.buf;
132 		pos = g_dat.num;
133 
134 		for(i = 0; i < g_dat.num; i++)
135 		{
136 			n = *(pbuf++);
137 
138 			//同じ値は無視
139 			if(n == size) { pos = -1; break; }
140 
141 			//挿入位置
142 			if(n > size) { pos = i; break; }
143 		}
144 
145 		if(pos == -1) continue;
146 
147 		if(g_dat.num >= _MAXNUM) return;
148 
149 		//一つ分を確保
150 
151 		if(!mMemAutoAppend(&g_dat.mem, &size, 2))
152 			return;
153 
154 		//挿入位置を空けてセット
155 
156 		pbuf = (uint16_t *)g_dat.mem.buf + g_dat.num;
157 
158 		for(i = g_dat.num - pos; i > 0; i--, pbuf--)
159 			*pbuf = *(pbuf - 1);
160 
161 		*pbuf = size;
162 
163 		g_dat.num++;
164 	}
165 }
166 
167 /** 指定位置のデータを削除 */
168 
BrushSizeList_deleteAtPos(int pos)169 void BrushSizeList_deleteAtPos(int pos)
170 {
171 	uint16_t *p;
172 	int i;
173 
174 	p = (uint16_t *)g_dat.mem.buf + pos;
175 
176 	for(i = g_dat.num - pos - 1; i > 0; i--, p++)
177 		*p = p[1];
178 
179 	g_dat.num--;
180 
181 	mMemAutoBack(&g_dat.mem, 2);
182 }
183